# Discord.js Bot to monitor streamers

**URL:** <https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200>\
**Category:** API\
**Created:** [September 17, 2020, 8:05pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200 "2020-09-17T20:05:32Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 17, 2020, 8:05pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/1 "2020-09-17T20:05:32Z")

</div>

Hello,

I am new to JS and even more new to APIs. I have a node.js discord bot (running locally at home) on my discord server and I want to incorporate a feature that will send an embed on a specific discord channel when someone on my server goes live on twitch. I want to use API to do it.

My issue is i get authentication errors when I try the example url located [here](https://dev.twitch.tv/docs/api/reference#get-streams). I am also not sure what I need to have my oauth redirect to be.

Thanks in advance to anyone who can help me out.

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 18, 2020, 2:10am UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/2 "2020-09-18T02:10:19Z")

</div>

All of Helix requires an oAuth token to be specified.

For your use case a server to server token, aka client credentials makes the most sense

> **[Getting OAuth Access Tokens](https://dev.twitch.tv/docs/authentication/getting-tokens-oauth/)**
>
> Getting OAuth Access Tokens

> [@3than](#):
>
> I am also not sure what I need to have my oauth redirect to be.

Since just using Server to server, just leave it as localhost. You only need a redirect URI if you are needing to authenticate a user

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 18, 2020, 4:07am UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/3 "2020-09-18T04:07:30Z")

</div>

Ok. So I would need a html send and request for JavaScript and send that at the beginning? Then it should respond with a json that I can save and use for my token. Is there other things I need to authenticate a channel request? And how would I save the responses from Twitch? Would I need a database like program on the bot as well?

Sorry if theses questions seam quite simple but I really don’t know what I’m doing. Thanks again

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 18, 2020, 11:33am UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/4 "2020-09-18T11:33:37Z")

</div>

> [@3than](#):
>
> So I would need a html send and request for JavaScript and send that at the beginning?

For a user token yes  
For a server to server token no.

> [@3than](#):
>
> And how would I save the responses from Twitch? Would I need a database like program on the bot as well?

If you use Twitch Webhooks instead of long polling the API you can get away with not storing anything

[https://dev.twitch.tv/docs/api/webhooks-guide](https://dev.twitch.tv/docs/api/webhooks-guide)

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 18, 2020, 2:44pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/5 "2020-09-18T14:44:31Z")

</div>

> [@BarryCarlyon](#):
>
> For a user token yes  
> For a server to server token no

So I would run the post once for server to server and use the return key for my requests?

What is the difference in information that Webhooks provide from long-pulling?

Also how would the request look different for long pulling and Webhooks. For Webhooks they showed this: “ /api/webhooks-reference/#subscribe-tounsubscribe-from-events” if I wanted to subscribe to a specific streamer how would I write it out and include my key.

And finally, how to I capture a response form Twitch? Would I need an async function to await for some response?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 18, 2020, 4:32pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/6 "2020-09-18T16:32:37Z")

</div>

> [@3than](#):
>
> What is the difference in information that Webhooks provide from long-pulling?

Nothing.

The webhook sends the same payload as the streams API would

> [@3than](#):
>
> Also how would the request look different for long pulling and Webhooks. For Webhooks they showed this: “ /api/webhooks-reference/#subscribe-tounsubscribe-from-events” if I wanted to subscribe to a specific streamer how would I write it out and include my key.

You make a request to the Webhooks hub to create a subscription (which remains active for up to 10 days). Then when the stream goes online/offline/changes title you get a POST’ed payload to your Callback

The structure of the POST to create a webhook subscription, for the headers is the same as any API request to Helix.

You just need to POST a JSON blob that tells Twitch what topic you want and how long you want it for. And setup a callback handler to receive (and verify the subscription)

Example:

```auto
{
    'hub.callback': 'https://yourURL/',
    'hub.mode': 'subscribe',
    'hub.topic': 'https://api.twitch.tv/helix/streams?user_id=USERID',
    'hub.lease_seconds': 10,
    'hub.secret': 'somesecret'
}

```

For long polling you just load the streams API once per minute every minute, (wasting resources and API requests), Webhooks you get data when data changes as Twitch tells you data has changed.

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 18, 2020, 5:47pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/7 "2020-09-18T17:47:51Z")

</div>

The callback handlebar will need the token? Is that the verification you were referring to?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 19, 2020, 12:51am UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/8 "2020-09-19T00:51:45Z")

</div>

No

1. You make a POST to Twitch at `https://api.twitch.tv/helix/webhooks/hub` with a App access Token and ClientID in the header, with a JSON blob similar to whats above, you get a 204 (No Content) or a 202 Accepted (I forget which offhand)

2. Twitch makes a GET request to your callback URL, to check that it’s valid, Twitch includes a `hub.challenge` as a Query string parameter

3. You Echo back that challenge

4. Then when data occurs, Twitch will make a POST to your callback with the data.

Steps 2/3 are the Verification I refer to

I provide a couple of Callback handler examples here [https://github.com/BarryCarlyon/twitch\_misc/tree/master/webhooks/handlers](https://github.com/BarryCarlyon/twitch_misc/tree/master/webhooks/handlers)

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 19, 2020, 2:01am UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/9 "2020-09-19T02:01:46Z")

</div>

So. I’m still stuck at getting my OAUTH token. I put this into my browser with my proper ids but i didn’t get anything. just a failed page.

[https://id.twitch.tv/oauth2/token?client\_id=](https://id.twitch.tv/oauth2/token?client_id=)&client\_secret=&grant\_type=client\_credentials

Also would this work as the subscribe request or am I way off?

```
const requesttopic = {

    'hub.callback': 'HTTPS://YOURURL',

    'hub.mode': 'subscribe',

    'hub.topic': 'https://api.twitch.tv/helix/streams?user_id=USERID',

    'hub.lease_seconds': 864000,

    'hub.secret': 'SOMESECRET'

};

// The parameters of fetch

const options = {

    method: 'POST',

    Headers: {

        'Authorization': 'Bearer <OAUTH TOKEN>',

        'Client-Id': 'eaj131p033pzugihwnjazrl4peuhfn',

        'Content-Type': 'application/json'

    },

    body: JSON.stringify(requesttopic),

};

// Sending fetch to webhook hub

app.post('https://api.twitch.tv/helix/webhooks/hub', function (req, res) {

    res.send(options)
```

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 19, 2020, 12:14pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/10 "2020-09-19T12:14:31Z")

</div>

> [@3than](#):
>
> So. I’m still stuck at getting my OAUTH token. I put this into my browser with my proper ids but i didn’t get anything. just a failed page.
> 
> [https://id.twitch.tv/oauth2/token?client\_id=&client\_secret=&grant\_type=client\_credentials](https://id.twitch.tv/oauth2/token?client_id=&client_secret=&grant_type=client_credentials)

Putting it in a browser sends a GET request, to get a token requires a POST request.

> [@3than](#):
>
> Also would this work as the subscribe request or am I way off?

Looks about right, depends if what you have written is correct for whatever `app` is

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 19, 2020, 4:35pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/11 "2020-09-19T16:35:14Z")

</div>

for app i have:

const express = require(‘express’);  
const app = express();

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 19, 2020, 4:45pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/12 "2020-09-19T16:45:43Z")

</div>

for the token? would i do something like this?

```
app.post('https://id.twitch.tv/oauth2/token?client_id=eaj131p033pzugihwnjazrl4peuhfn&client_secret=<SECRET>&grant_type=client_credentials', function (req, res) {

    res.send();

    req.console.log(req);

});

```

or would I do it a bit different?  
thanks

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 19, 2020, 7:28pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/13 "2020-09-19T19:28:30Z")

</div>

express handles in bound HTTP requests, it cannot make outbound requests.

You created a page on your website of

```
http(s)://somepage.com/https://id.twitch.tv/oauth2/token?client_id=eaj131p033pzugihwnjazrl4peuhfn&client_secret=<SECRET>&grant_type=client_credentials

```

Responding to inbound HTTP Post requests

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 19, 2020, 7:37pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/14 "2020-09-19T19:37:29Z")

</div>

ah, yeah sorry. I am using node-fetch.js an ran this (Assuming `const fetch = require('node-fetch');` ):

```
fetch('https://id.twitch.tv/oauth2/token?client_id=eaj131p033pzugihwnjazrl4peuhfn&client_secret=<SECRET>&grant_type=client_credentials', { method: 'POST'})

    .then(res => res.json()) // expecting a json response

    .then(json => console.log(json));

```

and I got my key back. Do I have to rerun that every month or so because it looks to have an expiration?

Now I have to change my other code to do fetch() and set up a handler for when Twitch responds. Can I use express for the handler? And am I missing anything else? Thanks

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 19, 2020, 8:44pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/15 "2020-09-19T20:44:57Z")

</div>

Ok, a few more questions regarding the subscribe request:

1. For the callback URL, can it be either a DomainName:port or a PublicIP:port? Or is it something different?

2. What is the hub.secret? is it something i can define and how does it work?

3. Is is possible to subscribe to multiple users in one request or do I need to make it run everytime for every user? If i can do it in one command, what would the format look like? If every user, what is the best way of accomplishing this because i don’t just want to paste the code in 10 different times and change the user part.

Thanks again

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 20, 2020, 8:53pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/16 "2020-09-20T20:53:29Z")

</div>

> [@3than](#):
>
> For the callback URL, can it be either a DomainName:port or a PublicIP:port? Or is it something different?

Yes but also no.

Ideally you would be operating over SSL

> [@3than](#):
>
> What is the hub.secret? is it something i can define and how does it work?

Yes, you define the secret and then a head is signed with the secret so you know Twitch sent it. As only Twitch knows the secret you pick.

For example

[https://github.com/BarryCarlyon/twitch\_misc/blob/master/webhooks/handlers/nodejs/receive.js#L40](https://github.com/BarryCarlyon/twitch_misc/blob/master/webhooks/handlers/nodejs/receive.js#L40)

> [@3than](#):
>
> Is is possible to subscribe to multiple users in one request or do I need to make it run everytime for every user? If i can do it in one command, what would the format look like? If every user, what is the best way of accomplishing this because i don’t just want to paste the code in 10 different times and change the user part.

No, there are no bulk subscribers, each stream/follow topic accepts one user\_id etc

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 20, 2020, 9:42pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/17 "2020-09-20T21:42:34Z")

</div>

I’m not all that familiar with SSL and I just have a public IP and port forwarding(Because I’m hosting locally from home). But having `'hub.callback': 'http://<PUBLIC_IP>:8000',` will work?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 20, 2020, 9:57pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/18 "2020-09-20T21:57:23Z")

</div>

For non sensitive topics sure.

But you _really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really_ shouldn’t be home hosting this.

If you are running from home, go back to polling the API

---

<div class="post-metadata">

**Author:** ![3than](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/3than/32/10237_2.png) [@3than](https://staging-discuss.dev.twitch.com/u/3than)\
**Post date:** [September 20, 2020, 10:03pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/19 "2020-09-20T22:03:05Z")

</div>

long poll and wait for the data to change basically? Would I log the times when data is received to compare the differences? Also i believe i can pull multiple users at once by just long pulling right?

---

<div class="post-metadata">

**Author:** ![BarryCarlyon](https://d1d6mrmdu7ztse.cloudfront.net/user_avatar/staging-discuss.dev.twitch.com/barrycarlyon/32/253_2.png) [@BarryCarlyon](https://staging-discuss.dev.twitch.com/u/BarryCarlyon)\
**Post date:** [September 20, 2020, 10:28pm UTC](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200/20 "2020-09-20T22:28:14Z")

</div>

> [@3than](#):
>
> long poll and wait for the data to change basically?

yup

> [@3than](#):
>
> Also i believe i can pull multiple users at once by just long pulling right?

yeah streams endpouint lets you lookup 100 users at once

[Next page](https://staging-discuss.dev.twitch.com/t/discord-js-bot-to-monitor-streamers/28200.md?page=2)
