using TwitchLib.Api; using TwitchLib.Client; using TwitchLib.Client.Events; using TwitchLib.Client.Models; using TwitchLib.Communication.Clients; namespace TTSMe; public class Bot { public const bool VERBOSE = false; private TwitchClient client { get; } private TwitchAPI apiClient { get; } private string _channel { get; } private static Voices voices => Voices.Instance(); private static bool SEND_WHISPERS => false; public Bot(string clientId, ConnectionCredentials credentials, bool verbose = false) { _channel = credentials.TwitchUsername; client = new TwitchClient(new WebSocketClient { Options = { MessagesAllowedInPeriod = 750, ThrottlingPeriod = TimeSpan.FromSeconds(90) } }); apiClient = new TwitchAPI { Settings = { ClientId = clientId, AccessToken = credentials.TwitchOAuth } }; client.Initialize(credentials, credentials.TwitchUsername); if (VERBOSE) client.OnLog += Log; client.OnMessageReceived += OnTtsMeMessageReceived; AppDomain.CurrentDomain.ProcessExit += OnProcessExit!; Connect(); } private void SendMessage(string message, string? username = null) { client.SendMessage(_channel, message); if (!SEND_WHISPERS || username is null) return; // TODO: Change this when I figure out how whispers work... client.SendWhisper(username, message); apiClient.Helix.Whispers.SendWhisperAsync(_channel, username, message, true); } private void Connect() { while (client is ({IsInitialized: false})) { Console.Error.WriteLine("client is not yet initialized."); Thread.Sleep(250); } Console.WriteLine($"Connecting to channel '{_channel}'..."); client.Connect(); try { Console.WriteLine($"Connected to channel '{_channel}'."); } catch (Exception e) { Console.WriteLine($"Failed to connect to channel '{_channel}': {e.Message}"); Disconnect(); } } private void Disconnect() { client.Disconnect(); Console.WriteLine($"Disconnected from channel '{_channel}'."); } private void OnProcessExit(object? _, EventArgs e) => Disconnect(); private static void Log(object? _, OnLogArgs e) => Console.WriteLine($"{e.DateTime:yyyy-MM-ddTHH:mm:ssZ} - {e.Data}"); private void OnTtsMeMessageReceived(object? _, OnMessageReceivedArgs e) { ChatMessage chatMessage = e.ChatMessage; string username = chatMessage.Username; string message = chatMessage.GetMessageText(); if (!chatMessage.HasStoredVoice()) voices.SetRandomVoice(username); string? ttsMeCommandResponse = TtsMeCommand.ProcessVoiceChange(chatMessage); if (ttsMeCommandResponse is not null) SendMessage(ttsMeCommandResponse); if (message.StartsWith("!ttsme")) return; // Don't process the command message Console.WriteLine($"{username} [{voices.GetVoice(username)!}]: !ttsme {message}"); Voices.ProcessVoiceMessage(chatMessage).Wait(); } }