Most Popular
Courier is a notification service that centralizes all of your templates and messaging channels in one place which increases visibility and reduces engineering time.
Sign-up
In this series, I explain how to use Twitch EventSub and Courier to automatically send notifications to multiple destinations – Slack, Discord, and more – when your Twitch stream goes live.
In part one, we built a Node.js app using Express.js to accept events from Twitch EventSub. Now, in part two, we’re going to listen for our event and trigger a notification using Courier.
Follow along with the series:
Need help getting started with sending notifications about your Twitch stream? Join our community on Discord – we’re happy to chat!
In this tutorial, I’ll show you how to take the Node.js and Express app that we built in part one and use it to listen for our events. From there, we’ll create and trigger a notification in Courier. I’ll demo sending an SMS notification with Twilio, but you can use Courier to send notifications to any channel, including popular chat apps like Discord and Facebook Messenger.
To complete this tutorial, you'll need a few things:
If you’re using the Node.js and Express.js app we created in part one, it should either be deployed somewhere publicly accessible that supports HTTPS and port 443, or be running locally using ngrok.
We'll use a new or existing Twitch application from your Developer Console along with the Twitch CLI to subscribe to the stream.online
event and point it to the /webhooks/callback
route on our server. Then, we'll update our server code to capture that event and send it to Courier to create and send the notification.
Keep in mind that there could be around a 45 second delay before Twitch triggers the event from the time your stream goes online.
To begin receiving requests from Twitch EventSub, we first need to create a subscription. We'll use the Twitch CLI to create a Stream Online subscription type and give it the callback URL from our Node.js application. It's important that the application is running and publicly available because EventSub will attempt to validate the callback URL when creating the subscription.
First, we need to configure the Twitch CLI using a new or existing Twitch application. If you have already configured your Twitch CLI, you can skip this step.
Navigate to the Twitch Developer Console and create a new by clicking “Register Your Application” or open an existing application. Add [http://localhost:3000](http://localhost:3000)
as an OAuth Redirect URL.
Take note of the Client ID, as we'll be using this shortly. You'll also need to generate a new Client Secret by clicking on the “New Secret” button. Be sure to save this somewhere safe because it won't be shown again. If you have an existing Client Secret for this application, you can use it. Generating a new secret will invalidate any existing secret.
Now, let's use these values to configure the Twitch CLI. In a terminal, run the following command:
1twitch configure
You will be prompted to enter your Client ID and Secret. To fetch an access token, run the following command:
1twitch token
You're now ready to start making Twitch API calls using the Twitch CLI.
To create our Stream Online subscription, we'll use the Twitch CLI to POST to the EventSub Subscriptions endpoint. You'll need to provide the full URL for your webhook callback, the secret value set in the TWITCH_SIGNING_SECRET
environment variable of your Node.js application, and your Twitch broadcaster user ID.
To find your broadcaster user ID, run the following command replacing trycourier
with your Twitch login ID:
1twitch api get users -q login=trycourier
This will output your Twitch user object in JSON format. Your broadcaster user ID will be the ID.
Now let's create the subscription. Run the following command with the needed substitutions:
1twitch api post eventsub/subscriptions -b '{2"type": "stream.online",3"version": "1",4"condition": {5"broadcaster_user_id": "YOUR_BROADCASTER_ID"6},7"transport": {8"method": "webhook",9"callback": "https://EXTERNAL_URL/webhook/callback",10"secret": "YOUR_SECRET"11}12}'
You should see “Verification successful“ in the console of your running application. Every time you go online, your application will now receive a POST with a payload similar to the following:
1{2"subscription": {3"id": "5d179ae7-d744-45a4-a259-5129634dd788",4"type": "stream.online",5"version": "1",6"condition": {7"broadcaster_user_id": "493127514"8},9"transport": {10"method": "webhook",11"callback": "https://15a1265bdd3c.ngrok.io/webhook/callback"12},13"created_at": "2021-01-26T17:15:17Z"14},15"event": {16"id": "9001",17"broadcaster_user_id": "493127514",18"broadcaster_user_login": "trycourier",19"broadcaster_user_name": "TryCourier",20"type": "stream.online"21}22}
Now we can update our application to accept and process this event.
Now that we’ve created our Stream Online subscription, the next step is to send it to Courier, which we’ll use to create and deliver notifications about our Twitch stream. To do this, we need to add a call to Courier's Send API when a stream.online
event comes in. We'll use the Courier Node.js SDK to do this. We'll also use the Twitch.js library to query the Twitch API to grab more details about the stream that we can send to Courier.
First, let's add these npm packages and configure the necessary environment variables.
We've reached a point where we are using enough environment variables that we should use a better method of loading them. Let's create a .env
file and use the dotenv package to load them when the application starts.
Create a .env file with the following:
1TWITCH_SIGNING_SECRET=purplemonkeydishwasher2TWITCH_CLIENT_ID=your-twitch-client-id3TWITCH_CLIENT_SECRET=your-twitch-client-id4COURIER_AUTH_TOKEN=your-courier-auth-token
Use the Twitch values from step one of our tutorial. You can find your Courier Auth Token in Settings > API Keys in your Courier account. Use the Published Production Key.
Now let's install the dotenv package, along with the other packages mentioned above:
1npm install dotenv @trycourier/courier twitch
And add the following line to the top of your index.js:
1require("dotenv").config();
Now when you run your application, these values will be loaded and ready for your application to use.
stream.online
eventLet's continue updating our application by running a function when the type of the event is stream.online
.
Just below the console.log
in the /webhooks/callback
handler, add the following:
1if (type === "stream.online") {2try {3sendOnline(event);4} catch (ex) {5console.log(6`An error occurred sending the Online notification for ${event.broadcaster_user_name}: `,7ex8);9}10}
Next, let's create sendOnline
as an async function. This function will handle grabbing any additional information about the Twitch stream and sending it to Courier.
Add the following to the top of index.js with the rest of the require statements:
1const { CourierClient } = require("@trycourier/courier");2const courier = CourierClient();3const { ApiClient } = require("twitch");4const { ClientCredentialsAuthProvider } = require("twitch-auth");5const authProvider = new ClientCredentialsAuthProvider(6process.env.TWITCH_CLIENT_ID,7process.env.TWITCH_CLIENT_SECRET8);9const twitch = new ApiClient({ authProvider });
This will create the Courier and Twitch clients we'll use in the sendOnline function. Add the following function to your application:
1const sendOnline = async event => {2const stream = await twitch.helix.streams.getStreamByUserId(3event.broadcaster_user_id4);5const game = await stream.getGame();67const { messageId } = await courier.send({8eventId: "TWITCH_ONLINE",9recipientId: "AYDRIAN10036",10profile: {11phone_number: "+12025550140"12},13data: {stream, game}14});15console.log(16`Online notification for ${event.broadcaster_user_name} sent. Message ID: ${messageId}.`17);18};
This function will use the Twitch client to grab information about the stream such as the title and game info and then pass it to the call to Courier's Send API so it can be used in the creation of your notification. You'll also want to update the recipientId to a unique string – I used my name and zip in all caps without spaces: AYDRIAN10036 – and the phone_number
with your phone number. You’ll need both of these in order to receive the notification we create in Courier.
The next time you go online, the stream.online
event will flow into Courier. Next, we'll use the stream information to create a notification using Courier's template builder.
For this tutorial, we'll be creating a text notification for our Twitch stream. We'll explore other notification channels in the third part of this series.
Let's start by configuring the Twilio integration in Courier. This will require you to enter details about your Twilio account. Check out our Getting Started with Twilio guide for more details.
Now it's time to design the notification in Courier. Navigate to the Notification Designer and select “Create Notification.” Click “Untitled Notification” on the top left to give your notification a descriptive name – in this case, I’ve named mine “Twitch Online Alert.”
Now let's add SMS as a channel for our notification by selecting SMS and choosing Twilio from the dropdown. We can now select SMS under Channels to the left and start designing our notification.
We'll design a simple SMS notification. First, we'll use a text block – click the “T” on the toolbar – and add the following text: “{stream._data.user_name} is playing {game._data.name} on Twitch.“ Next, we'll add another text block with the following text: “{stream._data.title}.” And we'll add one more text block with the following text: “https://twitch.tv/{stream._data.user_name}“. We’re personalizing the SMS using the stream information, which we passed to the notification in the data object as part of calling the Courier API.
This is enough for now, but feel free to add more content blocks and continue designing the SMS message. When you’re finished, click “Publish Changes” in the upper righthand corner.
If you’d like, you can preview the email using the Preview tab and ensure your variables are templated properly. You'll be prompted to Create a Test Event and then you'll want to update the JSON object with the following example, replacing the phone_number with your own:
1{2"data": {3"stream": {4"_data": {5"id": "40078987165",6"user_id": "493127514",7"user_name": "trycourier",8"game_id": "417752",9"game_name": "Talk Shows & Podcasts",10"type": "live",11"title": "Courier Live: Twitch EventSub and Courier",12"viewer_count": 0,13"started_at": "2021-01-05T19:54:35Z",14"language": "en",15"thumbnail_url": "https://static-cdn.jtvnw.net/previews-ttv/live_user_trycourier-{width}x{height}.jpg",16"tag_ids": null17}18},19"game": {20"_data": {21"id": "417752",22"name": "Talk Shows & Podcasts",23"box_art_url": "https://static-cdn.jtvnw.net/ttv-boxart/Talk%20Shows%20&%20Podcasts-{width}x{height}.jpg"24}25}26},27"profile": {28"phone_number": "+12025550140"29}30}
Once you save your test event, you should see the name variable populate in the Preview tab with whatever value you’ve set.
The last thing we want to do is to map the event we specified earlier in the Courier Send call to this notification. Next to the notification name, click the gear icon to launch the Notification Settings. Select Events from the left menu and enter “TWITCH_ONLINE” in the Events box.
Close the dialog and your notification is ready to send. If you don't want to wait for the next time you go online, you can test your notification using the Send Tab.
We can now test our application using the Twitch CLI. Run the following command with the needed substitutions:
1twitch event trigger streamup --to-user YOUR_BROADCASTER_ID -F https://EXTERNAL_URL/webhook/callback -s YOUR_SECRET
This command will trigger an example stream.online
event using your broadcaster id. You should see the event in the Courier Logs and receive an SMS message.
With all the new updates, your finished application should look like the following.
1require("dotenv").config();2const express = require("express");3const crypto = require("crypto");4const { CourierClient } = require("@trycourier/courier");5const app = express();6const port = process.env.PORT || 3000;7const twitchSigningSecret = process.env.TWITCH_SIGNING_SECRET;8const courier = CourierClient();9const { ApiClient } = require("twitch");10const { ClientCredentialsAuthProvider } = require("twitch-auth");11const authProvider = new ClientCredentialsAuthProvider(12process.env.TWITCH_CLIENT_ID,13process.env.TWITCH_CLIENT_SECRET14);15const twitch = new ApiClient({ authProvider });1617app.get("/", (req, res) => {18res.send("Hello World!");19});2021const verifyTwitchSignature = (req, res, buf, encoding) => {22const messageId = req.header("Twitch-Eventsub-Message-Id");23const timestamp = req.header("Twitch-Eventsub-Message-Timestamp");24const messageSignature = req.header("Twitch-Eventsub-Message-Signature");25const time = Math.floor(new Date().getTime() / 1000);26console.log(`Message ${messageId} Signature: `, messageSignature);2728if (Math.abs(time - timestamp) > 600) {29// needs to be < 10 minutes30console.log(31`Verification Failed: timestamp > 10 minutes. Message Id: ${messageId}.`32);33throw new Error("Ignore this request.");34}3536if (!twitchSigningSecret) {37console.log(`Twitch signing secret is empty.`);38throw new Error("Twitch signing secret is empty.");39}4041const computedSignature =42"sha256=" +43crypto44.createHmac("sha256", twitchSigningSecret)45.update(messageId + timestamp + buf)46.digest("hex");47console.log(`Message ${messageId} Computed Signature: `, computedSignature);4849if (messageSignature !== computedSignature) {50throw new Error("Invalid signature.");51} else {52console.log("Verification successful");53}54};5556const sendOnline = async (event) => {57const stream = await twitch.helix.streams.getStreamByUserId(58event.broadcaster_user_id59);60const game = await stream.getGame();6162const { messageId } = await courier.send({63eventId: "TWITCH_ONLINE",64recipient: "AYDRIAN10036",65profile: {66phone_number: "+12025550140"67},68data: { stream, game }69});70console.log(71`Online notification for ${event.broadcaster_user_name} sent. Message ID: ${messageId}.`72);73};7475app.use(express.json({ verify: verifyTwitchSignature }));7677app.post("/webhooks/callback", async (req, res) => {78const messageType = req.header("Twitch-Eventsub-Message-Type");79if (messageType === "webhook_callback_verification") {80console.log("Verifying Webhook");81return res.status(200).send(req.body.challenge);82}8384const { type } = req.body.subscription;85const { event } = req.body;8687console.log(88`Receiving ${type} request for ${event.broadcaster_user_name}: `,89event90);9192if (type === "stream.online") {93try {94sendOnline(event);95} catch (ex) {96console.log(97`An error occurred sending the Online notification for ${event.broadcaster_user_name}: `,98ex99);100}101}102103res.status(200).end();104});105106const listener = app.listen(port, () => {107console.log("Your app is listening on port " + listener.address().port);108});
Our application will now process stream.online
events and pass them to Courier along with additional stream data. Courier will then create an SMS notification and send it.
In the next post, we'll explore other types of notifications and how to use Courier to send to them all at the same time. In the meantime, take a look at the different integrations available in Courier and see if you can update your application to support a new one. Join our Discord community and let me know which one you're most interested in!
-Aydrian
Courier is a notification service that centralizes all of your templates and messaging channels in one place which increases visibility and reduces engineering time.
Sign-up
Get Your iOS App Ready for the 2025 Apple Push Notification Service Server Certificate Update
Apple is updating its Push Notification Service (APNs) certificates in 2025. Learn how to prepare your app for these changes, ensure uninterrupted notifications, and get expert tips for a smooth transition.
Mike Miller
December 13, 2024
Simplifying notifications with the Courier iOS SDK
Push notifications are a valuable tool for keeping users informed and increasing their engagement with your app. You can use push notifications to alert users about promotions, new content, or any other important updates. While push notifications are a powerful tool, setting up push notifications in iOS can be a daunting task that requires a significant amount of effort and time. Fortunately, the Courier iOS Mobile Notifications Software Development Kit (SDK) simplifies this process.
Mike Miller
March 23, 2023
Free Tools
Comparison Guides
Send up to 10,000 notifications every month, for free.
Get started for free
Send up to 10,000 notifications every month, for free.
Get started for free
© 2024 Courier. All rights reserved.