Viewer challenges on screen. Channel activity at a glance.
A local streaming toolkit that connects Twitch chat to a moderation queue, an OBS browser overlay and an Arduino LED indicator. It helps a streamer notice messages and donation notifications without watching the chat continuously.
Original development: autumn 2025, approximately one month (owner's estimate). Status: personal working prototype, preserved as a portfolio project. The public release adds configuration cleanup, offline tests and targeted fixes; these maintenance changes are separate from the original development period.
- Receives Twitch chat through
tmi.jsand accepts!challenge/!челенджcommands. - Validates submissions, applies per-viewer cooldowns and routes them to moderation.
- Lets the operator approve, reject, start, finish, skip and archive a session.
- Updates a browser overlay through WebSocket messages for use in OBS.
- Sends serial commands to an Arduino with 18 WS2812B LEDs using FastLED.
- Optionally polls Donatello for the newest donation and triggers an alert animation.
| Software | Hardware / integration |
|---|---|
| JavaScript, Node.js, Express, WebSocket, HTML/CSS | Arduino C/C++, FastLED, WS2812B |
| tmi.js, serialport, node-fetch fallback | Twitch chat, Donatello API, USB serial, OBS browser source |
| Node.js test runner, GitHub Actions | Data pin D6, 115200 baud, 18 LEDs in the supplied sketch |
Use Node.js 22 or newer. In a terminal in this folder:
npm ci --ignore-scripts
npm test
npm run demoOpen http://127.0.0.1:3199/. Send a synthetic challenge, open the moderation panel, approve it and choose Start Next. The overlay shows the current task. The demo page displays simulated serial commands. It never connects to Twitch, Donatello or a serial device. The normal three-minute cooldown still applies; use another synthetic viewer or reject a submission before retrying it.
- Copy
.env.exampleto.env. Keep.envprivate. - Set
TWITCH_CHANNEL,TWITCH_BOT_USERNAMEand a newly issuedTWITCH_OAUTH_TOKENfor the bot, then setTWITCH_ENABLED=1. - For hardware, open
firmware/twitch_led/twitch_led.inoin Arduino IDE, install FastLED and select the actual board and port. The file is the supplied 16A sketch with unchanged contents. SetLED_ENABLED=1and yourLED_PORT. - For donation notifications, set
DONATELLO_ENABLED=1and your ownDONATELLO_TOKEN. This optional integration polls every ten seconds. - Run
npm start. The local.envfile is loaded automatically.
This is the historical Twitch IRC/tmi.js integration; compatibility with current service permissions must be checked using your own account. No live tokens were used to validate this public release.
For OBS, add http://127.0.0.1:3199/current.html as a browser source. The local
moderation panel is http://127.0.0.1:3199/admin.html. Windows control helpers in
scripts/ target the default port 3199; update them if you change the port.
Use an appropriate regulated supply for the actual LED hardware, with a common ground and signal levels suitable for your board. Do not power an LED strip from a GPIO. The package is not a verified wiring or power-supply design.
Commands are uppercase ASCII lines ending in a newline, at 115200 baud.
| Command | Behavior in the supplied firmware |
|---|---|
OFF |
LEDs off |
CHAT |
Warm yellow animated wave / sparkles with introductory white flashes |
MOD |
Blue-purple breathing effect for moderation attention |
ALERT |
Yellow-white flashing alert |
REJECT |
Temporary red effect, then previous mode |
Pending submissions establish the MOD base state; otherwise it is OFF. Chat and
operator actions can temporarily override it. Donation effects have higher
priority than chat. The public host replaces the unsupported original COMET
approval command with CHAT; the firmware is unchanged.
These are cropped frames from the supplied historical video, not generated images or screenshots of the new demo. The frames show the interface and changing indicator illumination. They do not establish which API event caused every light change. The code documents one serial LED device. A separate live/offline stream status indicator was recalled by the owner but is not implemented in the supplied host or 16A firmware, so it is not claimed as a reproducible feature.
The application binds only to 127.0.0.1, checks browser origins and Host headers,
and requires JSON for state-changing HTTP requests. It has no operator login.
Use it on a trusted local computer; never publish it through a tunnel, proxy or
port forwarding. Local processes can still operate it.
Original credentials, viewer history, IDE settings, installed dependencies and absolute personal paths were excluded. Runtime session archives contain viewer data and must stay private. They are gitignored. Rotate any credentials that were previously shared; deleting them from a repository does not revoke them.
Known prototype limits: state is held in memory; session archives can be overwritten after restarting because session numbering restarts; the donation poller only requests the newest item and may miss bursts; the substring word filter may reject innocent text; reconnecting a disconnected serial port and calibrating the physical animations need device testing. No firmware compilation, fresh hardware test or live Twitch/Donatello end-to-end test is claimed.
- Technical document (DOCX)
- Technical document (DOC)
- Public-release changes and verification
- Demonstration frame inventory
No third-party source, hardware design or authorship license is invented by this portfolio packaging. Review permissions before reusing supplied assets elsewhere.


