Docsv1.0
Docs/Guides/Discord / Twitch Bot

Discord / Twitch Bot

Announce tips in Discord or Twitch chat automatically.

Discord / Twitch Bot

Announce tips in your Discord server or Twitch chat the moment they arrive. Both examples use the Tizemint SSE stream.


Prerequisites

  • A Tizemint API token (tzmnt_...) from Settings → API Tokens
  • For Discord: a Discord webhook URL
  • For Twitch: a bot account OAuth token
  • Node.js 18+

Approach A: Discord Webhook

Discord webhooks are the simplest way to post messages — no bot account needed.

Step 1: Create a Discord Webhook

  1. Open your Discord server and go to the channel where you want tip announcements.
  2. Click Edit Channel → Integrations → Webhooks → New Webhook.
  3. Name it (e.g., "Tizemint Tips") and copy the webhook URL.

Step 2: Install Dependencies

bash
npm init -y
npm install eventsource

Step 3: Discord Tip Bot Script

js
// tizemint-discord.js
import EventSource from "eventsource";
 
const TIZEMINT_TOKEN = process.env.TIZEMINT_TOKEN;     // tzmnt_...
const DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL;
 
if (!TIZEMINT_TOKEN || !DISCORD_WEBHOOK_URL) {
  console.error("Missing TIZEMINT_TOKEN or DISCORD_WEBHOOK_URL");
  process.exit(1);
}
 
function formatAmount(cents) {
  return `$${(cents / 100).toFixed(2)}`;
}
 
async function postToDiscord(payload) {
  const res = await fetch(DISCORD_WEBHOOK_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
  if (!res.ok) {
    console.error(`Discord webhook failed: ${res.status} ${await res.text()}`);
  }
}
 
async function handleEvent(data) {
  switch (data.type) {
    case "tip:received": {
      const amount = formatAmount(data.amount);
      const msg = data.message ? `\n> "${data.message}"` : "";
      await postToDiscord({
        embeds: [
          {
            title: "New Tip!",
            description: `**${data.displayName}** tipped **${amount}**${msg}`,
            color: 0x10b981, // Tizemint brand green
            timestamp: data.timestamp,
          },
        ],
      });
      break;
    }
 
    case "tip:goal-completed": {
      await postToDiscord({
        embeds: [
          {
            title: "Goal Completed!",
            description: `The goal has been reached! Thanks to everyone who contributed.`,
            color: 0x8b5cf6, // Purple for celebrations
            timestamp: data.timestamp,
          },
        ],
      });
      break;
    }
 
    default:
      // Ignore tip:overflow-chain and tip:queue-updated unless you want them
      break;
  }
}
 
function connect() {
  const url = `https://tizemint.com/api/tip-events/stream?token=${TIZEMINT_TOKEN}`;
  const es = new EventSource(url);
 
  es.onopen = () => console.log("[discord-bot] Connected to Tizemint stream");
 
  es.onmessage = async (event) => {
    let data;
    try {
      data = JSON.parse(event.data);
    } catch {
      return; // Keep-alive ping or malformed message
    }
    await handleEvent(data);
  };
 
  es.onerror = () => {
    console.log("[discord-bot] Connection lost, reconnecting in 5s...");
    es.close();
    setTimeout(connect, 5000);
  };
}
 
connect();

Step 4: Run It

bash
TIZEMINT_TOKEN=tzmnt_your_token \
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... \
node tizemint-discord.js
Tip

Tip amounts are in cents. 500 = $5.00. The formatAmount() helper handles this conversion.


Approach B: Twitch Chat

Post tip alerts directly into your Twitch channel chat using a bot account.

Step 1: Create a Bot Account (Optional)

You can use your own Twitch account, but a dedicated bot account (e.g., YourNameBot) keeps chat cleaner. Either way, you need an OAuth token.

Step 2: Get a Twitch OAuth Token

  1. Log in to Twitch as the bot account.
  2. Go to https://twitchapps.com/tmi/ and click Connect.
  3. Authorize and copy the oauth:... token.
Warning

Store this token securely in an environment variable — never hardcode it or commit it to version control.

Step 3: Install Dependencies

bash
npm init -y
npm install eventsource tmi.js

Step 4: Twitch Chat Bot Script

js
// tizemint-twitch.js
import EventSource from "eventsource";
import tmi from "tmi.js";
 
const TIZEMINT_TOKEN = process.env.TIZEMINT_TOKEN;    // tzmnt_...
const TWITCH_USERNAME = process.env.TWITCH_USERNAME;  // Bot's Twitch username
const TWITCH_OAUTH = process.env.TWITCH_OAUTH;        // oauth:xxxxxx
const TWITCH_CHANNEL = process.env.TWITCH_CHANNEL;    // Channel name (no #)
 
if (!TIZEMINT_TOKEN || !TWITCH_USERNAME || !TWITCH_OAUTH || !TWITCH_CHANNEL) {
  console.error(
    "Missing env vars: TIZEMINT_TOKEN, TWITCH_USERNAME, TWITCH_OAUTH, TWITCH_CHANNEL"
  );
  process.exit(1);
}
 
function formatAmount(cents) {
  return `$${(cents / 100).toFixed(2)}`;
}
 
// Connect the Twitch chat client
const client = new tmi.Client({
  identity: {
    username: TWITCH_USERNAME,
    password: TWITCH_OAUTH,
  },
  channels: [TWITCH_CHANNEL],
});
 
async function handleEvent(data) {
  switch (data.type) {
    case "tip:received": {
      const amount = formatAmount(data.amount);
      const parts = [
        `tizemintTip ${data.displayName} just tipped ${amount}!`,
      ];
      if (data.message) {
        parts.push(`"${data.message}"`);
      }
      await client.say(TWITCH_CHANNEL, parts.join(" "));
      break;
    }
 
    case "tip:goal-completed": {
      await client.say(
        TWITCH_CHANNEL,
        `tizemintGoal Goal reached! Thank you everyone who contributed! PogChamp`
      );
      break;
    }
 
    default:
      break;
  }
}
 
function connectSSE() {
  const url = `https://tizemint.com/api/tip-events/stream?token=${TIZEMINT_TOKEN}`;
  const es = new EventSource(url);
 
  es.onopen = () => console.log("[twitch-bot] Connected to Tizemint stream");
 
  es.onmessage = async (event) => {
    let data;
    try {
      data = JSON.parse(event.data);
    } catch {
      return;
    }
    await handleEvent(data);
  };
 
  es.onerror = () => {
    console.log("[twitch-bot] SSE connection lost, reconnecting in 5s...");
    es.close();
    setTimeout(connectSSE, 5000);
  };
}
 
// Start Twitch client first, then begin listening for events
client.connect().then(() => {
  console.log(`[twitch-bot] Connected to Twitch chat: #${TWITCH_CHANNEL}`);
  connectSSE();
});

Step 5: Run It

bash
TIZEMINT_TOKEN=tzmnt_your_token \
TWITCH_USERNAME=YourBotName \
TWITCH_OAUTH=oauth:your_oauth_token \
TWITCH_CHANNEL=your_channel_name \
node tizemint-twitch.js

Running Both at Once

You can run both bots in the same process by combining them, or use PM2 to manage them as separate services:

bash
npm install -g pm2
 
# Discord bot
pm2 start tizemint-discord.js --name tizemint-discord \
  --env TIZEMINT_TOKEN=tzmnt_... \
  --env DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...
 
# Twitch bot
pm2 start tizemint-twitch.js --name tizemint-twitch \
  --env TIZEMINT_TOKEN=tzmnt_... \
  --env TWITCH_USERNAME=YourBot \
  --env TWITCH_OAUTH=oauth:... \
  --env TWITCH_CHANNEL=yourchannel
 
pm2 save
pm2 startup

Event Reference

Event TypeDescription
tip:receivedA viewer sent a tip
tip:goal-completedA tip filled the current goal
tip:overflow-chainOverflow from a completed goal started a new one
tip:queue-updatedGoal queue reordered

Troubleshooting

Discord embeds don't appear Confirm the webhook URL is correct and the channel hasn't been deleted. Discord webhooks return 204 on success — any other status means an error.

Twitch bot joins but doesn't post Ensure the bot account has been granted permission to chat in your channel (it must not be banned or restricted by follower-only / subscriber-only mode). Check the TWITCH_CHANNEL value has no # prefix.

tmi.js login authentication failed Your OAuth token may have expired or been revoked. Re-generate it at twitchapps.com/tmi.

Messages post twice You may have two instances of the script running. Check with pm2 list or ps aux | grep tizemint.