Example #1
0
        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);
        }
Example #3
0
        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 = "" };
        }
Example #5
0
        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 = ""};
        }
Example #7
0
        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." };
            }
        }
Example #10
0
 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);
 }
Example #12
0
        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);
            }
        }
Example #13
0
 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 = "" };
 }
Example #15
0
        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
                   };
        }
Example #17
0
        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);
        }
Example #18
0
 public bool CanRespond(SlackMessage context)
 {
     return CanRespondFunction(context);
 }
Example #19
0
        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");
 }