Skip to main content

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_connection must exist for the account on the target platform
  • The token_encryption_key in 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​

FlagDescription
--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.
--rawPrint 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​

SymptomCause
"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​

FlagDescription
--live-chat-id <id>Skip broadcast discovery and connect directly to this chat.

How It Works​

  1. Looks up the YouTube channel_connection for the account
  2. Decrypts the OAuth access token from the database
  3. Discovers active broadcasts via the YouTube Data API (or uses --live-chat-id)
  4. Opens a gRPC streamList connection and prints every incoming item
  5. 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​

TypeDescription
TextMessageEventRegular chat message
SuperChatEventPaid Super Chat
SuperStickerEventPaid Super Sticker
NewSponsorEventNew channel member
MemberMilestoneChatEventMembership anniversary message
MembershipGiftingEventGift memberships sent
GiftMembershipReceivedEventGift membership received
MessageDeletedEventMessage deleted by moderator
MessageRetractedEventMessage retracted by author
UserBannedEventUser banned (permanent or temporary)
PollEventChat poll
ChatEndedEventStream ended
SponsorOnlyModeStartedEventMembers-only mode enabled
SponsorOnlyModeEndedEventMembers-only mode disabled
TombstoneDeleted message placeholder
FanFundingEventLegacy 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>
FlagDescription
--rawPrint 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.
--automodAutoMod 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​

  1. Looks up the account's Twitch channel_connection
  2. Decrypts its OAuth access token and resolves the client ID from the app that issued the token: the connection's pinned credential_source picks the global Lumio app from [auth] (system, the Twitch default) or the account's app_credentials row (account). The header line Credentials: shows which one is used
  3. Connects to the EventSub WebSocket and receives a session ID
  4. Subscribes to all event types via the Helix API
  5. Prints every incoming event with type, user, and a human-readable summary
  6. On disconnect, fetches a fresh token and reconnects automatically
  7. Handles Twitch session_reconnect inside 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​

TypeDescription
channel.chat.messageChat message
channel.chat.message_deleteSingle message deleted by a moderator
channel.chat.notificationSub, resub, gift sub, raid notice in chat
channel.followNew follower
channel.subscribeNew subscription
channel.subscription.giftGift subscriptions
channel.subscription.messageResub message
channel.cheerBits cheer
channel.raidIncoming raid
channel.banUser banned or timed out
channel.unbanUser unbanned
channel.moderateModerator action
channel.channel_points_custom_reward_redemption.addChannel point redemption
channel.channel_points_custom_reward_redemption.updateRedemption fulfilled or canceled
channel.channel_points_custom_reward.add/update/removeCustom reward created, changed or deleted
channel.poll.begin/progress/endPoll lifecycle
channel.prediction.begin/progress/lock/endPrediction lifecycle
channel.hype_train.begin/progress/endHype train lifecycle
channel.goal.begin/progress/endGoal lifecycle
channel.updateStream title/category/language change (tags read from Helix, see Events → Stream update payloads)
channel.ad_break.beginAd break started
channel.suspicious_user.messageSuspicious user message
channel.suspicious_user.updateSuspicious user status change
stream.onlineStream went live
stream.offlineStream ended