public BotMessage GetResponse(SlackMessage context) { if (GetResponseFunctions.Count == 0) { throw new InvalidOperationException("Attempted to get a response for \"" + context.Message.Text + "\", but no valid responses have been registered."); } return GetResponseFunctions[new Random().Next(GetResponseFunctions.Count - 1)](context); }
public void GivenASlackMessageWhenThereIsNotAYouTubeLinkThenReturnFalse(string text) { var slackMessage = new SlackMessage {Text = text}; var isYouTubeLink = slackMessage.IsYouTubeLink(); Assert.AreEqual(false, isYouTubeLink); }
public bool CanRespond(SlackMessage context) { if (this.Scorebook == null || this.TeamID != context.TeamID) { // start up scorebook for this team this.TeamID = context.TeamID; this.Scorebook = new Scorebook(TeamID); } // put the scorebook in context in case someone wants to see the scoreboard context.Set<Scorebook>(this.Scorebook); return !context.Message.User.IsSlackbot && Regex.IsMatch(context.Message.Text, SCORE_REGEX); }
protected virtual BotMessage GetExceptionResponse(Exception exception, SlackMessage message) { this.supportApi.CreateSupportTicketOnTrello(new SupportTicketModel() { Message = exception.ToString(), Subject = "Exception in Bot Runner", Status = (int) Status.Open, Type = (int) SupportType.Bug }); reactionApi.AddReaction(ConfigurationManager.AppSettings["BotKey"], "exclamation", message.GetChannelId(), message.GetTimeStamp()); return new BotMessage { Text = "" }; }
public BotMessage GetResponse(SlackMessage context) { Version version = Assembly.GetExecutingAssembly().GetName().Version; string message = @"I'm " + context.BotUserName + " v." + version.Major.ToString() + "." + version.Minor.ToString() + "." + version.Build.ToString() + "! Here's what all's been goin' on with me lately.```" + "- Those nerdy bots down at my local game store have suckered me into learnin' how to play Dungeons and Draggins! Ask me about my character!\n" + "- My internet legacy is growin', y'all! My wiki at https://github.com/jammerware/margiebot/wiki is real polished now, and you can add me to your next bot project from NuGet! Just Install-Package MargieBot. \n" + "```"; return new BotMessage() { Text = message }; }
private BotMessage FineRecipients(List<string> userIds, UserModel issuer, string reason, SlackMessage message) { foreach(var slackId in userIds) { var userModel = this.userApi.GetUserBySlackId(slackId); IssueFineResult result = this.fineApi.IssueFine(issuer.Id, userModel.Id, reason); if (result.HasErrors) { return this.GetErrorResponse(result, message); } } reactionApi.AddReaction(ConfigurationManager.AppSettings["BotKey"], "ok_hand", message.GetChannelId(), message.GetTimeStamp()); return new BotMessage{ Text = ""}; }
public BotMessage GetResponse(SlackMessage context) { Match match = Regex.Match(context.Message.Text, WIKI_MULTIWORD_REGEX); string searchTerm = string.Empty; if (match.Success) { searchTerm = match.Groups["term"].Value; } else { match = Regex.Match(context.Message.Text, WIKI_SINGLEWORD_REGEX); searchTerm = match.Groups["term"].Value; } string requestUrl = string.Format("http://en.wikipedia.org/w/api.php?action=query&list=search&format=json&prop=extracts&exintro=&explaintext=&srsearch={0}&utf8=&continue=", WebUtility.UrlEncode(searchTerm.Trim())); string response = new NoobWebClient().GetResponse(requestUrl, RequestMethod.Get).GetAwaiter().GetResult(); JObject responseData = JObject.Parse(response); if (responseData["query"] != null && responseData["query"]["searchinfo"] != null) { int totalHits = responseData["query"]["searchinfo"]["totalhits"].Value<int>(); if (totalHits > 0) { string articleTitle = responseData["query"]["search"][0]["title"].Value<string>(); string articleRequestUrl = "https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=" + WebUtility.UrlEncode(articleTitle); string articleResponse = new NoobWebClient().GetResponse(articleRequestUrl, RequestMethod.Get).GetAwaiter().GetResult(); JObject articleData = JObject.Parse(articleResponse); if (articleData["query"]["pages"]["-1"] == null) { string summary = articleData["query"]["pages"].First.First["extract"].Value<string>(); if (summary.IndexOf('\n') > 0) { summary = summary.Substring(0, summary.IndexOf('\n')); } return new BotMessage() { Text = "Awwww yeah. I know all about that. Check it, y'all!: " + string.Format("http://en.wikipedia.org/wiki/{0}", articleTitle.Replace(" ", "_")) + " \n> " + summary }; } } } return new BotMessage() { Text = "I never heard of that, which isn't all that surprisin'. What IS surprisin' is that neither has Wikipedia. Have you been hangin' out behind the barn again with SkeeterBot?" }; }
public BotMessage GetResponse(SlackMessage context) { IReadOnlyDictionary<string, int> scores = context.Get<Scorebook>().GetScores(); if (scores.Count > 0) { StringBuilder builder = new StringBuilder(context.Get<Phrasebook>().GetScoreboardHype()); builder.Append("```"); // add the scores to a list for sorting. while we do, figure out who has the longest name for the pseudo table formatting List<KeyValuePair<string, int>> sortedScores = new List<KeyValuePair<string, int>>(); string longestName = string.Empty; foreach (string key in scores.Keys) { KeyValuePair<string, int> newScore = new KeyValuePair<string, int>(context.UserNameCache[key], scores[key]); if(newScore.Key.Length > longestName.Length) { longestName = newScore.Key; } sortedScores.Add(newScore); } sortedScores.Sort((x, y) => { return y.Value.CompareTo(x.Value); }); foreach(KeyValuePair<string, int> userScore in sortedScores) { StringBuilder nameString = new StringBuilder(userScore.Key); while(nameString.Length < longestName.Length) { nameString.Append(" "); } builder.Append(nameString.ToString() + " | " + userScore.Value.ToString() + "\n"); } builder.Append("```"); return new BotMessage() { Text = builder.ToString() }; } else { return new BotMessage() { Text = "Not a one-of-ya has scored yet. Come on, sleepyheads!" }; } }
public BotMessage GetResponse(SlackMessage context) { string data = string.Empty; if (LastDataGrab != null && LastDataGrab.Value > DateTime.Now.AddMinutes(-10)) { data = LastData; } else { NoobWebClient client = new NoobWebClient(); data = client.GetResponse("http://api.wunderground.com/api/" + WundergroundAPIKey + "/conditions/q/TN/Nashville.json", RequestMethod.Get).GetAwaiter().GetResult(); LastData = data; LastDataGrab = DateTime.Now; } JObject jData = JObject.Parse(data); if (jData["current_observation"] != null) { string tempString = jData["current_observation"]["temp_f"].Value<string>(); double temp = double.Parse(tempString); return new BotMessage() { Text = "It's about " + Math.Round(temp).ToString() + "° out, and it's " + jData["current_observation"]["weather"].Value<string>().ToLower() + ". " + context.Get<Phrasebook>().GetWeatherAnalysis(temp) + "\n\nIf you wanna see more. head over to " + jData["current_observation"]["forecast_url"].Value<string>() + " - my girlfriend DonnaBot works over there!" }; } else { return new BotMessage() { Text = "Aww, nuts. My weatherbot gal-pal ain't around. Try 'gin later - she's prolly just fixin' her makeup." }; } }
public bool CanRespond(SlackMessage context) { return (context.Message.ChatHub.Type == SlackChatHubType.DM || context.Message.MentionsBot) && (Regex.IsMatch(context.Message.Text, WIKI_MULTIWORD_REGEX) || Regex.IsMatch(context.Message.Text, WIKI_SINGLEWORD_REGEX)); }
public bool CanRespond(SlackMessage context) { return (context.Message.MentionsBot || context.Message.ChatHub.Type == SlackChatHubType.DM) && Regex.IsMatch(context.Message.Text, @"\bscore\b", RegexOptions.IgnoreCase); }
static void _bot_MessageReceived(string json) { //Copied from MargieBot source and modified to allow all messages var jObject = JObject.Parse(json); if (jObject[Keys.Slack.MessageJson.Type].Value<string>() != "message") return; var channelID = jObject[Keys.Slack.MessageJson.Channel].Value<string>(); SlackChatHub hub; if (_bot.ConnectedHubs.ContainsKey(channelID)) { hub = _bot.ConnectedHubs[channelID]; } else { hub = SlackChatHub.FromID(channelID); var hubs = new List<SlackChatHub>(); hubs.AddRange(_bot.ConnectedHubs.Values); hubs.Add(hub); } var messageText = (jObject[Keys.Slack.MessageJson.Text] != null ? jObject[Keys.Slack.MessageJson.Text].Value<string>() : null); var message = new SlackMessage { ChatHub = hub, RawData = json, Text = messageText, User = (jObject[Keys.Slack.MessageJson.User] != null ? new SlackUser { ID = jObject[Keys.Slack.MessageJson.User].Value<string>() } : null) }; var context = new ResponseContext { BotHasResponded = false, BotUserID = _bot.UserID, BotUserName = _bot.UserName, Message = message, TeamID = _bot.TeamID, UserNameCache = new ReadOnlyDictionary<string, string>(_userNameCache) }; if (_bot.ResponseContext != null) { foreach (var key in _bot.ResponseContext.Keys) { context.Set(key, _bot.ResponseContext[key]); } } foreach (var handler in _messageHandlers) { handler.Execute(context); } }
public bool CanRespond(SlackMessage context) { return (context.Message.MentionsBot || context.Message.ChatHub.Type == SlackChatHubType.DM) && Regex.IsMatch(context.Message.Text, DEFINE_REGEX); }
protected virtual BotMessage GetErrorResponse(ValidationResult result, SlackMessage message) { reactionApi.AddReaction(ConfigurationManager.AppSettings["BotKey"], "raised_hand", message.GetChannelId(), message.GetTimeStamp()); chatApi.PostMessage(ConfigurationManager.AppSettings["BotKey"], message.User.ID, result.FullTrace); return new BotMessage { Text = "" }; }
public BotMessage GetResponse(SlackMessage context) { // perform scoring List<ScoringResult> scoringResults = new List<ScoringResult>(); // bet you anything there's a better way to do this Match match = Regex.Match(context.Message.Text, SCORE_REGEX); for (int i = 0; i < match.Groups["formattedUserID"].Captures.Count; i++) { scoringResults.Add(new ScoringResult() { FormattedUserID = match.Groups["formattedUserID"].Captures[i].Value, IsNewScorer = !this.Scorebook.HasUserScored(match.Groups["userID"].Captures[i].Value), IsValidScorer = (match.Groups["userID"].Captures[i].Value != context.Message.User.ID), UserID = match.Groups["userID"].Captures[i].Value }); } IList<string> newScorers = scoringResults.Where(r => r.IsNewScorer).Select(r => r.UserID).ToList(); IList<string> scoringUsers = scoringResults.Where(r => r.IsValidScorer).Select(r => r.UserID).ToList(); IList<string> allUsers = scoringResults.Select(r => r.UserID).ToList(); // score the users and shove the scorebook into the context for use by the ScoreboardRequestResponder Scorebook.ScoreUsers(scoringUsers, 1); Phrasebook phrasebook = context.Get<Phrasebook>(); StringBuilder responseBuilder = new StringBuilder(); if (allUsers.Contains(context.Message.User.ID)) { responseBuilder.Append(string.Format("Bless your heart, {0}. You can't score yourself - what kinda game would that be?! Y'all, {0} is cute, but I think he/she might be dumb as a box o' rocks.\n\n", context.Message.User.FormattedUserID)); } if(scoringUsers.Count() > 0) { if(responseBuilder.Length > 0) { responseBuilder.Append("Anyway... "); } if(scoringUsers.Count() == 1) { if(scoringUsers[0] == context.BotUserID) { int margieScore = Scorebook.GetUserScore(context.BotUserID); responseBuilder.Append(string.Format("Awwww, aren't you a sweetie! *[blushes]* If you insist. Now I have {0} point{1}.\n\n", margieScore, margieScore == 1 ? string.Empty : "s")); } else if(newScorers.Contains(scoringUsers[0])) { responseBuilder.Append(string.Format("A new challenger appears, y'all! {0} is on the board with a point. {1}", scoringResults.Where(r => r.UserID == scoringUsers[0]).First().FormattedUserID, phrasebook.GetAffirmation())); } else { ScoringResult scoredUser = scoringResults.Where(r => r.UserID == scoringUsers[0]).First(); responseBuilder.Append( string.Format( "{0} {1} just scored a point. {2} {1}, your score is now {3}.", phrasebook.GetExclamation(), scoredUser.FormattedUserID, phrasebook.GetAffirmation(), Scorebook.GetUserScore(scoredUser.UserID) ) ); } } else { responseBuilder.Append("There's points all over this joint, y'all. "); IList<ScoringResult> scoringUserResults = scoringResults.Where(r => r.IsValidScorer).ToList(); if (scoringUserResults.Count == 2) { responseBuilder.Append( string.Format( "{1} and {2} each just scored a point. {3}", phrasebook.GetExclamation(), scoringUserResults[0].FormattedUserID, scoringUserResults[1].FormattedUserID, phrasebook.GetAffirmation() ) ); } else { for (int i = 0; i < scoringUserResults.Count; i++) { responseBuilder.Append(scoringUserResults[i].FormattedUserID); if (i < scoringResults.Count - 2) { responseBuilder.Append(", "); } else if(i == scoringResults.Count - 2) { responseBuilder.Append(", and "); } } responseBuilder.Append(" each just scored a point. " + phrasebook.GetExclamation()); } } } return new BotMessage() { Text = responseBuilder.ToString().Trim() }; }
private PaymentImageModel GetImage(SlackMessage message) { var rawMessageModel = new JsonSerializer<SlackRawMessageModel>().DeserializeFromString(message.RawData); if(rawMessageModel.file == null || string.IsNullOrEmpty(rawMessageModel.file.url)) { return null; } byte[] data; using (WebClient client = new WebClient()) { data = client.DownloadData(rawMessageModel.file.url); } return new PaymentImageModel { FileName = rawMessageModel.file.name, ImageBytes = data, MimeType = rawMessageModel.file.mimetype }; }
private async Task ListenTo(string json) { JObject jObject = JObject.Parse(json); if (jObject["type"].Value<string>() == "message") { string channelID = jObject["channel"].Value<string>(); SlackChatHub hub = null; if (ConnectedHubs.ContainsKey(channelID)) { hub = ConnectedHubs[channelID]; } else { hub = SlackChatHub.FromID(channelID); Dictionary<string, SlackChatHub> hubs = new Dictionary<string, SlackChatHub>(ConnectedHubs.ToDictionary(kvp => kvp.Key, kvp => kvp.Value)); hubs.Add(hub.ID, hub); ConnectedHubs = hubs; } string messageText = (jObject["text"] != null ? jObject["text"].Value<string>() : null); // check to see if bot has been mentioned SlackMessage message = new SlackMessage() { ChatHub = hub, MentionsBot = (messageText != null ? Regex.IsMatch(messageText, BotNameRegex, RegexOptions.IgnoreCase) : false), RawData = json, // some messages may not have text or a user (like unfurled data from URLs) Text = messageText, User = (jObject["user"] != null ? new SlackUser() { ID = jObject["user"].Value<string>() } : null) }; ResponseContext context = new ResponseContext() { BotHasResponded = false, BotUserID = UserID, BotUserName = UserName, Message = message, TeamID = this.TeamID, UserNameCache = new ReadOnlyDictionary<string, string>(this.UserNameCache) }; // if the end dev has added any static entries to the ResponseContext collection of Bot, add them to the context being passed to the responders. if (ResponseContext != null) { foreach (string key in ResponseContext.Keys) { context.Set(key, ResponseContext[key]); } } // margie can never respond to herself and requires that the message have text and be from an actual person if (message.User != null && message.User.ID != UserID && message.Text != null) { foreach (IResponder responder in Responders) { if (responder.CanRespond(context)) { await Say(responder.GetResponse(context), context); context.BotHasResponded = true; } } } } RaiseMessageReceived(json); }
public bool CanRespond(SlackMessage context) { return CanRespondFunction(context); }
public BotMessage GetResponse(SlackMessage context) { string term = WebUtility.UrlEncode(Regex.Match(context.Message.Text, DEFINE_REGEX).Groups["term"].Value); NoobWebClient client = new NoobWebClient(); string definitionData = client.GetResponse( string.Format( "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/{0}?key={1}", term, ApiKey ), RequestMethod.Get ).GetAwaiter().GetResult(); XElement root = XElement.Parse(definitionData); if (root.Descendants("suggestion").FirstOrDefault() != null) { return new BotMessage() { Text = "You know what? I don't even know what that is, and neither does my buddy WebsterBot. And he's super smart, y'all. He wanted to know if maybe you meant *" + root.Descendants("suggestion").First().Value + "*?" }; } else if (root.Descendants("ew").FirstOrDefault() == null) { return new BotMessage() { Text = "Are y'all funnin' with me again? That can't be a real thing, can it?" }; } else { string word = root.Descendants("ew").First().Value; string partOfSpeech = root.Descendants("fl").First().Value; string definition = root.Descendants("dt").First().Value; string etymology = null; string audioFile = null; if (root.Descendants("et").FirstOrDefault() != null) { etymology = root.Descendants("et").First().Value; etymology = Regex.Replace(etymology, "</?it>", "_"); } // compute the sound url thing if (root.Descendants("sound") != null) { audioFile = root.Descendants("wav").First().Value; // do a bunch of dumb stuff to find the audio file URL because this API is wacky // http://www.dictionaryapi.com/info/faq-audio-image.htm#collegiate if (audioFile.StartsWith("bix")) { audioFile = "bix/" + audioFile; } else if (audioFile.StartsWith("gg")) { audioFile = "gg/" + audioFile; } else if (audioFile.StartsWith("number")) { audioFile = "number/" + audioFile; } else { audioFile = audioFile.Substring(0, 1) + "/" + audioFile; } audioFile = "http://media.merriam-webster.com/soundc11/" + audioFile; } string[] defSplits = definition.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (defSplits.Length > 1) { StringBuilder defBuilder = new StringBuilder(); foreach (string def in defSplits) { defBuilder.Append("• " + def + "\n"); } definition = defBuilder.ToString(); } else { definition = definition.Replace(":", string.Empty); } return new BotMessage() { Attachments = new List<SlackAttachment>() { new SlackAttachment() { ColorHex = "#AD91C2", Fallback = "Define " + term, Fields = new List<SlackAttachmentField>() { new SlackAttachmentField() { IsShort = true, Title = "Definition", Value = definition }, new SlackAttachmentField() { IsShort = true, Title = "Part of Speech", Value = partOfSpeech }, new SlackAttachmentField() { IsShort = true, Title = "Etymology", Value = (!string.IsNullOrEmpty(etymology) ? etymology : "It's a made up word. They all are.") }, new SlackAttachmentField() { IsShort = true, Title = "How to Say It", Value = audioFile }, }, Title = "Define: " + term, TitleLink = "http://dictionary.reference.com/browse/" + WebUtility.UrlEncode(term), } }, Text = "Well, I have literally _no_ idea what that means, so I called my friend WebsterBot." }; } }
public bool CanRespond(SlackMessage context) { return (context.Message.MentionsBot || context.Message.ChatHub.Type == SlackChatHubType.DM) && Regex.IsMatch(context.Message.Text, @"\bweather\b"); }