private IEnumerable <ResponseMessage> HandleNBitStack(IncomingMessage incomingMessage) { var genericAnswerKeywords = new List <string>() { "question", "i have a question", "i need help" }; if (genericAnswerKeywords.Contains(incomingMessage.RawText.ToLower())) { yield return(incomingMessage.IndicateTypingOnChannel()); _statsPlugin.IncrementState("Helper:BlindlyHelped"); yield return(incomingMessage.ReplyToChannel( $"Perhaps you should look at https://nbitstack.com/c/btcpayserver and see if there is already an answer for you there, @{incomingMessage.Username}")); } var discourseSearchKeywords = new List <string>() { "how can i", "i need help with" }; if (discourseSearchKeywords.Any(s => incomingMessage.RawText.ToLower().StartsWith(s.ToLower()))) { var discourseUrl = "https://nbitstack.com"; var searchText = incomingMessage.RawText; discourseSearchKeywords.ForEach(s => { searchText = searchText.Replace(s, ""); }); yield return(incomingMessage.IndicateTypingOnChannel()); var message = $"Maybe this can help: {discourseUrl}/search?q={Url.Encode(searchText.Trim())}"; _statsPlugin.IncrementState("RedirectedToDiscourseSearch:Count"); yield return(incomingMessage.ReplyToChannel(message)); } }
private IEnumerable <ResponseMessage> AddPostmortemLinkToIncidentHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); if (!this.incidentManagementPlugin.IncidentCommandUserInputWellFormatted(incomingMessage.TargetedText)) { yield return(incomingMessage.ReplyToChannel($"Please provide postmortem link. Help: {this.postmortemIncidentHelpText}")); } var postmortemLink = TextHelper.GetIncidentText($"{Configuration.Prefix} postmortem", incomingMessage.TargetedText); var incident = this.incidentManagementPlugin.UpdateIncidentWithPostmortem(postmortemLink, incomingMessage.Username, incomingMessage.Channel); if (incident == null) { yield return (incomingMessage .ReplyToChannel("Sorry, no open incident was found attached to this channel. Was the incident already closed?")); } else { yield return(incomingMessage.ReplyToChannel( $"Incident #{incident.FriendlyId} has been updated with a postmortem link. " + $"Once the postmortem and incident are complete, please run {this.closeIncidentHelpText} to close the incident.")); } }
private IEnumerable <ResponseMessage> JiraHandler(IncomingMessage message, IValidHandle matchedHandle) { string searchTerm = message.TargetedText.Substring(matchedHandle.HandleHelpText.Length).Trim(); if (string.IsNullOrEmpty(searchTerm)) { yield return(message.ReplyToChannel($"Please give me something to search, e.g. {matchedHandle} trains")); } else { yield return(message.IndicateTypingOnChannel()); string url = _configReader.GetConfigEntry <string>("jira:url"); string prefix = _configReader.GetConfigEntry <string>("jira:prefix"); string base64Token = _configReader.GetConfigEntry <string>("jira:base64Token"); if (string.IsNullOrEmpty(url) && string.IsNullOrEmpty(prefix) && string.IsNullOrEmpty(base64Token)) { _statsPlugin.IncrementState("Jira:Failed"); yield return(message.ReplyToChannel("Woops, looks like settings for Jira is not configured properly. Please ask the admin to fix this")); } else { string messageToAnswer = GetDataFromJira(message.RawText, url, prefix, base64Token); yield return(message.ReplyToChannel(messageToAnswer)); } } }
private IEnumerable <ResponseMessage> Handler(IncomingMessage message, IValidHandle matchedHandle) { if (!_authorizationPlugin.HasPermission("tflights", message.UserEmail)) { yield return(message.ReplyToChannel("Nope! Ask for access first.")); yield break; } yield return(message.IndicateTypingOnChannel()); var results = _flightFinderClient.Find().GetAwaiter().GetResult(); var attachments = results .OrderBy(x => x.Departure) .Take(15) .Select(x => new Attachment { Text = GetText(x), Color = GetColor(x) }) .ToList(); attachments.Add(new Attachment { Fallback = "Book your flights at https://www.flypgs.com/en", Color = "#000" }.AddAttachmentAction("Book flights", "https://www.flypgs.com/en")); yield return(message.ReplyToChannel("Cheapest upcoming weekend flights from London to Istanbul - Friday evening to Sunday evening:", attachments)); }
private IEnumerable <ResponseMessage> ApplicationDetailHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); if (NewRelicPlugin.ApplicationDetailTargetedCommandMisformed(incomingMessage.TargetedText)) { yield return(incomingMessage.ReplyToChannel($"NewRelic application detail command was not formatted correctly. Help: {this.applicationDetailHelpText}")); yield break; } var applicationName = this.newRelicPlugin.GetApplicationNameFromTargetedText(incomingMessage.TargetedText); var applicationAttachments = this.newRelicPlugin.GetApplicationDetailsFiltered(applicationName); if (!applicationAttachments.Any()) { yield return(incomingMessage.ReplyToChannel( $"No applications were found in NewRelic with the name `{applicationName}`")); } else { foreach (var responseMessage in ChuckAttachmentsAndReplyToChannel( incomingMessage, applicationAttachments, $"There were {applicationAttachments.Count} application(s) found for that name. They are:")) { yield return(responseMessage); } } }
private IEnumerable <ResponseMessage> UnhealthyApplicationsDetailHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); string title; var applicationAttachments = new List <Attachment>(); try { applicationAttachments = this.newRelicPlugin.GetUnhealthyApplicationsDetail(); title = applicationAttachments.Any() ? $"There are {applicationAttachments.Count} unhealthy applications in NewRelic. Those are:" : $"There are no unhealthy applications in NewRelic."; } catch (Exception e) { Console.WriteLine(e); title = "An exception occurred when retrieving an list of the applications from NewRelic."; } foreach (var responseMessage in ChuckAttachmentsAndReplyToChannel(incomingMessage, applicationAttachments, title)) { yield return(responseMessage); } }
private IEnumerable <ResponseMessage> NewIncidentHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); if (!this.incidentManagementPlugin.IncidentCommandUserInputWellFormatted(incomingMessage.TargetedText)) { yield return(incomingMessage.ReplyToChannel($"Please provide incident title. Help: {this.newIncidentHelpText}")); yield break; } var incidentText = TextHelper.GetIncidentText($"{Configuration.Prefix} new", incomingMessage.TargetedText); var incident = this.incidentManagementPlugin.DeclareNewIncident(incidentText, incomingMessage.Username); if (incident == null) { yield return (incomingMessage .ReplyToChannel("Sorry, no warrooms are available so this incident cannot be created.")); } else { yield return(incomingMessage.ReplyToChannel($"Incident #{ incident.FriendlyId } has been declared and bound to #{ incident.ChannelName } channel.")); } }
private IEnumerable <ResponseMessage> ListRecentIncidentHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); var recentIncidentAttachments = this.incidentManagementPlugin.GetRecentIncidents(); yield return(incomingMessage.ReplyToChannel($"There were { recentIncidentAttachments.Count } recent incident(s):", recentIncidentAttachments)); }
private IEnumerable <ResponseMessage> GenericCommandHandler(IncomingMessage incomingMessage, string command) { Exception exception = null; HttpResponseMessage apiResponseMessage = null; yield return(incomingMessage.IndicateTypingOnChannel()); if (this.lboPlugin.CommandMisformed(incomingMessage.TargetedText)) { yield return(incomingMessage.ReplyToChannel($"Command was not formatted correctly. Help: '{GetHelpText(command)}'")); yield break; } var lboRequest = new LoadBalancerRequest(incomingMessage.TargetedText); var appliance = this.lboPlugin.GetAppliance(lboRequest.ApplianceName); if (appliance == null) { yield return(incomingMessage.ReplyToChannel($"No appliance could be found with the name:{lboRequest.ApplianceName}. Help: '{GetHelpText(command)}'")); yield break; } try { apiResponseMessage = this.lboPlugin.MakeApiRequest(appliance, lboRequest); } catch (Exception e) { this.log.Error(e); exception = e; } if (this.lboPlugin.ApiRequestThrewException(apiResponseMessage, exception)) { yield return(incomingMessage.ReplyToChannel($"An exception occured when communicating to applicance '{appliance.Name} ({appliance.ApiUrl}).")); yield break; } var lbResponse = this.lboPlugin.ParseApiResponse(apiResponseMessage); if (lbResponse.Contains("Error")) { yield return(incomingMessage.ReplyToChannel($"An error occured when issuing command against VIP {lboRequest.Vip} for RIP {lboRequest.Rip}. Check the VIP and RIP names are valided for applicance `{appliance.Name}` ({appliance.ApiUrl}).")); yield break; } yield return(incomingMessage.ReplyToChannel($"{lbResponse}")); }
private IEnumerable <ResponseMessage> JokeHandler(IncomingMessage message, IValidHandle matchedHandle) { yield return(message.IndicateTypingOnChannel()); var jokeResponse = new Random().Next(0, 100) < 80 ? GetChuckNorrisJoke() : GetMommaJoke(); _statsPlugin.IncrementState("Jokes:Told"); var jokeString = $"{{ {jokeResponse.SelectToken("$..joke").Parent} }}"; var joke = JsonConvert.DeserializeObject <JokeContainer>(jokeString); yield return(message.ReplyToChannel(joke.Joke)); }
private IEnumerable <ResponseMessage> FlickrHandler(IncomingMessage message, IValidHandle matchedHandle) { string searchTerm = message.TargetedText.Substring(matchedHandle.HandleHelpText.Length).Trim(); if (string.IsNullOrEmpty(searchTerm)) { yield return(message.ReplyToChannel($"Please give me something to search, e.g. {matchedHandle} trains")); } else { yield return(message.IndicateTypingOnChannel()); string apiKey = _configReader.GetConfigEntry <string>("flickr:apiKey"); if (string.IsNullOrEmpty(apiKey)) { _statsPlugin.IncrementState("Flickr:Failed"); yield return(message.ReplyToChannel("Woops, looks like a Flickr API Key has not been entered. Please ask the admin to fix this")); } else { var flickr = new Flickr(apiKey); var options = new PhotoSearchOptions { Tags = searchTerm, PerPage = 50, Page = 1 }; PhotoCollection photos = flickr.PhotosSearch(options); if (photos.Any()) { _statsPlugin.IncrementState("Flickr:Sent"); int i = new Random().Next(0, photos.Count); Photo photo = photos[i]; var attachment = new Attachment { AuthorName = photo.OwnerName, Fallback = photo.Description, ImageUrl = photo.LargeUrl, ThumbUrl = photo.ThumbnailUrl }; yield return(message.ReplyToChannel($"Here is your picture about '{searchTerm}'", attachment)); } else { _statsPlugin.IncrementState("Flickr:Failed"); yield return(message.ReplyToChannel($"Sorry @{message.Username}, I couldn't find anything about {searchTerm}")); } } } }
private IEnumerable <ResponseMessage> PurgeZone(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); if (!CommandWellFormatted(incomingMessage.TargetedText, requiredCommandLength: 4)) { yield return(incomingMessage.ReplyToChannel($"Command was not formatted correctly. Help: {GetPurgeZoneHelpText()}")); yield break; } var zoneName = GetCleanZoneName(GetPositionalElementFromTargetText(incomingMessage.TargetedText, position: 3)); var result = this.cloudflarePlugin.PurgeZone(zoneName); yield return(incomingMessage.ReplyToChannel(result.Message)); }
private IEnumerable <ResponseMessage> ListActiveIncidentHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); var openIncidentAttachments = this.incidentManagementPlugin.GetOpenIncidents(); if (openIncidentAttachments.Any()) { yield return(incomingMessage.ReplyToChannel( $"There are {openIncidentAttachments.Count} incident(s) currently open:", openIncidentAttachments)); } else { yield return(incomingMessage.ReplyToChannel( $"Great news! There's no active incidents at the moment. If you need to declare a new incident, run { this.newIncidentHelpText }.")); } }
private IEnumerable <ResponseMessage> CloseIncidentHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); var incident = this.incidentManagementPlugin.CloseIncident(incomingMessage.Username, incomingMessage.Channel); if (incident == null) { yield return(incomingMessage.ReplyToChannel( $"Sorry, no incident was found attached to this channel that could be closed. Was the incident resolved yet, already closed or missing the postmortem? " + $"If it the incident hasn't been marked as resolved, run {this.resolveIncidentHelpText} first. If the incident is resolved but missing the postmortem, run {this.postmortemIncidentHelpText} along with the postmortem link first.")); } else { yield return(incomingMessage.ReplyToChannel($"Incident #{ incident.FriendlyId } succesfully closed. Please prepare the postmortem on Jive using incident/postmortem id { incident.FriendlyId }.\n" + "Channel will now be marked as available.")); } }
private IEnumerable <ResponseMessage> JokeHandler(IncomingMessage message, string matchedHandle) { yield return(message.IndicateTypingOnChannel()); IRestResponse jokeResponse = new Random().Next(0, 100) < 80 ? GetTambalJoke() : GetMommaJoke(); if (jokeResponse.StatusCode == HttpStatusCode.OK) { _statsPlugin.IncrementState("Jokes:Told"); var joke = JsonConvert.DeserializeObject <JokeContainer>(jokeResponse.Content); yield return(message.ReplyToChannel(joke.Joke)); } else { _statsPlugin.IncrementState("Jokes:Failed"); yield return(message.ReplyToChannel($"Dam, I can't think of one. [{jokeResponse.StatusCode}]")); } }
private IEnumerable <ResponseMessage> ResolveIncidentHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); var incident = this.incidentManagementPlugin.ResolveIncident(incomingMessage.Username, incomingMessage.Channel); if (incident == null) { yield return(incomingMessage.ReplyToChannel( "Sorry, no unresolved incident was found attached to this channel. Was the incident already resolved or closed?")); } else { yield return(incomingMessage.ReplyToChannel( $"Incident #{incident.FriendlyId} succesfully resolved. Please run {this.postmortemIncidentHelpText} followed " + $"by the postmortem link to add the postmortem to this incident, if not already done. " + $"To create a new postmortem using the template, please go here { this.incidentManagementPlugin.PostmortemTemplateLink }.")); } }
private IEnumerable <ResponseMessage> HandleJokes(IncomingMessage incomingMessage) { var bcashKeywords = new List <string>() { "bcash", "bitcoin cash", "tell me a joke" }; if (bcashKeywords.Contains(incomingMessage.RawText.ToLower())) { yield return(incomingMessage.IndicateTypingOnChannel()); _statsPlugin.IncrementState("Jokes:Told"); yield return(incomingMessage.ReplyToChannel(jokes[_r.Next(0, jokes.Count)].Content)); } if (incomingMessage.RawText.ToLower().StartsWith("addjoke:")) { var joke = incomingMessage.RawText.Substring("addjoke:".Length); jokes.Add(new Joke() { Content = joke }); _jsonStoragePlugin.SaveFile("jokes", jokes.ToArray()); yield return(incomingMessage.ReplyDirectlyToUser("joke added!")); } if (incomingMessage.RawText.ToLower().StartsWith("removejoke:")) { var joke = incomingMessage.RawText.Substring("removejoke:".Length); if (jokes.Any(joke1 => joke == joke1.Content)) { var jokeIndex = jokes.FindIndex(joke1 => joke == joke1.Content); jokes.RemoveAt(jokeIndex); _jsonStoragePlugin.SaveFile("jokes", jokes.ToArray()); yield return(incomingMessage.ReplyDirectlyToUser("joke removed!")); } } }
private IEnumerable <ResponseMessage> ApplicationMetricsHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); yield return(incomingMessage.ReplyToChannel($"Sorry this command isn't supported yet.")); yield break; //if (NewRelicPlugin.ApplicationDetailTargetedCommandMisformed(incomingMessage.TargetedText)) //{ // yield return incomingMessage.ReplyToChannel($"NewRelic application metrics command was not formatted correctly. Help: {this.applicationMetricsHelpText}"); // yield break; //} //var application = this.newRelicPlugin.GetApplicationFromTargetedText(incomingMessage.TargetedText); //if (application == null) //{ // yield return incomingMessage.ReplyToChannel($"No NewRelic application could be found with the ID specified. Help: {this.applicationMetricsHelpText}"); // yield break; //} //yield return incomingMessage.ReplyToChannel(this.newRelicPlugin.GetSummaryMetricsText(application.Id)); }
private IEnumerable <ResponseMessage> DnsLookupHandler(IncomingMessage incomingMessage, IValidHandle matchedHandle) { yield return(incomingMessage.IndicateTypingOnChannel()); if (!DnsLookupCommandWellFormatted(incomingMessage.TargetedText)) { yield return(incomingMessage.ReplyToChannel($"Command was not formatted correctly. Help: {GetHelpText(Lookup)}")); yield break; } var hostToLookup = DnsPlugin.GetHostFromMessage(incomingMessage.TargetedText); var ipAddresses = DnsPlugin.LookUpIpFromCommandText(hostToLookup); if (ipAddresses == null) { yield return(incomingMessage.ReplyToChannel($"Error looking up requested host '{hostToLookup}'. No result were returned.")); yield break; } yield return(incomingMessage.ReplyToChannel($"dns lookup for '{hostToLookup}' returned: {DnsPlugin.GetIpAddressesAsText(ipAddresses)}")); }
private IEnumerable <ResponseMessage> Handler(IncomingMessage message, IValidHandle matchedHandle) { yield return(message.IndicateTypingOnChannel()); }
private IEnumerable <ResponseMessage> DiscourseSearch(IncomingMessage incomingMessage, IValidHandle validHandle) { var genericAnswerKeywords = new List <string>() { "question", "i have a question", "i need help" }; if (genericAnswerKeywords.Contains(incomingMessage.RawText.ToLower())) { yield return(incomingMessage.IndicateTypingOnChannel()); _statsPlugin.IncrementState("Helper:BlindlyHelped"); yield return(incomingMessage.ReplyToChannel( $"Perhaps you should look at https://nbitstack.com/c/btcpayserver and see if there is already an answer for you there, @{incomingMessage.Username}")); } var discourseSearchKeywords = new List <string>() { "how can i", "i need help with" }; if (discourseSearchKeywords.Any(s => incomingMessage.RawText.ToLower().StartsWith(s.ToLower()))) { var discourseUrl = "https://nbitstack.com"; var searchText = incomingMessage.RawText; discourseSearchKeywords.ForEach(s => { searchText = searchText.Replace(s, ""); }); yield return(incomingMessage.IndicateTypingOnChannel()); var message = $"Maybe this can help: {discourseUrl}/search?q={Url.Encode(searchText.Trim())}"; _statsPlugin.IncrementState("RedirectedToDiscourseSearch:Count"); yield return(incomingMessage.ReplyToChannel(message)); } var bcashKeywords = new List <string>() { "bcash", "bitcoin cash", "tell me a joke" }; if (bcashKeywords.Contains(incomingMessage.RawText.ToLower())) { yield return(incomingMessage.IndicateTypingOnChannel()); _statsPlugin.IncrementState("Jokes:Told"); yield return(incomingMessage.ReplyToChannel(jokes[_r.Next(0, jokes.Count)].Content)); } if (incomingMessage.RawText.ToLower().StartsWith("addjoke:")) { var joke = incomingMessage.RawText.Substring("addjoke:".Length); jokes.Add(new Joke() { Content = joke }); _jsonStoragePlugin.SaveFile("jokes", jokes.ToArray()); yield return(incomingMessage.ReplyDirectlyToUser("joke added!")); } if (incomingMessage.RawText.ToLower().StartsWith("removejoke:")) { var joke = incomingMessage.RawText.Substring("removejoke:".Length); if (jokes.Any(joke1 => joke == joke1.Content)) { var jokeIndex = jokes.FindIndex(joke1 => joke == joke1.Content); jokes.RemoveAt(jokeIndex); _jsonStoragePlugin.SaveFile("jokes", jokes.ToArray()); yield return(incomingMessage.ReplyDirectlyToUser("joke removed!")); } } }