Twitch Bot • OBS Overlays • Chrome Extension • Full-Stack + DevOps

Twitch Stream Toolkit

A config-driven Twitch bot with a real-time OBS overlay system and a Twitch-authenticated web admin panel, built on Node with zero web dependencies and deployed on AWS behind automatic HTTPS, paired with a companion Chrome extension that automates on-stream privacy protection. Built for a live channel (internally “bob-a-bot”), then generalized into a reusable, secret-free template.

Status Live in Production

Runs 24/7 for a live Twitch channel. Overlays are public; the admin panel sits behind Twitch login.

Deployments

Channels It Runs For

Live01

bobavillain

Runs 24/7 as “bob-a-bot” on the Twitch channel bobavillain, the channel it was originally built for.

Scalable02

Ready for More

Because the whole platform is config-driven, the same bot can be stood up for additional channels from a single JSON file, with no code changes.

Project Summary

Project Overview

Purpose

One self-hosted app that covers counters, song requests, alerts, moderation, and on-stream overlays, fully controllable by the streamer and their mods from chat or a web dashboard.

Problem

Streamers usually stitch together several paid third-party services to cover these features. This replaces them with a single app the streamer owns and controls.

Approach

Built for one specific channel, then generalized into a config-driven template so the same platform can be stood up for anyone.

Feature System

Core Features

Chat01

Chat & Channel Points

  • Counters via Channel Points, bit cheers, and chat commands
  • Custom commands matched on the first word
  • Timers and timed challenges
  • Clips and stream title / category controls
Community02

Moderation & Community

  • Shoutouts (/announce plus native Twitch popup)
  • Follower thanks and follow-age lookups
  • Chat moderation: timeout, ban, and unban
  • Redeem logs and a game backlog
Overlays03

OBS Overlays

  • Three independent, movable browser sources
  • Countdown timer that cycles through multiple timers
  • Live counters ticker
  • Spotify now-playing card that auto shows / hides
Control04

Web Admin Panel

  • Twitch login, gated to broadcaster, allowlist, and mods
  • Live counters and command / quote / game management
  • Timeout, ban, unban, and redeem history
  • Diagnostics page that fires overlay tests
Integrations05

External Services

  • Spotify song requests
  • DeepL live translation
  • Weather (Open-Meteo) and other no-key APIs
  • Each integration stays off until it's configured
Events06

Live Events (EventSub)

  • Channel Point redemptions
  • Raids and go-live notifications
  • New follows
  • Delivered over an EventSub WebSocket listener
In OBS

Overlay Preview

Countdown timer overlay showing a label, a quoted note, a 0:09 countdown, and a progress bar

Countdown timer: label, note, live countdown, and a progress bar, cycling through multiple configured timers.

Live counters ticker overlay showing two counters, Spicy at 1 and Pushups at 11

Live counters ticker: one card per active counter, driven by Channel Points, bit cheers, and chat commands.

Spotify now-playing overlay showing the current track title and artist with a progress bar

Spotify now-playing card: current track and artist with a progress bar, auto showing and hiding with playback.

Architecture

How It Works

Process01

One Long-Lived Node Process

A single process connects to Twitch chat and EventSub and starts an embedded web server in the same process, with no separate services to orchestrate.

Web Layer02

One Server, Three Jobs

The embedded server serves the OBS overlays (pushing live state over SSE), serves the Twitch-OAuth admin panel, and exposes a small JSON API the panel calls.

Edge03

Reverse Proxy

Caddy sits in front on port 443 for HTTPS and proxies to the bot on an internal port, keeping the Node process off the public interface.

State04

Flat-File Persistence

Counters, commands, quotes, and timers persist to JSON files on disk, one file per feature. Simple, transparent, and trivially backed up, with no database to run.

New: Client-Side Companion

Streamer Privacy Guard

An unpacked Chrome extension that redacts personal information and blocks mail sites, but only while the stream is live. Offline, it is fully unloaded rather than merely disabled: no content script runs, no blocking rules exist, nothing executes on any page. Not published to the Chrome Web Store by design; loaded unpacked on the streaming machine.

Google search results for a coffee shop with the map thumbnail blurred and the address and hours lines blacked out while the stream is live
Example

Search results redacted live: the map thumbnail is blurred and location detail lines are blacked out, matching the Redaction and Location Guard behavior.

Browser tab showing a Hidden while live placeholder in place of Gmail, explaining the site is blocked while streaming and will restore automatically once the stream ends
Example

A mail host swapped for the self-restoring placeholder: nothing is closed, and the tab returns to Gmail on its own once the stream ends.

Signal01

Live State from the Bot

Polls a public /live endpoint added to the existing bot server, backed by an in-memory value that Twitch EventSub keeps current, so checking it costs nothing. A missing or stale signal is treated as live, so a dropped connection can never silently un-blur the screen.

Redaction02

Text, Two Layers Deep

A personal list of exact strings (name, address, old handles) plus generic safety-net patterns for emails, phones, addresses, and Luhn-checked card numbers. Three looks are available: blend, black bars, and a tunable blur, chosen per field.

Location03

Maps and Place Names

Blurs and desaturates map surfaces across Google Maps, embedded iframes, and Leaflet/Mapbox/OpenLayers widgets, and hides the location furniture search engines and shops wrap around a city, down to context-matched ZIPs and a curated place-name list.

Blocking04

Self-Restoring Mail Blocks

Mail hosts redirect to a local placeholder that carries the original URL and navigates back on its own once the stream ends. Nothing is closed and no draft is lost; the tab title is blanked before the redirect so the address never flashes.

Modes05

Auto, Always On, Always Off

Auto follows the live signal for normal use. Always On arms it for testing or a minute before going live. Always Off stays fully dormant. Both forced modes badge purple so a test can never be mistaken for a real live signal.

Escape Hatch06

Hold to Peek

A configurable hold-to-peek shortcut reveals redactions only while held, with a warning banner across the top. Releasing the key, switching tabs, or leaving the window all re-hide immediately.

Why It Works This Way

Privacy Guard Decisions

Fail-Safe01

Unknown State Means Stay Redacted

A missing check or one older than two minutes is treated the same as live. Worst case is mild annoyance browsing off-stream; the alternative worst case is a doxx on stream, so the fallback only ever leans toward more redaction, never less.

Recoverability02

Text Is Barred or Blended, Never Blurred

A blurred string can be undone by rendering candidate text at the same radius and matching against the frame, since the alphabet is small and known, a documented attack a VOD gives unlimited time to run. Maps get heavy blur instead, since deblurring imagery isn't practical the same way.

Footprint03

Dormant Means Unloaded, Not Idle

The content script is registered when live and unregistered when offline through chrome.scripting, so when the stream is down no extension code runs on any page at all rather than sitting idle on every tab.

Reliability04

Two Independent Blocking Paths

Chrome silently refuses declarativeNetRequest redirects for null-initiator navigations, like a typed URL, with no error anywhere. A second, independent tabs listener does the same job so either path alone can fail without the block failing.

Tech Stack

Tools + Build

Node.js 18+ES ModulestwurpleTwitch Helix APITwitch EventSubOAuth 2.0Server-Sent EventsNode httpcrypto HMAC SessionsSpotify Web APIDeepL APIVanilla HTML/CSS/JSAWS EC2CaddyLet's Encrypt TLSpm2cron BackupsUptimeRobotFlat-file JSONChrome Extension (MV3)declarativeNetRequestchrome.scriptingMutationObserver
Engineering + Design

Decisions Worth Calling Out

Config01

Config-Driven, Not Hard-Coded

Around 40 features toggle and tune through a single JSON file, so a non-developer can reconfigure the bot and it generalizes cleanly into a template. This is the core architectural bet.

Footprint02

Zero Web Dependencies

Routing, SSE, sessions, OAuth, and CSRF are all built on Node built-ins plus fetch: no Express, no framework, no build step. Tiny footprint and minimal supply-chain surface.

Realtime03

SSE-Driven Overlays

Overlay updates are one-directional, so Server-Sent Events beat WebSockets here: simpler, auto-reconnecting, no library. Countdowns tick locally in the browser from a server-sent end timestamp, so they stay smooth and network-light.

Security04

Security by Least Exposure

Overlays are gated by a secret key; the admin panel is Twitch-OAuth gated to an allowlist and mods, with HMAC-signed SameSite=Lax session cookies and a custom-header CSRF check. No secrets ever reach the client.

Infrastructure + Ops

Deployment & Reliability

Cloud01

Self-Hosted on AWS

Runs on an AWS EC2 instance (Amazon Linux) with pm2 for process management and reboot persistence, on a static Elastic IP with DNS via a subdomain.

HTTPS02

Automatic TLS

A Caddy reverse proxy provisions and renews Let's Encrypt certificates automatically, so HTTPS is hands-off.

Reliability03

Backups & Monitoring

Nightly cron backups protect the flat-file data, and UptimeRobot health-checks a /health endpoint so outages surface immediately.

Reuse04

Reusable Template

Extracted a generic, secret-free template from the live bot without taking the running instance down, genericizing hard-coded labels into config along the way.

Problem Solving

Engineering Challenges

Overlay01

Multi-Timer Reconciliation

Several timers can run at once (challenge redeems plus reminders). The overlay reconciles a live list over SSE and cycles through them (~15s each), giving each its own style and an independent local countdown.

Legibility02

Readable Over Any Scene

Overlays have to read over arbitrary gameplay footage. Solved with solid tile backings and text outlines (no drop shadows), tested against both bright and dark scenes.

Keep Exploring

More projects like this

← Back to all projects