Skip to content

feat: Twitch messenger channel integration #99

Description

@aecs4u

Summary

Add Twitch integration to enable RustyClaw agents to communicate in Twitch chat channels for livestream interactions.

Background

Twitch is the world's leading livestreaming platform with 140M+ monthly active users. Key features:

  • IRC-based chat protocol
  • Emote system
  • Bits/subscriptions
  • Whispers (DMs)
  • Bot API for chat commands

Prior Art

  • OpenClaw supports Twitch as one of its 18+ messenger channels

Motivation

Twitch integration enables:

  • AI-powered chat moderation
  • Interactive livestream agents
  • Automated responses to commands
  • Community engagement automation
  • Integration with streaming tools

Proposed Design

  1. Configuration (config.toml):

    [[messengers]]
    name = "twitch"
    type = "twitch"
    enabled = true
    username = "rustyclaw_bot"
    oauth_token = "$TWITCH_OAUTH_TOKEN"  # oauth:abcd1234...
    channels = ["#streamer1", "#streamer2"]
    command_prefix = "!"
  2. Core Functionality:

    • Connect via IRC protocol (irc.chat.twitch.tv:6697)
    • Send messages to channels
    • Receive chat messages and commands
    • Handle emotes and badges
    • Whisper (DM) support
    • Rate limiting compliance (20 messages/30s for verified bots)
  3. Implementation (src/messengers/twitch.rs):

    use twitch_irc::{ClientConfig, SecureTCPTransport, TwitchIRCClient, login::StaticLoginCredentials};
    
    pub struct TwitchMessenger {
        client: TwitchIRCClient<SecureTCPTransport, StaticLoginCredentials>,
        channels: Vec<String>,
    }
    
    impl TwitchMessenger {
        pub async fn new(username: String, oauth_token: String, channels: Vec<String>) -> Result<Self> {
            let config = ClientConfig::new_simple(
                StaticLoginCredentials::new(username.clone(), Some(oauth_token))
            );
            let (mut incoming_messages, client) = 
                TwitchIRCClient::<SecureTCPTransport, StaticLoginCredentials>::new(config);
    
            // Join channels
            for channel in &channels {
                client.join(channel.clone());
            }
    
            Ok(Self { client, channels })
        }
    
        pub async fn send_message(&self, channel: &str, message: &str) -> Result<()> {
            self.client.say(channel.to_string(), message.to_string()).await?;
            Ok(())
        }
    
        pub async fn send_whisper(&self, username: &str, message: &str) -> Result<()> {
            self.client.whisper(username.to_string(), message.to_string()).await?;
            Ok(())
        }
    }

Dependencies

[dependencies]
twitch-irc = "5.0"  # Official Twitch IRC client

API Features

Feature Support
Chat messages ✅ IRC protocol
Whispers (DMs) ✅ IRC /w command
Emotes ✅ Parse from message tags
Badges (mod, sub, etc.) ✅ Parse from message tags
Bits/Cheers ✅ Parse from message tags
Raids/Hosts ✅ IRC USERNOTICE

Acceptance Criteria

  • Twitch configuration with OAuth token
  • Join/leave channels dynamically
  • Send chat messages with rate limiting
  • Receive chat messages with emotes/badges
  • Whisper (DM) support
  • Handle commands with configurable prefix
  • Respect Twitch rate limits (20 msg/30s)
  • Documentation in docs/MESSENGER_TWITCH.md

Security Considerations

  • OAuth token stored in encrypted secrets vault
  • Rate limit compliance to avoid bans
  • Moderation log for inappropriate content
  • Channel permissions and mod status awareness

Related Issues

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions