Twitch Bot: Get rewards via tmi.js

[EN] Channel points are a (relative) new feature on Twitch. Viewer can collect it while watching. With this simple trick, your Bot can react on rewards with tmi.js. For exmaple let the bot greet this user!

HINT: Your redeem has to have an input field for text inputs, otherwise there is not text push to IRC and it is invisible for the bot!

Channel points allows the viewer of a Twitch streamer to collect „loyalty“ points while watching the stream, put something in chat or cheer with some Bits (Twitch digital currency). As a streamer you can offer some rewards for an amount of points. For example „Highlight my message“ for 100 channel points.

This type of rewards are nice, but also very simple and not so much interaction with the user. The streamers creativity is bounded. Twitch offers some ideas:

  • Let a viewer choose which game or map you play next
  • Let a viewer customize game character
  • Give a friend request
  • Dance on stream

But what is about rewards, that interacts with your Twitch Bot (written in Java-Script with the library tmi.js)? You could talk with all APIs (application interfaces) or do any logic you want.

How to: Twitch Bot rewards

You could write your own rewards with logic. For exmaple with Java-Script on NodeJS with the help of the library tmi.js. There is a tutorial for this at end of the tmi.js page.

Bot, tell me a joke!

For example a reward could be: „Tell me a joke!“ or „Actual weather“ with an API.

  • Two bytes meet.  The first byte asks, “Are you ill?”
    The second byte replies, “No, just feeling a bit off.”
  • How many programmers does it take to change a light bulb?
    None – It’s a hardware problem
  • Debugging: Removing the needles from the haystack.

Sorry for the bad computer science jokes…

This is how the reward looks like:

And this the result from the bot:

„tmi.js can’t do this!“

Correct. Eh.. no not at all. For the actual tmi.js version 1.5.0 there doesn’t exist any event listener for rewards. So tmi.js can’t do it natively like „Follow“ or „Subscription“ events. But you can listen to the context at the message event listener. Fortunately redeemed channel points are also Twitch chat messages (when a message is required!). So we could read and detect channel rewards and differentiate them from normal messages. For my reward it is:

Message context from a „onMessage“ event listener.

The secret lies in context from a message, because redeemed rewards also generates a message in chat. From the context you can find the custom-reward-id (for my reward: 4e7f4966-3979-4bf6-af76-447fdc0717cb) key for the reward. With an if clause you have to search for this every message. Then you can react on this!

Write own Rewards with tmi.js

Let’s develop an easy reward „Tell me a joke!“. First of all you’ve to create a reward on Twitch for your channel. Give them a name and number of channel points.

At your tmi.js script you have now to add an array with jokes. For example we can use my jokes from this article:

var jokes = [
	"Two bytes meet. The first byte asks, “Are you ill?” + 
	"The second byte replies, “No, just feeling a bit off.”",
	"How many programmers does it take to change a light bulb?" + 
	"None – It’s a hardware problem",
	"Debugging: Removing the needles from the haystack."
];Code-Sprache: JavaScript (javascript)

Now we have to react on the reward you create before. Then we have to find our Reward-ID like I described in the article before. For this you can redeem the reward and listen on the created message. Now you can add the logic to your tmi.js script:

client.on('message', (channel, context, message, self) => {
	if (context["custom-reward-id"] === "YOUR-REWARD-ID") {
		client.say(channel, jokes[Math.floor(Math.random() * jokes.length)]);
	}
}Code-Sprache: JavaScript (javascript)

The full script looks like this:

let tmi = require ('tmi.js');
let config = {
  identity: {
    username: USERNAME,
    password: OAUTH-TOKEN
  },
  channels: CHANNELS
};
let client = new tmi.client();
client.connect();

var jokes = [
	"Two bytes meet. The first byte asks, “Are you ill?” + 
	"The second byte replies, “No, just feeling a bit off.”",
	"How many programmers does it take to change a light bulb?" + 
	"None – It’s a hardware problem",
	"Debugging: Removing the needles from the haystack."
];

client.on('message', (channel, context, message, self) => {
	if (context["custom-reward-id"] === "YOUR-REWARD-ID") {
		client.say(channel, jokes[Math.floor(Math.random() * jokes.length)]);
	}
}Code-Sprache: JavaScript (javascript)

Some Reward ideas (with logic)

On my german Twitch channel BYTEthinks my viewer can collect BYTEcoins and change it with this (tmi.js-)rewards:

  • Change lamp color in stream
    Change overlay lamp color written in HTML & CSS in given color hexcode (e.g. #ff0000 -> red)
  • Ask the bot a question!
    Redirect the written question via API to WolframAlpha and return the answer (e.g. „How tall is Eiffel Tower?“ Bot: „324 meters“)
  • Spotify song request
    Add via Spotify API songs to the current playback queue from Spotify.

Beside that, there are an infinite number of ideas you could do as reward. Be creative! Here are some ideas for your inspiration:

  • I tell you some random secret of mine
    Return a random fact of an array
  • Tell me a joke!
    The same as above, but with an array of jokes
  • Make me an VIP for 24h!
    Bot react with „VIP“ command from the tmi.js library

What ideas do you have for an programmable reward system? Write a comment below! Thanks!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

20 Kommentare
  1. Samuel sagt:

    Do someone know if there is a way to redeem points without input field ? Or does it always must have an input field for text?

    Thanks for the article it’s still working perfectly !

  2. Epson Printer Error 000041 sagt:

    Thanks for sharing this knowledgeable post. What an excellent post and outstanding article. Thanks for your awesome topic . Really I got very valuable information here.

  3. Martin sagt:

    Irgendwie will das bei mir nicht klappen. Ich bekomme den Fehler:
    ReferenceError: context is not defined

    Was mache ich falsch?

    aber danke für das Tutorial, vielleicht raffe ich das ja noch^^

    • Martin sagt:

      nvm, habs jetzt. Es ist immer das gleiche, ich probiere stundenlang, bis ich nachfrage. 5 Minuten später funktioniert es dann haha. Danke für die tolle Anleitung, gibt mir gute Ideen für meinen Kanal :D

    • Finn Dohrn sagt:

      Moin Martin,

      wo hakt es denn genau? Hast du vllt. ein paar Code Schnipsel via https://pastebin.com/? Dann schau ich gerne mal rein! Klingt so, als wenn du context nicht im Methodenkopf hast. :)

      VG Finn

      • Martin sagt:

        ach, super doof…es war genau das, was du gesagt hast^^.

        Danke dir auf jeden Fall vielmals.
        Ich versuche was bestimmtes hinzubekommen, aber bekomme es noch nicht ganz hin (habe nur Abi-Programmier-Basics)

        Beispiel: Der User schreibt als Nachricht 1 zur Belohnung, der Bot antwortet mit A. Wenn ne 2 geschireben wird, antwortet er B, usw…

        Aber wie lese ich die Nachricht aus? Den Rest würde ich mit ganz vielen if’s, elseif’s, else und returns machen^^

        • Finn Dohrn sagt:

          Na dann hast du es doch vorher selber rausgefunden. Das ist sowieso das beste Lernen. ;D

          Im Methoden Header müsstest du auch eine Variable „message“ haben, dort steht die Message drinnen. Schau mal in mein volles Skript in Zeile 19.

          Noch ein Tipp für Dich: Gib dir am besten mit console.log(VARIABLE) die Inhalte der Variablen aus, dann siehst du auch, was du wo finden kannst. Ist ziemlich interessant fürs Verständnis was Twitch einem so mit liefert!

          VG Finn

  4. Rodrigo sagt:

    Doesn’t seem to work for me too.

    `client.on(„message“, ….` doesn’t fire when points redeem is redeemed. I receive 0 messages!

  5. Simon sagt:

    Doesnt seem to work anymore.
    Have anyone an other way to react on reedem points?
    Because the idea is realy nice i think.

    • Finn Dohrn sagt:

      Hey Simon,
      what part is not working? In my bot, this code is still working.
      Greetings, Finn

    • Simon sagt:

      So. Mal etwas genauer umgesehen und deinen Stream gefunden.
      Schreib mal lieber auf deutsch. Hab meinen fehler gefunden. Es muss auch eine Channel Point Nachricht dabei geben. Also das der User auch was schreibt. Eine möglichkeit ohne nachricht kennst du nicht zufällig?
      Hintergrund: Soll ein kleiner bot werden, der die channel points in streamelements punkte umtauscht. also per !addpoints automatisch die punkte vergibt. wäre eben am schönsten wenn man nur nen knopf hätte mit z.b. 1000 punkte zu 500 tauschen und der bot den streamelements bot triggert.

      heute leider etwas zu späd gekommen. aber sonntag werd ich mir deinen stream mal ansehen. dachte nicht dass du noch so aktiv bist. der blog und youtube sehen ja nicht soo aktuell aus :)

      vielen dank für die schnelle antwort. Muss mich aber generell vorher mehr in javascript und node.js einlesen denke ich, noch sehr neuland für mich. aber der bot wird dazu ein guter einstieg.

      lg Simon

    • Finn Dohrn sagt:

      Englisch wäre auch kein Thema. ;-)

      Ne, leider klappt es in Verbindung mit tmi.js nur mit Text Belohnungen, da die Belohnung über den IRC Chat geteilt wird. Die anderen Belohnungen (ohne Text) werden nicht im Chat als „Nachricht“ gepusht und sind für das tmi.js unsichtbar. Was du machen kannst, ist natürlich eine Zahl verlangen z.B. man soll 1000 eingeben und er wandelt es in 500 um.

      Aktiv bin ich auf YouTube leider aktuell nicht, da ich zu viel zu tun habe. Den Blog pflege ich, wenn ich Lust und nen passenden Artikel habe.

      VG, Finn

  6. Rowario sagt:

    Спасибо брат!

  7. derrobin154 sagt:

    A good article for developers using the TMI.js
    Well done Finn! :)