static void Main(string[] args) { //Survey survey = new Survey(); // Initialize and connect to Twitch chat IrcClient irc = new IrcClient("irc.chat.twitch.tv", 6667, _botName, _twitchOAuth, _broadcasterName); // Ping to the server to make sure this bot stays connected to the chat // Server will respond back to this bot with a PONG (without quotes): // Example: ":tmi.twitch.tv PONG tmi.twitch.tv :irc.twitch.tv" PingSender ping = new PingSender(irc); ping.Start(); // Listen to the chat until program exits while (true) { if (survey.IsActive && survey.End < DateTime.Now) { irc.SendPublicChatMessage(survey.ReportResults()); } // Read any message from the chat room string message = irc.ReadMessage(); Console.WriteLine(message); // Print raw irc messages if (message.Contains("PRIVMSG")) { // Messages from the users will look something like this (without quotes): // Format: ":[user]![user]@[user].tmi.twitch.tv PRIVMSG #[channel] :[message]" // Modify message to only retrieve user and message int intIndexParseSign = message.IndexOf('!'); string userName = message.Substring(1, intIndexParseSign - 1); // parse username from specific section (without quotes) // Format: ":[user]!" // Get user's message intIndexParseSign = message.IndexOf(" :"); message = message.Substring(intIndexParseSign + 2).Trim(); Console.WriteLine(message); // Print parsed irc message (debugging only) // Broadcaster commands if (userName.Equals(_broadcasterName)) { if (message.Equals("!exitbot")) { irc.SendPublicChatMessage("Bye! Have a beautiful time!"); Environment.Exit(0); // Stop the program } if (message.Contains("!umfrage ") || message.Contains("!Umfrage ")) { if (message.Contains("--s")) { irc.SendPublicChatMessage(survey.ReportResults()); } else { surveyEndOffset = 2; if (message.Contains("--t ")) { surveyEndOffset = Int32.Parse(message.Substring(message.LastIndexOf(' ') + 1)); } survey = new SurveyCommand() { Title = message.Substring(message.IndexOf(' ') + 1), AnsweredMaybe = 0, AnsweredNo = 0, AnsweredYes = 0, Start = DateTime.Now, End = DateTime.Now.AddMinutes(surveyEndOffset), IsActive = true, Participants = new List <string>() }; irc.SendPublicChatMessage(survey.GetSurveyStartedMessage()); } } } else { // General commands anyone can use if (survey.IsActive) { if (!survey.Participants.Contains(userName)) { if (message.ToLower().Equals("+")) { survey.AnsweredYes += 1; survey.Participants.Add(userName); } if (message.ToLower().Equals("-")) { survey.AnsweredNo += 1; survey.Participants.Add(userName); } if (message.ToLower().Equals("+-") || message.ToLower().Equals("+/-")) { survey.AnsweredMaybe += 1; survey.Participants.Add(userName); } } else { irc.SendPublicChatMessage($"/w {userName} Du kannst nur ein mal pro Umfrage abstimmen. Die aktuelle Umfrage läuft noch bis {survey.End.ToString("hh:mm:ss")}"); } } if (message.Equals("!hello")) { irc.SendPublicChatMessage("Hello World!"); } } } } }
static void Main(string[] args) { // Twitch variables string twitchOAuth = ""; string twitchClientID = ""; string twitchAccessToken = ""; // used for channel editing // Twitter variables bool hasTwitterInfo = true; string twitterConsumerKey = ""; string twitterConsumerSecret = ""; string twitterAccessToken = ""; string twitterAccessSecret = ""; bool isSongRequestAvail = false; // check song request status (disabled by default) /* Connect to database or exit program on connection error */ try { // Grab connection string (production or test) if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.conn)) { _connStr = Properties.Settings.Default.conn; // production database only Console.WriteLine("Connecting to database..."); } else if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.connTest)) { _connStr = Properties.Settings.Default.connTest; // test database only Console.WriteLine("<<<< WARNING: Connecting to local database (testing only) >>>>"); } else { Console.WriteLine("Internal Error: Connection string to database not provided!"); Console.WriteLine("Shutting down now..."); Thread.Sleep(3500); Environment.Exit(1); } // Check if server is connected if (!IsServerConnected(_connStr)) { // clear sensitive data _connStr = null; Console.WriteLine("Datebase connection failed. Please try again"); Console.WriteLine(); Console.WriteLine("-- Common technical issues: --"); Console.WriteLine("1: Check if firewall settings has your client IP address."); Console.WriteLine("2: Double check the connection string under 'Properties' inside 'Settings'"); Console.WriteLine(); Console.WriteLine("Shutting down now..."); Thread.Sleep(5000); Environment.Exit(1); } } catch (Exception ex) { Console.WriteLine("Error Message: " + ex.Message); Console.WriteLine("Local troubleshooting needed by author of this bot"); Console.WriteLine(); Console.WriteLine("Shutting down now..."); Thread.Sleep(3000); Environment.Exit(1); } /* Try to grab the info needed for the bot to connect to the channel */ try { Console.WriteLine("Database connection successful!"); Console.WriteLine(); Console.WriteLine("Checking if user settings has all necessary info..."); // Grab settings _strBotName = Properties.Settings.Default.botName; _strBroadcasterName = Properties.Settings.Default.broadcaster; twitchOAuth = Properties.Settings.Default.twitchOAuth; twitchClientID = Properties.Settings.Default.twitchClientID; twitchAccessToken = Properties.Settings.Default.twitchAccessToken; twitterConsumerKey = Properties.Settings.Default.twitterConsumerKey; twitterConsumerSecret = Properties.Settings.Default.twitterConsumerSecret; twitterAccessToken = Properties.Settings.Default.twitterAccessToken; twitterAccessSecret = Properties.Settings.Default.twitterAccessSecret; _strDiscordLink = Properties.Settings.Default.discordLink; _strCurrencyType = Properties.Settings.Default.currencyType; _isAutoDisplaySong = Properties.Settings.Default.enableDisplaySong; _isAutoPublishTweet = Properties.Settings.Default.enableTweet; _intStreamLatency = Properties.Settings.Default.streamLatency; // Check if program has client ID (developer needs to provide this inside the settings) if (string.IsNullOrWhiteSpace(twitchClientID)) { Console.WriteLine("Error: MISSING Twitch Client ID"); Console.WriteLine("Please contact the author of this bot to re-release this application with the client ID"); Console.WriteLine(); Console.WriteLine("Shutting down now..."); Thread.Sleep(3000); Environment.Exit(1); } // Check if user has the minimum info in order to run the bot // Tell user to input essential info while (string.IsNullOrWhiteSpace(_strBotName) && string.IsNullOrWhiteSpace(_strBroadcasterName) && string.IsNullOrWhiteSpace(twitchOAuth) && string.IsNullOrWhiteSpace(twitchAccessToken)) { Console.WriteLine("You are missing essential info"); if (string.IsNullOrWhiteSpace(_strBotName)) { Console.WriteLine("Enter your bot's username: "******"Enter your Twitch username: "******"Enter your Twitch OAuth: "); Properties.Settings.Default.twitchOAuth = Console.ReadLine(); twitchOAuth = Properties.Settings.Default.twitchOAuth; } if (string.IsNullOrWhiteSpace(twitchAccessToken)) { Console.WriteLine("Enter your Twitch Access Token: "); Properties.Settings.Default.twitchAccessToken = Console.ReadLine(); twitchAccessToken = Properties.Settings.Default.twitchAccessToken; } Properties.Settings.Default.Save(); Console.WriteLine("Saved Settings!"); Console.WriteLine(); } // Option to edit settings before running it Console.WriteLine("Do you want to edit your essential bot settings (y/n or yes/no)?"); string strResponse = Console.ReadLine().ToLower(); // Check if user inserted a valid option while (!(strResponse.Equals("y") || strResponse.Equals("yes") || strResponse.Equals("n") || strResponse.Equals("no"))) { Console.WriteLine("Please insert a valid option (y/n or yes/no)"); strResponse = Console.ReadLine().ToLower(); } // Change some settings if (strResponse.Equals("y") || strResponse.Equals("yes")) { int intOption = 0; Console.WriteLine(); /* Loop until user is finished making changes */ do { // Display bot settings Console.WriteLine("---> Here are your essential bot settings <---"); Console.WriteLine("1. Bot's username: "******"2. Your main Twitch username: "******"3. Twitch OAuth: " + Properties.Settings.Default.twitchOAuth); Console.WriteLine("4. Twitch Access Token: " + Properties.Settings.Default.twitchAccessToken); Console.WriteLine(); Console.WriteLine("From the options 1-4 (or 0 to exit editing), which option do you want to edit?"); // Edit an option if (int.TryParse(Console.ReadLine(), out intOption) && intOption < 5 && intOption >= 0) { Console.WriteLine(); switch (intOption) { case 1: Console.WriteLine("Enter your bot's new username: "******"Enter your new Twitch username: "******"Enter your new Twitch OAuth (include 'oauth:' along the 30 character phrase): "); Properties.Settings.Default.twitchOAuth = Console.ReadLine(); twitchOAuth = Properties.Settings.Default.twitchOAuth; break; case 4: Console.WriteLine("Enter your new Twitch access token: "); Properties.Settings.Default.twitchAccessToken = Console.ReadLine(); twitchAccessToken = Properties.Settings.Default.twitchAccessToken; break; } Properties.Settings.Default.Save(); Console.WriteLine("Saved Settings!"); Console.WriteLine(); } else { Console.WriteLine("Please write a valid option between 1-4 (or 0 to exit editing)"); Console.WriteLine(); } } while (intOption != 0); Console.WriteLine("Finished with editing settings"); } else // No need to change settings Console.WriteLine("Essential settings confirmed!"); Console.WriteLine(); // Extra settings menu Console.WriteLine("Do you want to edit your extra bot settings [twitter/discord/currency] (y/n or yes/no)?"); strResponse = Console.ReadLine().ToLower(); // Check if user inserted a valid option while (!(strResponse.Equals("y") || strResponse.Equals("yes") || strResponse.Equals("n") || strResponse.Equals("no"))) { Console.WriteLine("Please insert a valid option (y/n or yes/no)"); strResponse = Console.ReadLine().ToLower(); } // Change some settings if (strResponse.Equals("y") || strResponse.Equals("yes")) { int intOption = 0; Console.WriteLine(); /* Loop until user is finished making changes */ do { // Display bot settings Console.WriteLine("---> Here are your extra bot settings <---"); Console.WriteLine("1. Twitter consumer key: " + Properties.Settings.Default.twitterConsumerKey); Console.WriteLine("2. Twitter consumer secret: " + Properties.Settings.Default.twitterConsumerSecret); Console.WriteLine("3. Twitter access token: " + Properties.Settings.Default.twitterAccessToken); Console.WriteLine("4. Twitter access secret: " + Properties.Settings.Default.twitterAccessSecret); Console.WriteLine("5. Discord link: " + Properties.Settings.Default.discordLink); Console.WriteLine("6. Currency type: " + Properties.Settings.Default.currencyType); Console.WriteLine("7. Enable Auto Tweets: " + Properties.Settings.Default.enableTweet); Console.WriteLine("8. Enable Auto Display Songs: " + Properties.Settings.Default.enableDisplaySong); Console.WriteLine("9. Stream Latency: " + Properties.Settings.Default.streamLatency); Console.WriteLine(); Console.WriteLine("From the options 1-9 (or 0 to exit editing), which option do you want to edit?"); // Edit an option string strOption = Console.ReadLine(); if (int.TryParse(strOption, out intOption) && intOption < 10 && intOption >= 0) { Console.WriteLine(); switch (intOption) { case 1: Console.WriteLine("Enter your new Twitter consumer key: "); Properties.Settings.Default.twitterConsumerKey = Console.ReadLine(); twitterConsumerKey = Properties.Settings.Default.twitterConsumerKey; break; case 2: Console.WriteLine("Enter your new Twitter consumer secret: "); Properties.Settings.Default.twitterConsumerSecret = Console.ReadLine(); twitterConsumerSecret = Properties.Settings.Default.twitterConsumerSecret; break; case 3: Console.WriteLine("Enter your new Twitter access token: "); Properties.Settings.Default.twitterAccessToken = Console.ReadLine(); twitterAccessToken = Properties.Settings.Default.twitterAccessToken; break; case 4: Console.WriteLine("Enter your new Twitter access secret: "); Properties.Settings.Default.twitterAccessSecret = Console.ReadLine(); twitterAccessSecret = Properties.Settings.Default.twitterAccessSecret; break; case 5: Console.WriteLine("Enter your new Discord link: "); Properties.Settings.Default.discordLink = Console.ReadLine(); _strDiscordLink = Properties.Settings.Default.discordLink; break; case 6: Console.WriteLine("Enter your new currency type: "); Properties.Settings.Default.currencyType = Console.ReadLine(); _strCurrencyType = Properties.Settings.Default.currencyType; break; case 7: Console.WriteLine("Want to enable (true) or disable (false) auto tweets: "); Properties.Settings.Default.enableTweet = Convert.ToBoolean(Console.ReadLine()); _isAutoPublishTweet = Properties.Settings.Default.enableTweet; break; case 8: Console.WriteLine("Want to enable (true) or disable (false) display songs from Spotify: "); Properties.Settings.Default.enableDisplaySong = Convert.ToBoolean(Console.ReadLine()); _isAutoDisplaySong = Properties.Settings.Default.enableDisplaySong; break; case 9: Console.WriteLine("Enter your new stream latency (in seconds): "); Properties.Settings.Default.streamLatency = int.Parse(Console.ReadLine()); _intStreamLatency = Properties.Settings.Default.streamLatency; break; } Properties.Settings.Default.Save(); Console.WriteLine("Saved Settings!"); Console.WriteLine(); } else { Console.WriteLine("Please write a valid option between 1-9 (or 0 to exit editing)"); Console.WriteLine(); } } while (intOption != 0); Console.WriteLine("Finished with editing settings"); } else // No need to change settings Console.WriteLine("Extra settings confirmed!"); Console.WriteLine(); // Get broadcaster ID so the user can only see their data from the db _intBroadcasterID = getBroadcasterID(_strBroadcasterName.ToLower()); // Add broadcaster as new user to database if (_intBroadcasterID == 0) { string query = "INSERT INTO tblBroadcasters (username) VALUES (@username)"; using (SqlConnection conn = new SqlConnection(_connStr)) using (SqlCommand cmd = new SqlCommand(query, conn)) { cmd.Parameters.Add("@username", SqlDbType.VarChar, 30).Value = _strBroadcasterName; conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); } _intBroadcasterID = getBroadcasterID(_strBroadcasterName.ToLower()); } // Try looking for the broadcaster's ID again if (_intBroadcasterID == 0) { Console.WriteLine("Cannot find a broadcaster ID for you. " + "Please contact the author with a detailed description of the issue"); Thread.Sleep(3000); Environment.Exit(1); } /* Connect to local Spotify client */ _spotify = new SpotifyControl(); _spotify.Connect(); Console.WriteLine(); Console.WriteLine("Time to get to work!"); Console.WriteLine(); /* Make sure usernames are set to lowercase for the rest of the application */ _strBotName = _strBotName.ToLower(); _strBroadcasterName = _strBroadcasterName.ToLower(); // Password from www.twitchapps.com/tmi/ // include the "oauth:" portion // Use chat bot's oauth /* main server: irc.twitch.tv, 6667 */ _irc = new IrcClient("irc.twitch.tv", 6667, _strBotName, twitchOAuth, _strBroadcasterName); // Update channel info _intFollowers = TaskJSON.GetChannel().Result.followers; _strBroadcasterGame = TaskJSON.GetChannel().Result.game; /* Make new thread to get messages */ Thread thdIrcClient = new Thread(() => TwitchBotApp.GetChatBox(isSongRequestAvail, twitchAccessToken, hasTwitterInfo)); thdIrcClient.Start(); /* Whisper broadcaster bot settings */ Console.WriteLine("---> Extra Bot Settings <---"); Console.WriteLine("Discord link: " + _strDiscordLink); Console.WriteLine("Currency type: " + _strCurrencyType); Console.WriteLine("Enable Auto Tweets: " + _isAutoPublishTweet); Console.WriteLine("Enable Auto Display Songs: " + _isAutoDisplaySong); Console.WriteLine("Stream latency: " + _intStreamLatency + " second(s)"); Console.WriteLine(); /* Start listening for delayed messages */ DelayMsg delayMsg = new DelayMsg(); delayMsg.Start(); /* Get list of mods */ _mod = new Moderator(); setListMods(); /* Get list of timed out users */ _timeout = new Timeout(); setListTimeouts(); /* Ping to twitch server to prevent auto-disconnect */ PingSender ping = new PingSender(); ping.Start(); /* Remind viewers of bot's existance */ PresenceReminder preRmd = new PresenceReminder(); preRmd.Start(); /* Authenticate to Twitter if possible */ if (hasTwitterInfo) { Auth.ApplicationCredentials = new TwitterCredentials( twitterConsumerKey, twitterConsumerSecret, twitterAccessToken, twitterAccessSecret ); } } catch (Exception ex) { LogError(ex, "Program", "Main(string[])", true); } }