Webhook Tutorial: Auto-Posting Twitch Live Status to Telegram
technicaltutorialbots

Webhook Tutorial: Auto-Posting Twitch Live Status to Telegram

ttelegrams
2026-01-23 12:00:00
11 min read
Advertisement

A practical 2026 tutorial: use Twitch EventSub + a Telegram bot to auto-post live stream alerts, with secure webhook handling and deploy tips.

Hook: Stop losing viewers while you fiddle with alerts — automate Twitch live posts to Telegram

Creators and publishers tell me the same pain: streams go live, but audiences on Telegram don’t hear about it fast enough — or you spend minutes posting manually every session. In 2026 the expectation is instant, cross-platform notifications. This guide walks you through a reliable, secure webhook solution using Twitch EventSub and a Telegram bot so your channel or group gets automatic, polished live alerts the moment a stream starts.

What you’ll build and why it matters in 2026

By the end of this tutorial you'll have a production-ready flow that:

  • Uses Twitch EventSub (webhook) to detect stream.online and stream.offline events.
  • Verifies Twitch signatures and handles callback verification securely.
  • Fetches stream details via the Twitch Helix API for rich messages.
  • Posts formatted announcements to Telegram channels or groups via a Telegram bot.
  • Uses best practices for deployment, rate-limit handling, and deduplication.

Context for 2026: platforms pushed creators toward automation in late 2025 — multi-network streaming, better EventSub coverage on Twitch, and wider adoption of messaging apps like Telegram and Bluesky for audience retention. Automating live notifications is now a baseline growth tactic.

High-level architecture

  1. Twitch detects a broadcaster going live and sends an EventSub webhook to your publicly accessible callback endpoint.
  2. Your server verifies the signature and the message-type (verification, notification, revocation).
  3. On notification (stream.online), your server optionally fetches enhanced stream data from Twitch Helix and composes a Telegram-ready announcement.
  4. Your server calls the Telegram Bot API to post the message to a channel or group where your bot has posting permissions.

Before you start: requirements checklist

  • Twitch Developer Account, Client ID and Client Secret.
  • Public HTTPS endpoint (ngrok for testing; VPS, Cloud Run, Vercel, or a small server for production).
  • Node.js 18+ or your preferred runtime (examples use Node + Express).
  • Telegram bot token (create via BotFather) and the chat_id of the target channel/group.
  • Storage for secrets (environment variables, vault, or managed secret store).

Step 1 — Register a Twitch app and get an App Access Token

  1. Go to the Twitch Developer Console and create an app. Set the OAuth Redirect URI to any placeholder (you'll use the callback URL for EventSub).
  2. Record your Client ID and Client Secret.
  3. Request an App Access Token (client credentials flow). Example curl:
curl -X POST "https://id.twitch.tv/oauth2/token" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "grant_type=client_credentials"

You’ll receive an access_token used for creating EventSub subscriptions and calling Helix endpoints.

Step 2 — Create an EventSub webhook subscription

EventSub supports webhooks and websockets. Webhooks are easiest for Telegram pipelines because they push notifications to your callback URL.

Key subscription types for live notifications:

  • stream.online — broadcaster goes live.
  • stream.offline — stream ended.

Create subscription via Helix:

curl -X POST "https://api.twitch.tv/helix/eventsub/subscriptions" \
    -H "Client-ID: YOUR_CLIENT_ID" \
    -H "Authorization: Bearer YOUR_APP_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "stream.online",
      "version": "1",
      "condition": { "broadcaster_user_id": "BROADCASTER_ID" },
      "transport": {
        "method": "webhook",
        "callback": "https://yourdomain.com/twitch/callback",
        "secret": "YOUR_SECRET"
      }
    }'
  

Notes:

  • secret is used to compute an HMAC so you can verify requests.
  • Twitch will send a verification challenge to the callback URL — your server must reply with the challenge as plain text within the verification response.

Step 3 — Build the webhook receiver (Node.js + Express example)

Core responsibilities for the endpoint:

  • Verify signatures: HMAC-SHA256 of message_id + timestamp + body using the subscription secret.
  • Handle verification challenge responses.
  • Process notification events and forward to Telegram.

Minimal example (install express, axios):

const express = require('express');
const crypto = require('crypto');
const axios = require('axios');

const app = express();
app.use(express.json({ limit: '1mb' }));

const TWITCH_SECRET = process.env.TWITCH_SECRET; // from subscription
const TELEGRAM_TOKEN = process.env.TELEGRAM_TOKEN;
const TELEGRAM_CHAT = process.env.TELEGRAM_CHAT; // e.g. -1001234567890

function verifyTwitch(req) {
  const messageId = req.header('Twitch-Eventsub-Message-Id');
  const timestamp = req.header('Twitch-Eventsub-Message-Timestamp');
  const signature = req.header('Twitch-Eventsub-Message-Signature');
  const body = JSON.stringify(req.body);
  const hmacMessage = messageId + timestamp + body;
  const expected = 'sha256=' + crypto.createHmac('sha256', TWITCH_SECRET).update(hmacMessage).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

app.post('/twitch/callback', async (req, res) => {
  const messageType = req.header('Twitch-Eventsub-Message-Type');

  // Verification request
  if (messageType === 'webhook_callback_verification') {
    return res.status(200).send(req.body.challenge);
  }

  // Security: verify signature for notifications and revocations
  if (!verifyTwitch(req)) {
    console.warn('Invalid signature');
    return res.sendStatus(403);
  }

  if (messageType === 'notification') {
    const { type } = req.body.subscription;
    const event = req.body.event;

    if (type === 'stream.online') {
      // Compose announcement (we'll fetch more details below)
      await sendTelegramLiveMessage(event);
    }

    if (type === 'stream.offline') {
      await sendTelegramOfflineMessage(event);
    }
  }

  return res.sendStatus(200);
});

async function sendTelegramLiveMessage(event) {
  // event contains broadcaster_user_id, broadcaster_user_login, started_at
  // optionally fetch current stream info via Helix /streams for title, thumbnail
  const title = `[LIVE] ${event.broadcaster_user_name} is live!`;
  const link = `https://twitch.tv/${event.broadcaster_user_login}`;
  const text = `${title}\n\n${link}\nStarted: ${event.started_at}`;

  await axios.post(`https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`, {
    chat_id: TELEGRAM_CHAT,
    text,
    disable_web_page_preview: false
  });
}

async function sendTelegramOfflineMessage(event) {
  const text = `⚪️ ${event.broadcaster_user_name} has ended the stream.`;
  await axios.post(`https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`, {
    chat_id: TELEGRAM_CHAT,
    text
  });
}

app.listen(process.env.PORT || 3000);

This example is intentionally minimal. Below we cover production hardening, signing verification edge-cases, and rich message building.

Step 4 — Enrich notifications: fetch stream data from Helix

Twitch EventSub notification gives you broadcaster id and start time. For a polished Telegram post include the stream title, game name, and a dynamic preview thumbnail. Use the Helix Get Streams endpoint:

GET https://api.twitch.tv/helix/streams?user_id=BROADCASTER_ID

Headers:
  Client-ID: YOUR_CLIENT_ID
  Authorization: Bearer YOUR_APP_ACCESS_TOKEN

The response includes title, viewer_count, thumbnail_url (with placeholders {width}x{height}). Compose a message template like:

Template: 🎥 {display_name} is live now — {title}\nGame: {game_name} • Viewers: {viewer_count}\nWatch: {url}

Attach the thumbnail by replacing the placeholders to request a good resolution, then send as chat photo or as message with web preview.

Step 5 — Telegram bot setup and permissions

  1. Create a bot using BotFather; get the BOT_TOKEN.
  2. Invite the bot to your channel or group.
  3. For channels: add the bot as an admin with permission to post messages. Use the channel handle (@channelname) or its internal chat_id (starts with -100...). If you don’t know chat_id, add the bot to channel and call getUpdates or use a helper endpoint to resolve id.
  4. For groups: make bot admin or allow it to post. For private groups, you’ll need the numeric chat_id.

Tip: use sendMessage for simple posts or sendPhoto / sendMediaGroup for richer alerts with thumbnails and buttons. Add an inline keyboard to include CTAs like “Watch Live” or “Subscribe”.

Message templates and CTAs that work

Use short, action-oriented text and buttons. Examples:

  • Basic: 🎥 {name} is live now — {title} \n Watch: {link}
  • Rich: include thumbnail + inline keyboard [{Watch}, {Clips}, {Subscribe}]
  • Membership upsell: “Members: special reward tonight — join here” + private link to a members-only chat.

Examples of inline keyboard payload (JSON) for sendMessage:

{
  reply_markup: {
    inline_keyboard: [[
      { text: '🎬 Watch', url: 'https://twitch.tv/username' },
      { text: '✨ Clips', url: 'https://twitch.tv/username/clips' }
    ]]
  }
}

Deployment & testing tips

  • Local testing: use ngrok to expose localhost for Twitch verification. Remember Twitch verification is required when creating the subscription.
  • Serverless: if using Vercel or Netlify serverless functions ensure the function responds to verification quickly (Twitch expects the challenge reply) and supports raw body to verify signatures.
  • Production: use HTTPS with a valid TLS certificate. Host on a low-latency endpoint in your audience region.

Security & reliability best practices

  • Verify signatures on every request using the secret given when creating the subscription.
  • Store secrets in environment variables or secret managers; do not hard-code them.
  • Use timingSafeEqual for HMAC comparison to prevent timing attacks.
  • Implement idempotency: Twitch can resend notifications. Deduplicate by message ID or event timestamp stored for a short window.
  • Monitor revocations: Twitch sends a revocation message if the subscription is revoked; alert yourself to re-subscribe automatically.
  • Respect rate limits for both Twitch and Telegram — implement retries with exponential backoff for transient failures.

Handling edge cases

  • Short test streams: stream.online may trigger for very short broadcasts. Add a debounce (e.g., post only if stream lasted > 30s or wait 15–30s for a follow-up notification).
  • Multiple broadcasters: if you manage alerts for many channels, use a per-broadcaster secret or centralize validation and queueing for scale.
  • Multiple platforms: use the same webhook logic to fan-out to Discord, Bluesky, or email. Template messages for each platform to avoid cross-posted awkwardness.

Advanced strategies: personalization, analytics, and monetization

Once the core pipeline runs reliably, these techniques help grow and monetize your Telegram audience in 2026:

  • Segmented alerts: Send different messages to public channel vs members-only group (premium alerts with behind-the-scenes links).
  • Smart dedupe and scheduling: Prevent spam by limiting posts per day per channel and scheduling a morning digest for streams that start during off-hours.
  • Analytics: Track click-throughs via UTM links to measure conversions from Telegram to Twitch. Feed data to a simple dashboard.
  • Automated highlights: After stream.offline, trigger a job to create clips and post a highlight summary with a “Watch the replay” CTA.
  • Cross-platform promotion: 2025–26 trends show creators amplify live streams by posting previews to Bluesky and Telegram simultaneously. Use the same webhook to post tailored messages to each network.

Common pitfalls and how to avoid them

  • Missing verification response during subscription creation — ensure your callback returns the challenge body exactly as sent.
  • Bot not allowed to post — give admin rights in channel or group.
  • Not handling revocations — subscribe management is essential; re-create subscriptions automatically when tokens renew.
  • Using long-running synchronous processing in the webhook — acknowledge Twitch quickly (200 OK) and process notifications asynchronously if heavy work is required.

Sample production checklist

  1. HTTPS endpoint with valid certificate and low latency.
  2. Secrets stored in environment variables or secret vault; keys rotated every 90 days.
  3. Logging and alerting for verification failures and revocations.
  4. Retry logic and rate-limit handling for Telegram API calls.
  5. Dedicated job queue (BullMQ or SQS) for enrichment tasks (fetching thumbnails, generating clips).

Quick debugging workflow

  1. Use ngrok logs to observe incoming Twitch callbacks when testing locally.
  2. Check headers: Twitch-Eventsub-Message-Id / Timestamp / Signature / Type.
  3. Log the raw request body before parsing (store only in safe logs) to reproduce signature verification locally.
  4. If Telegram posts fail, call getUpdates or check bot privacy settings via BotFather and confirm chat_id.

Only post streams for broadcasters who consent. If you manage alerts for a multi-streamer network, store personal data only where necessary and follow GDPR/CCPA best practices when you keep event logs containing user info.

As of 2026 the ecosystem favors automation more than ever. Twitch’s EventSub continues to add new event types (commerce events, extensions signals) and messaging apps like Telegram make bots first-class for audience engagement. Expect to expand this webhook into multi-channel funnels (Telegram, Bluesky, Mastodon, Discord) and to integrate AI-driven summarization for post-stream highlights.

Wrap-up: actionable checklist to go live

  1. Create Twitch app and acquire Client ID/Secret.
  2. Deploy a public HTTPS webhook or expose via ngrok for testing.
  3. Create EventSub subscription(s) with a secret and point to your callback.
  4. Build verification logic (HMAC) and handle message types (verification, notification, revocation).
  5. Fetch Helix /streams for enriched content and craft Telegram messages with thumbnails and inline keyboard CTAs.
  6. Give your bot posting rights and test in a private channel before publishing to your main audience.
  7. Monitor for revocations, rotate secrets, and implement dedupe logic.

Starter templates and next steps

Use the Node.js example in this article as a base. Expand by adding a job queue (BullMQ or SQS), caching stream metadata to reduce Helix calls, and integrate analytics for click tracking. If you want a ready-made repo or Telegram message templates, I maintain a collection of starter scripts and copy-ready announcement cards for creators.

Call to action

Ready to stop missing viewers? Deploy your webhook this week: set up the Twitch app, spin up a small HTTPS endpoint, and try the Node.js example with ngrok. Join our Telegram channel for creators to get the starter repo, announcement templates, and a step-by-step checklist tailored to multi-streamer networks. Click through, clone the starter code, and automate your first live alert today.

Advertisement

Related Topics

#technical#tutorial#bots
t

telegrams

Contributor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

Advertisement
2026-01-24T17:16:08.634Z