---
title: "How to announce Twitch and YouTube live streams in Discord | StreetHosting"
description: "Make your Discord bot post in a channel when a streamer goes live on Twitch or uploads a new YouTube video, without ever repeating the same announcement."
url: "https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications"
type: "page"
language: "en-US"
---

Discord Bots · 8 min · Intermediate

Published on Nov 13, 2026 · Updated on Nov 13, 2026

# Discord bot for Twitch live alerts and new YouTube videos

Learn how to query the Twitch Helix API and the YouTube RSS feed, build the announcement embed and remember what was already announced so the bot never repeats a message.

By [Equipe StreetHosting](https://streethosting.com.br/en/autores#equipe-streethosting) · StreetHosting infrastructure and support team

[Automation and webhooks](https://streethosting.com.br/en/guides/topics/automation)

Summarize with:

[](https://chat.openai.com/?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "ChatGPT") [](https://claude.ai/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Claude") [](https://www.google.com/search?udm=50&aep=11&q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Google AI Mode") [](https://x.com/i/grok?text=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Grok") [](https://www.perplexity.ai/search/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Perplexity")

Share:

[](https://x.com/intent/tweet?text=How%20to%20announce%20Twitch%20and%20YouTube%20live%20streams%20in%20Discord&url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications "Share on X") [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications "Share on Facebook") [](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications "Share on LinkedIn") [](https://wa.me/?text=How%20to%20announce%20Twitch%20and%20YouTube%20live%20streams%20in%20Discord%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fdiscord-bots%2Fdiscord-bot-twitch-youtube-live-notifications "Share on WhatsApp")

For agents: Copy as Markdown [.md](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications.md)

In this guide 7 sections

* [How the announcement works](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#como-funciona)
* [Twitch: create the app and get the token](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#twitch-token)
* [Twitch: check who is live](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#twitch-streams)
* [Avoiding duplicate announcements](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#evitar-duplicado)
* [YouTube: new videos from the RSS feed](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#youtube-rss)
* [The YouTube limit with live streams](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#limite-youtube-live)
* [Where to run it at StreetHosting](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#hospedar)

Quick answer

To announce Twitch lives, create an application in the developer console, get an app access token and query the `/helix/streams` endpoint every minute. Save the id of each broadcast you already announced so you never repeat it. For YouTube, read the channel RSS feed for new videos, keeping in mind that live streams do not show up reliably without the Data API.

## How the announcement works[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#como-funciona)

Discord knows nothing about Twitch or YouTube. Your bot is the one that finds out the channel went live, by asking the platform every so often. When the answer shows a live stream that has not been announced yet, the bot posts a message with an embed in the channel you picked. It is a simple loop of query, compare and announce.

There are two ways to learn about a live stream on Twitch. The first is polling, which we build here: every minute the bot calls the Helix API and sees who is broadcasting. The second is EventSub, where Twitch tells your bot as soon as the `stream.online` event happens. EventSub is faster and wastes no calls, but it needs a WebSocket connection or a public HTTPS address, plus more code. For a server with half a dozen streamers, polling every minute gives the same result with far less work.

The example uses discord.js v14 and Node 20 or newer, which already ships with `fetch` built in. If you do not have the bot running yet, start with the guide on [creating your first Discord bot from scratch](https://streethosting.com.br/en/guides/discord-bots/create-discord-bot). This bot only sends messages, so the Guilds intent is enough.

## Twitch: create the app and get the token[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#twitch-token)

The Twitch API requires every call to say who you are. Since the bot only reads public stream data, you use the app access token, which does not depend on anyone logging in.

1. Sign in to the Twitch developer console with your account and open the applications tab.
2. Register a new application. For the OAuth redirect URL you can use `http://localhost`, which will not be used.
3. Copy the Client ID and generate a Client Secret.
4. Put both in the bot's environment variables, never inside the code.

The token comes from a POST call to the Twitch authentication server. It lasts a long time, but it does expire, so the code below stores the expiry and asks for a new one when needed.

`` let token = null; let tokenExpira = 0; async function obterToken() { if (token && Date.now() < tokenExpira) return token; const resp = await fetch('https://id.twitch.tv/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ client_id: process.env.TWITCH_CLIENT_ID, client_secret: process.env.TWITCH_CLIENT_SECRET, grant_type: 'client_credentials', }), }); if (!resp.ok) throw new Error(`Token da Twitch falhou: ${resp.status}`); const dados = await resp.json(); token = dados.access_token; // renova 5 minutos antes de vencer tokenExpira = Date.now() + (dados.expires_in - 300) * 1000; return token; } ``

The Client Secret is a password. If it leaks into a public repository, generate a new one in the Twitch console right away. The guide on [keeping your bot token safe with environment variables](https://streethosting.com.br/en/guides/discord-bots/discord-bot-token-environment-variables) shows how to keep these values out of the code.

## Twitch: check who is live[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#twitch-streams)

The `GET https://api.twitch.tv/helix/streams` endpoint returns only the broadcasts that are on the air right now. You repeat the `user_login` parameter for each channel, in a single call. Anyone who is offline simply does not appear in the list, so an empty response means nobody is live.

`` const CANAIS_TWITCH = ['streamer_um', 'streamer_dois']; async function buscarLives() { const params = new URLSearchParams(); for (const login of CANAIS_TWITCH) params.append('user_login', login); const resp = await fetch(`https://api.twitch.tv/helix/streams?${params}`, { headers: { 'Client-Id': process.env.TWITCH_CLIENT_ID, Authorization: `Bearer ${await obterToken()}`, }, }); if (resp.status === 401) { token = null; // força um token novo na próxima rodada throw new Error('Token da Twitch recusado'); } if (!resp.ok) throw new Error(`Helix respondeu ${resp.status}`); const { data } = await resp.json(); return data; } ``

Each item in `data` carries `id` (the broadcast id), `user_login`, `user_name`, `title`, `game_name` and `thumbnail_url`. The thumbnail comes with width and height placeholders that you need to replace with numbers.

Twitch's rate limit is generous for this use. One query per minute with every channel in the same call is very little. Do not make one call per channel in a loop, because that multiplies usage for no gain.

## Avoiding duplicate announcements[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#evitar-duplicado)

If the bot announced every time it saw someone live, it would post a new message every minute. The fix is to remember what was already announced. On Twitch each broadcast has its own id, which changes when the streamer ends the stream and starts another. Saving the last id per channel solves it: if the id of the current live matches the saved one, the bot stays quiet.

An in-memory object is not enough, because it disappears when the bot restarts and the announcement goes out again. Save to a simple JSON file.

`` const fs = require('node:fs'); const { Client, Events, GatewayIntentBits, EmbedBuilder } = require('discord.js'); const ARQUIVO_ESTADO = './estado-avisos.json'; function lerEstado() { try { return JSON.parse(fs.readFileSync(ARQUIVO_ESTADO, 'utf8')); } catch { return { twitch: {}, youtube: {} }; } } function salvarEstado(estado) { fs.writeFileSync(ARQUIVO_ESTADO, JSON.stringify(estado, null, 2)); } const client = new Client({ intents: [GatewayIntentBits.Guilds] }); async function checarTwitch(canal) { const lives = await buscarLives(); const estado = lerEstado(); for (const live of lives) { if (estado.twitch[live.user_login] === live.id) continue; const miniatura = live.thumbnail_url .replace('{width}', '1280') .replace('{height}', '720'); const embed = new EmbedBuilder() .setColor(0x9146ff) .setTitle(live.title || 'Ao vivo agora') .setURL(`https://twitch.tv/${live.user_login}`) .setAuthor({ name: `${live.user_name} está ao vivo` }) .addFields({ name: 'Jogando', value: live.game_name || 'Sem categoria' }) .setImage(`${miniatura}?t=${Date.now()}`); await canal.send({ content: `${live.user_name} entrou ao vivo! https://twitch.tv/${live.user_login}`, embeds: [embed], }); // salva só depois de enviar, para um erro de envio não perder o aviso estado.twitch[live.user_login] = live.id; salvarEstado(estado); } } ``

The `?t=`at the end of the thumbnail tricks Discord's cache, which could otherwise show an old image from the previous live stream. To wire everything up, call the checks on an interval when the bot is ready:

`client.once(Events.ClientReady, async () => { const canal = await client.channels.fetch(process.env.CANAL_AVISOS_ID); if (!canal || !canal.isTextBased()) { console.error('Canal de avisos não encontrado'); return; } const rodar = async () => { try { await checarTwitch(canal); await checarYoutube(canal); } catch (err) { console.error('Falha na checagem:', err.message); } }; rodar(); setInterval(rodar, 60 * 1000); }); client.login(process.env.DISCORD_TOKEN);`

The `try/catch` around everything matters: a network drop or a bad response from Twitch must not take the bot down, only skip that round. If some call starts failing with many 429 responses, see the guide on [Discord rate limits](https://streethosting.com.br/en/guides/discord-bots/fix-discord-429-rate-limit).

## YouTube: new videos from the RSS feed[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#youtube-rss)

Every YouTube channel has a public feed at `https://www.youtube.com/feeds/videos.xml?channel_id=ID_DO_CANAL`. It lists the most recent videos, needs no API key and has no quota. The channel ID starts with `UC` and usually appears on the channel page, in the advanced information. A URL with an at sign does not work for this feed.

To read the XML without writing a parser, install `rss-parser` with `npm install rss-parser`. It returns each video as an item with title, link and date. The guide on an [RSS news feed in Discord](https://streethosting.com.br/en/guides/discord-bots/discord-bot-rss-feed-news) goes deeper into this library. Here the duplicate logic changes a little: instead of a single id, we store the list of the latest videos seen, so a deleted video does not mess up the record.

`` const Parser = require('rss-parser'); const parser = new Parser(); const CANAIS_YOUTUBE = { 'Nome do canal': 'UCxxxxxxxxxxxxxxxxxxxxxx', }; async function checarYoutube(canal) { const estado = lerEstado(); for (const [nome, channelId] of Object.entries(CANAIS_YOUTUBE)) { const feed = await parser.parseURL( `https://www.youtube.com/feeds/videos.xml?channel_id=${channelId}` ); const primeiraVez = !estado.youtube[channelId]; const vistos = estado.youtube[channelId] || []; const novos = feed.items.filter((item) => !vistos.includes(item.id)); // na primeira execução só memoriza, para não anunciar o canal inteiro if (!primeiraVez) { for (const video of novos.reverse()) { await canal.send(`${nome} publicou um vídeo novo: ${video.title}\n${video.link}`); } } estado.youtube[channelId] = feed.items.map((item) => item.id).slice(0, 30); salvarEstado(estado); } } ``

Two details. The `novos.reverse()` makes the bot announce from oldest to newest, in the order the videos came out. And the first run check avoids the shock of the bot dumping the channel's latest videos the moment you turn it on. If you paste the plain link in the message, Discord builds the video preview by itself.

## The YouTube limit with live streams[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#limite-youtube-live)

The RSS feed was designed for published videos. A live stream may show up in it when it is created or scheduled, but the feed does not say whether it is live at this moment nor tell you when it ends. A bot based only on RSS will announce the live stream as if it were an ordinary video, and sometimes not even that. You cannot treat this as reliable detection.

To really know whether a channel is live, the way is the YouTube Data API v3, which requires creating a Google Cloud project and generating an API key. Searching for videos with the live event type uses a lot of the daily quota, so the ideal is to query only a few times per hour, or use the channel video list and check the state of each video, which is cheaper. Check the current quota numbers in Google's documentation before choosing the interval.

In practice, many communities do the following: Twitch by polling, YouTube only for new videos through RSS and, if the channel streams on YouTube, the Data API at a longer interval. If the YouTube live alert is not essential, RSS already covers what matters.

## Where to run it at StreetHosting[](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#hospedar)

This bot only works if the process stays on, because it is the one asking Twitch and YouTube. Running on your own computer, the alerts vanish when you turn the machine off. On the [StreetHosting bot hosting](https://streethosting.com.br/en/bots) the bot runs in a container with a panel, on Node.js, and stays up all the time. The Discord Essential plan, at R$ 9.99/month with 1 GB of RAM, handles an alert bot with room to spare, since it uses very little.

Keep the state file inside the bot folder so it stays there across restarts, and register the environment variables in the panel. If you would rather set up the process yourself, the guide on [hosting a Discord bot 24/7](https://streethosting.com.br/en/guides/discord-bots/discord-bot-hosting-24-7) explains the options.

In this guide

* [How the announcement works](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#como-funciona)
* [Twitch: create the app and get the token](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#twitch-token)
* [Twitch: check who is live](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#twitch-streams)
* [Avoiding duplicate announcements](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#evitar-duplicado)
* [YouTube: new videos from the RSS feed](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#youtube-rss)
* [The YouTube limit with live streams](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#limite-youtube-live)
* [Where to run it at StreetHosting](https://streethosting.com.br/en/guides/discord-bots/discord-bot-twitch-youtube-live-notifications#hospedar)

## Frequently asked questions

Do I have to pay to use the Twitch API?

No. Creating an application in the Twitch developer console is free and gives you a Client ID and a Client Secret. The streams lookup only needs the app access token, with no user login.

What is the difference between polling every minute and using EventSub?

With polling the bot asks every so often who is live, so the announcement can arrive up to one interval late. With EventSub, Twitch tells your bot the moment the channel goes live, but you need a WebSocket connection or a public HTTPS address to receive the webhook. For a handful of channels, polling works fine.

Does the YouTube RSS feed announce when a channel starts a live stream?

Not reliably. The feed was built for published videos and may list a live stream only after it is created, without saying whether it is live right now. To detect a live stream properly, the way is the YouTube Data API with your own key.

How do I stop the bot from announcing the same live stream several times?

Save the id of the last announcement. On Twitch each broadcast has its own id, so you just compare it with the saved one. On YouTube, save the ids of the videos already seen. Write them to a file so the record survives a bot restart.

Does the bot need to stay on all the time?

Yes. The bot process itself queries the APIs, so if it is off when the channel goes live, the announcement only goes out when it comes back. That is why it is worth hosting it somewhere that keeps the bot running 24 hours a day.

Next step

See bot plans

24/7 Discord bots with fast activation and support in Portuguese.

[See bot plans](https://streethosting.com.br/en/bots)

## Related guides

[Discord bots Intermediate How to post news from an RSS feed in a Discord channel Learn to read an RSS feed with the rss-parser library, save the last item seen, poll without overloading the site and post each story in an embed with a title and link. 7 min Read guide](https://streethosting.com.br/en/guides/discord-bots/discord-bot-rss-feed-news) [Discord bots Beginner How to use a Discord webhook for server alerts A Discord webhook is a quick way to notify your team about incidents, deploys and outages without relying on manual monitoring. 2 min Read guide](https://streethosting.com.br/en/guides/discord-bots/discord-webhook-server-alerts) [Discord bots Beginner Discord embeds with discord.js: how to build formatted messages The embed is the colored card that gives your bot's messages a professional look. Learn to build one from scratch, the official limits, what markdown works inside it and how to edit an embed that was already sent. 7 min Read guide](https://streethosting.com.br/en/guides/discord-bots/discordjs-embed-formatted-messages)

[← Back to the Guide Center](https://streethosting.com.br/en/guides)
