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
- Open your Discord server and go to the channel where you want tip announcements.
- Click Edit Channel → Integrations → Webhooks → New Webhook.
- Name it (e.g., "Tizemint Tips") and copy the webhook URL.
Step 2: Install Dependencies
npm init -y
npm install eventsourceStep 3: Discord Tip Bot Script
// 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
TIZEMINT_TOKEN=tzmnt_your_token \
DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... \
node tizemint-discord.jsTip 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
- Log in to Twitch as the bot account.
- Go to https://twitchapps.com/tmi/ and click Connect.
- Authorize and copy the
oauth:...token.
Store this token securely in an environment variable — never hardcode it or commit it to version control.
Step 3: Install Dependencies
npm init -y
npm install eventsource tmi.jsStep 4: Twitch Chat Bot Script
// 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
TIZEMINT_TOKEN=tzmnt_your_token \
TWITCH_USERNAME=YourBotName \
TWITCH_OAUTH=oauth:your_oauth_token \
TWITCH_CHANNEL=your_channel_name \
node tizemint-twitch.jsRunning Both at Once
You can run both bots in the same process by combining them, or use PM2 to manage them as separate services:
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 startupEvent Reference
| Event Type | Description |
|---|---|
| tip:received | A viewer sent a tip |
| tip:goal-completed | A tip filled the current goal |
| tip:overflow-chain | Overflow from a completed goal started a new one |
| tip:queue-updated | Goal 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.