Platform Stream Debuggers
CLI tools for inspecting live platform event streams in real time. Each debugger connects directly to a platform's streaming API, subscribes to all event types, and prints every incoming event with its type, timestamp, and payload.
Both tools read credentials from the database using the same config as the API server.
Shared Prerequisites
- The API database must be accessible (PostgreSQL)
- A valid
channel_connectionmust exist for the account on the target platform - The
token_encryption_keyin the config must match the key used to encrypt stored tokens - The API's Token Refresh Worker should be running (
just dev-api) to keep tokens fresh
Shared Options
| Flag | Description |
|---|---|
--account <uuid> | Required. Account UUID whose credentials to use. |
--config <path> | Config directory holding config/default.toml + config/local.toml. Defaults to the apps/api crate directory, baked in at compile time. |
--raw | Print full raw output for every event. |
Both binaries chdir into the config directory before loading Settings, so they work from any working directory without --config.
Troubleshooting
| Symptom | Cause |
|---|---|
"configuration file not found" | The --config directory has no config/ subtree - point it at apps/api or drop the flag to use the default |
"Failed to get token: invalid key length" | token_encryption_key is empty or missing in config |
"Failed to get token: decryption failed" | token_encryption_key does not match the key used to encrypt stored tokens |
"invalid authentication credentials" | Token is expired - ensure the Token Refresh Worker is running |
YouTube gRPC Debugger
Connects to YouTube's liveChatMessages.streamList gRPC API and prints every incoming chat message and event.
Usage
cargo run -p lumio-api --bin grpc-debug -- --account <uuid>
# Explicit live chat ID (skip broadcast discovery)
cargo run -p lumio-api --bin grpc-debug -- --account <uuid> --live-chat-id <id>
Additional Options
| Flag | Description |
|---|---|
--live-chat-id <id> | Skip broadcast discovery and connect directly to this chat. |
How It Works
- Looks up the YouTube
channel_connectionfor the account - Decrypts the OAuth access token from the database
- Discovers active broadcasts via the YouTube Data API (or uses
--live-chat-id) - Opens a gRPC
streamListconnection and prints every incoming item - On disconnect, fetches a fresh token and reconnects automatically
Output
[resp #1] items=42 next_page=true offline=false
[0] TextMessageEvent | id=abc123 | 2026-05-05T12:00:00Z | Username (UC...)
text: Hello world
detail: text: Some("Hello world")
[1] SuperChatEvent | id=def456 | 2026-05-05T12:01:00Z | Supporter (UC...)
text: Great stream!
detail: amount: Some(5000000) Some("EUR")
Unknown event types show their numeric value with automatic raw output:
[0] UNKNOWN(25) | id=xyz789 | 2026-05-05T12:02:00Z | ? (?)
raw: LiveChatMessage { ... }
YouTube Event Types
| Type | Description |
|---|---|
TextMessageEvent | Regular chat message |
SuperChatEvent | Paid Super Chat |
SuperStickerEvent | Paid Super Sticker |
NewSponsorEvent | New channel member |
MemberMilestoneChatEvent | Membership anniversary message |
MembershipGiftingEvent | Gift memberships sent |
GiftMembershipReceivedEvent | Gift membership received |
MessageDeletedEvent | Message deleted by moderator |
MessageRetractedEvent | Message retracted by author |
UserBannedEvent | User banned (permanent or temporary) |
PollEvent | Chat poll |
ChatEndedEvent | Stream ended |
SponsorOnlyModeStartedEvent | Members-only mode enabled |
SponsorOnlyModeEndedEvent | Members-only mode disabled |
Tombstone | Deleted message placeholder |
FanFundingEvent | Legacy fan funding |
Twitch EventSub Debugger
Connects to Twitch's EventSub WebSocket, subscribes to all event types for the account's channel, and prints every incoming notification.
Usage
cargo run -p lumio-api --bin eventsub-debug -- --account <uuid>
| Flag | Description |
|---|---|
--raw | Print the full raw JSON of every event. |
--config <dir> | Directory with config/default.toml / config/local.toml. Defaults to apps/api. |
--watch-channel <login> | Read another channel's chat instead of the account's own. Subscribes only to channel.chat.notification for that Twitch login, read as the account's connected user (the connection token needs user:read:chat), and prints every notice with its raw payload. Use it to capture notice types Twitch has not documented yet from a channel where they occur. |
--automod | AutoMod capture. Subscribes only to automod.message.hold / automod.message.update (v2) and channel.chat.message on the account's own channel and prints every event raw. The channel connection needs moderator:manage:automod; reconnect it once if it was granted before that scope was requested. Cannot be combined with --watch-channel. |
cargo run -p lumio-api --bin eventsub-debug -- --account <uuid> --watch-channel ronnygolisch
How It Works
- Looks up the account's Twitch
channel_connection - Decrypts its OAuth access token and resolves the client ID from the app that issued the token: the connection's pinned
credential_sourcepicks the global Lumio app from[auth](system, the Twitch default) or the account'sapp_credentialsrow (account). The header lineCredentials:shows which one is used - Connects to the EventSub WebSocket and receives a session ID
- Subscribes to all event types via the Helix API
- Prints every incoming event with type, user, and a human-readable summary
- On disconnect, fetches a fresh token and reconnects automatically
- Handles Twitch
session_reconnectinside the EventSub client: it opens the new URL and closes the old connection after the new welcome, and the subscriptions carry over
Output
[eventsub] Connected (session: abc123)
[eventsub] Subscribed to 25 event types
[#1] 14:32:05 | channel.chat.message | Username
chat: Hello everyone!
[#2] 14:32:08 | channel.follow | NewFollower
new follower
[#3] 14:32:15 | channel.subscribe | Subscriber
tier 1000 sub
[#4] 14:33:01 | channel.raid | OtherStreamer
raid with 150 viewers
[#5] 14:33:45 | channel.ban | ModName
timeout: spam
[#6] 14:34:00 | stream.offline |
stream went OFFLINE
Twitch Event Types
| Type | Description |
|---|---|
channel.chat.message | Chat message |
channel.chat.message_delete | Single message deleted by a moderator |
channel.chat.notification | Sub, resub, gift sub, raid notice in chat |
channel.follow | New follower |
channel.subscribe | New subscription |
channel.subscription.gift | Gift subscriptions |
channel.subscription.message | Resub message |
channel.cheer | Bits cheer |
channel.raid | Incoming raid |
channel.ban | User banned or timed out |
channel.unban | User unbanned |
channel.moderate | Moderator action |
channel.channel_points_custom_reward_redemption.add | Channel point redemption |
channel.channel_points_custom_reward_redemption.update | Redemption fulfilled or canceled |
channel.channel_points_custom_reward.add/update/remove | Custom reward created, changed or deleted |
channel.poll.begin/progress/end | Poll lifecycle |
channel.prediction.begin/progress/lock/end | Prediction lifecycle |
channel.hype_train.begin/progress/end | Hype train lifecycle |
channel.goal.begin/progress/end | Goal lifecycle |
channel.update | Stream title/category/language change (tags read from Helix, see Events → Stream update payloads) |
channel.ad_break.begin | Ad break started |
channel.suspicious_user.message | Suspicious user message |
channel.suspicious_user.update | Suspicious user status change |
stream.online | Stream went live |
stream.offline | Stream ended |