/// <summary> /// Notifies the conversation client (customer) or the conversation owner (agent) that there /// was a problem forwarding their message /// </summary> /// <param name="messageRouterResult">The result to handle.</param> private static async Task <string> HandleFailedToForwardMessageAsync(MessageRouterResult messageRouterResult) { string message = $"{(string.IsNullOrEmpty(messageRouterResult.ErrorMessage) ? "Failed to forward the message" : messageRouterResult.ErrorMessage)}"; await MessagingUtils.ReplyToActivityAsync(messageRouterResult.Activity, message); return(message); }
public override async Task VerifyStandaloneXml( StandaloneVerificationRequest request, IServerStreamWriter <StandaloneVerificationResponse> responseStream, ServerCallContext context) { try { _msg.InfoFormat("Starting stand-alone verification request from {0}", context.Peer); _msg.DebugFormat("Request details: {0}", request); Action <LoggingEvent> action = SendInfoLogAction(responseStream, ServiceCallStatus.Running); using (MessagingUtils.TemporaryRootAppender(new ActionAppender(action))) { Func <ITrackCancel, ServiceCallStatus> func = trackCancel => VerifyStandaloneXmlCore(request, responseStream, trackCancel); ServiceCallStatus result = await GrpcServerUtils.ExecuteServiceCall( func, context, _singleStaThreadScheduler); _msg.InfoFormat("Verification {0}", result); } } catch (Exception e) { _msg.Error($"Error verifying quality for request {request}", e); SendFatalException(e, responseStream); SetUnhealthy(); } }
public async Task UserInfo(IUser? runner = null) { DatabaseUser databaseUser; if (runner is null) databaseUser = Database.GetUser(Context.User.Id); else databaseUser = Database.GetUser(runner.Id); var user = Client.GetUser(databaseUser.Id); var guildUser = Context.Guild?.GetUser(databaseUser.Id); var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); embedBuilder.WithAuthor(user); embedBuilder.WithDescription(user.Status.ToString()); embedBuilder.AddField("General", $"**User ID**: {user.Id}\n" + $"**Created**: {user.CreatedAt}\n" + $"**Human?**: {!user.IsBot}"); if (guildUser != null) embedBuilder.AddField("This Server", $"**Nickname**: {guildUser.Nickname}\n" + $"**Joined**: {guildUser.JoinedAt}\n"); embedBuilder.AddField("ShrimpBot", $"**Money**: {Config.CurrencySymbol}{databaseUser.Money}\n" + $"**Cuteness**: {databaseUser.Cuteness}\n" + $"**Bot Permission Level**: {databaseUser.BotPermissions}\n"); await ReplyAsync(embed: embedBuilder.Build()); }
public async Task ServerInfo() { var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); var server = Context.Guild; if (server is null) { await ReplyAsync("Looks like we aren't in a server."); return; } embedBuilder.WithAuthor(server.Name, server.IconUrl); embedBuilder.AddField("General", $"**Created**: {server.CreatedAt}\n" + $"**Owner**: {server.Owner}\n" + $"**Members**: {server.MemberCount}\n"); embedBuilder.AddField("Misc. Information", $"**Text Channels**: {server.TextChannels.Count}\n" + $"**Roles**: {server.Roles.Count}\n" + $"**Emotes**: {server.Emotes.Count}\n" + $"**Content Filter**: {server.ExplicitContentFilter}\n" + $"**Server Boost Level**: {server.PremiumTier}"); await ReplyAsync(embed: embedBuilder.Build()); }
/// <summary> /// From IMessageRouterResultHandler. /// </summary> /// <param name="messageRouterResult">The result to handle.</param> /// <returns></returns> public virtual async Task HandleResultAsync(MessageRouterResult messageRouterResult) { if (messageRouterResult == null) { throw new ArgumentNullException($"The given result ({nameof(messageRouterResult)}) is null"); } string messageRouterResultAsString = messageRouterResult.ToString(); if (messageRouterResult.Activity != null) { await MessagingUtils.ReplyToActivityAsync(messageRouterResult.Activity, messageRouterResultAsString); } else { MessageRouterManager messageRouterManager = MessageRouterManager.Instance; if (messageRouterResult.ConversationOwnerParty != null) { await messageRouterManager.SendMessageToPartyByBotAsync( messageRouterResult.ConversationOwnerParty, messageRouterResultAsString); } if (messageRouterResult.ConversationClientParty != null) { await messageRouterManager.SendMessageToPartyByBotAsync( messageRouterResult.ConversationClientParty, messageRouterResultAsString); } } }
public async Task AddImage(string path, string type, string creator, string source) { var runner = Database.GetUser(Context.User.Id); if (runner.BotPermissions < BotPermissionLevel.BotAdministrator) { await ReplyAsync(MessagingUtils.GetNoPermissionsString()); return; } if (creator == "null") { creator = string.Empty; } if (source == "null") { source = string.Empty; } var imageType = type.ToLower() switch { "anime" => ImageType.Anime, "catgirls" => ImageType.Catgirls, "all" => ImageType.All, _ => ImageType.All, }; Database.CreateImage(path, imageType, new CuteImage { Creator = creator, Path = path, ImageSource = source }); }
public async Task Leaderboard() { var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); List <DatabaseUser> users = Database.GetAllUsers(); if (users.Count >= 10) { users = users.GetRange(0, 10).OrderByDescending(o => o.Money).ToList(); } else { users = users.OrderByDescending(o => o.Money).ToList(); } var stringBuilder = new StringBuilder(); int i = 1; foreach (var user in users) { string userx = Client.Rest.GetUserAsync(user.Id).Result.Username; if (userx == Context.User.Username) { userx = $"**{userx}**"; } stringBuilder.AppendLine($"{i} - {userx}: {Config.CurrencySymbol}{string.Format("{0:n}", user.Money)}"); i++; } embedBuilder.AddField($"Top {Config.Name} users", stringBuilder.ToString()); await ReplyAsync(embed : embedBuilder.Build()); }
/// <summary> /// Notifies the conversation client (customer) or the conversation owner (agent) that /// there was a problem forwarding their message. /// </summary> /// <param name="messageRouterResult">The result to handle.</param> protected virtual async Task HandleFailedToForwardMessageAsync(MessageRouterResult messageRouterResult) { string messageText = string.IsNullOrEmpty(messageRouterResult.ErrorMessage) ? ConversationText.FailedToForwardMessage : messageRouterResult.ErrorMessage; await MessagingUtils.ReplyToActivityAsync(messageRouterResult.Activity, messageText); }
public async Task Timers() { var timers = RuntimeInformation.Timers.RunningTimers.Where(x => x.CreatorID == Context.User.Id); if (!timers.Any()) { await ReplyAsync("You don't have any running timers."); return; } var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); embedBuilder.WithTitle("Your running timers"); embedBuilder.WithAuthor(Context.User); int i = 1; foreach (var timer in timers) { embedBuilder.AddField($"Timer #{i}", $"**Elapses**: {MessagingUtils.GetLengthString(timer.Elapses - DateTime.UtcNow)}\n" + $"**Message**: {timer.Message}", inline: true); i++; } await ReplyAsync(embed : embedBuilder.Build()); }
public async Task Daily() { var runner = Database.GetUser(Context.User.Id); if (DateTime.UtcNow - runner.DailyLastClaimed >= new TimeSpan(1, 0, 0, 0)) { var responses = new string[] { "You helped Squid fix bugs in FMP and got {0} {1}.", "You beat theBeat out of the water and got {0} {1} for your hard work.", "The dev did a fucky wucky." }; string response = responses[rng.Next(0, responses.Length - 1)]; decimal moneygained = (decimal)Math.Round(50 * runner.DailyBonus); runner.Money += moneygained; runner.DailyBonus += 0.1; runner.DailyLastClaimed = DateTime.UtcNow; await ReplyAsync(string.Format(response, moneygained, Config.Currency)); } else { await ReplyAsync($"You already worked for Squid today. Try again in {MessagingUtils.GetLengthString((runner.DailyLastClaimed + new TimeSpan(1, 0, 0, 0)) - DateTime.UtcNow)}."); return; } Database.WriteUser(runner); }
private static Action <LoggingEvent> SendInfoLogAction( [NotNull] IServerStreamWriter <StandaloneVerificationResponse> responseStream, ServiceCallStatus callStatus) { Action <LoggingEvent> action = e => { if (e.Level.Value < Level.Info.Value) { return; } var response = new StandaloneVerificationResponse { Message = new LogMsg { Message = e.RenderedMessage, MessageLevel = e.Level.Value }, ServiceCallStatus = (int)callStatus }; MessagingUtils.TrySendResponse(responseStream, response); }; return(action); }
/// <summary> /// Tries to send the given message activity to the given party using this bot on the same /// channel as the party who the message is sent to. /// </summary> /// <param name="partyToMessage">The party to send the message to.</param> /// <param name="messageActivity">The message activity to send (message content).</param> /// <returns>The ResourceResponse instance or null in case of an error.</returns> public async Task <ResourceResponse> SendMessageToPartyByBotAsync(Party partyToMessage, IMessageActivity messageActivity) { Party botParty = null; if (partyToMessage != null) { // We need the channel account of the bot in the SAME CHANNEL as the RECIPIENT. // The identity of the bot in the channel of the sender is most likely a different one and // thus unusable since it will not be recognized on the recipient's channel. botParty = RoutingDataManager.FindBotPartyByChannelAndConversation( partyToMessage.ChannelId, partyToMessage.ConversationAccount); } if (botParty != null) { messageActivity.From = botParty.ChannelAccount; MessagingUtils.ConnectorClientAndMessageBundle bundle = MessagingUtils.CreateConnectorClientAndMessageActivity( partyToMessage.ServiceUrl, messageActivity); return(await bundle.connectorClient.Conversations.SendToConversationAsync( (Activity)bundle.messageActivity)); } return(null); }
private static async void InventoryService_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { BaseCommandResult result = null; var command = MessagingUtils.UnpackCommand <BaseCommand>(args.Request.Message); if (command is CheckCommand) { var checkResult = new CheckResult(); SysInfo.Fill(checkResult); SpeculationControl.Fill(checkResult); result = checkResult; } else { result = new ErrorResult(); } await args.Request.SendResponseAsync(MessagingUtils.PackResult <ValueSet>(result)); // close app after each command m_appServiceExit.Set(); }
/// <summary> /// Tries to initiates the engagement by creating a request on behalf of the sender in the /// given activity. This method does nothing, if a request for the same user already exists. /// </summary> /// <param name="activity">The activity.</param> /// <returns>The result of the operation.</returns> public MessageRouterResult InitiateEngagement(Activity activity) { MessageRouterResult messageRouterResult = RoutingDataManager.AddPendingRequest(MessagingUtils.CreateSenderParty(activity)); messageRouterResult.Activity = activity; return(messageRouterResult); }
public async Task UserPicture(IUser? person = null) { var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); var imagePath = (person ?? Context.User).GetAvatarUrl(size: 1024); embedBuilder.WithImageUrl(imagePath); await ReplyAsync(embed: embedBuilder.Build()); }
/// <summary> /// Tries to initiate a connection (1:1 conversation) by creating a request on behalf of /// the SENDER in the given activity. This method does nothing, if a request for the same /// user already exists. /// </summary> /// <param name="activity">The activity. The SENDER in this activity (From property) is considered the requestor.</param> /// <param name="rejectConnectionRequestIfNoAggregationChannel">If true, will reject all requests, if there is no aggregation channel.</param> /// <returns>Same as RequestConnection(Party, bool)</returns> public virtual MessageRouterResult RequestConnection( Activity activity, bool rejectConnectionRequestIfNoAggregationChannel = false) { MessageRouterResult messageRouterResult = RequestConnection(MessagingUtils.CreateSenderParty(activity), rejectConnectionRequestIfNoAggregationChannel); messageRouterResult.Activity = activity; return(messageRouterResult); }
public async Task Stats() { var uptime = DateTime.Now - RuntimeInformation.StartupTime; var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); embedBuilder.AddField($"{Config.Name} stats", $"Uptime: {uptime}\n" + $"Commands handled: {RuntimeInformation.CommandsHandled}"); await ReplyAsync(embed : embedBuilder.Build()); }
/// <summary> /// Notifies the conversation client (customer) that no agents are available. /// </summary> /// <param name="messageRouterResult">The result to handle.</param> protected virtual async Task HandleNoAgentsAvailableResultAsync(MessageRouterResult messageRouterResult) { if (messageRouterResult.Activity != null) { await MessagingUtils.ReplyToActivityAsync(messageRouterResult.Activity, ConversationText.NoAgentsAvailable); } else { System.Diagnostics.Debug.WriteLine("The activity of the result is null"); } }
private Activity HandleSystemMessage(Activity activity) { MessageRouterManager messageRouterManager = WebApiConfig.MessageRouterManager; if (activity.Type == ActivityTypes.DeleteUserData) { Party senderParty = MessagingUtils.CreateSenderParty(activity); IList <MessageRouterResult> messageRouterResults = messageRouterManager.RemoveParty(senderParty); foreach (MessageRouterResult messageRouterResult in messageRouterResults) { if (messageRouterResult.Type == MessageRouterResultType.OK) { System.Diagnostics.Debug.WriteLine(ConversationText.UserDataDeleted, senderParty.ChannelAccount?.Name); } } } else if (activity.Type == ActivityTypes.ConversationUpdate) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels if (activity.MembersRemoved != null && activity.MembersRemoved.Count > 0) { foreach (ChannelAccount channelAccount in activity.MembersRemoved) { Party partyToRemove = new Party(activity.ServiceUrl, activity.ChannelId, channelAccount, activity.Conversation); IList <MessageRouterResult> messageRouterResults = messageRouterManager.RemoveParty(partyToRemove); foreach (MessageRouterResult messageRouterResult in messageRouterResults) { if (messageRouterResult.Type == MessageRouterResultType.OK) { System.Diagnostics.Debug.WriteLine(ConversationText.PartyRemoved, partyToRemove.ChannelAccount?.Name); } } } } } else if (activity.Type == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (activity.Type == ActivityTypes.Typing) { // Handle knowing that the user is typing } else if (activity.Type == ActivityTypes.Ping) { } return(null); }
public async Task Uwuify([Remainder] string text) { if (!MessagingUtils.CheckForPings(text)) { await ReplyAsync(FunService.Uwuify(text)); } else { await ReplyAsync($"{MessagingUtils.NoPermissionEmote} You can't ping everyone."); } }
public async Task Help(string search = null) { var embedBuilder = MessagingUtils.GetShrimpbotEmbedBuilder(); if (search is null) { List <ModuleInfo> modules = CommandService.Modules.OrderBy(x => x.Name).ToList(); foreach (ModuleInfo module in modules) { if (module.Name == "Bot Management") { continue; } string summary = $"{module.Summary}\r\n\r\n"; summary += string.Join(", ", module.Commands.Select(x => x.Name)); embedBuilder.AddField(module.Name, summary, inline: true); } await ReplyAsync( ":information_source: **Shrimpbot Help**\n" + $"To get more information about a category or command, type {Config.Prefix}help [category].", false, embedBuilder.Build()); } else { ModuleInfo module = CommandService.Modules.FirstOrDefault(x => x.Name.ToLower().StartsWith(search.ToLower())); if (module is null) { CommandInfo info = CommandService.Commands.FirstOrDefault(y => y.Name.ToLower().StartsWith(search.ToLower())); if (info is null) { await ReplyAsync($"{MessagingUtils.InvalidParameterEmote} The category or commandyou tried to search for doesn't seem to exist."); return; } embedBuilder.Title = info.Name; embedBuilder.Description = info.Summary ?? "No description"; if (!string.IsNullOrEmpty(info.Remarks)) { embedBuilder.AddField("Parameters", info.Remarks); } await ReplyAsync(":information_source: **ShrimpBot Help**", embed : embedBuilder.Build()); return; } string summary = $"{module.Summary}\r\n\r\n"; foreach (CommandInfo command in module.Commands) { summary += $"__{command.Name}__ - {command.Summary ?? "No description"}\n"; } embedBuilder.AddField(module.Name, summary, inline: true); await ReplyAsync(":information_source: **Shrimpbot Help**", embed : embedBuilder.Build()); } }
public async Task DatabaseEvaluateSql(string sql) { var runner = Database.GetUser(Context.User.Id); if (runner.BotPermissions < BotPermissionLevel.BotAdministrator) { await ReplyAsync(MessagingUtils.GetNoPermissionsString()); return; } Database.ExecuteSql(sql); }
public async Task Timer(TimeSpan length, [Remainder] string?message = null) { if (length.Ticks <= 0) { await ReplyAsync("Timer has to run for longer than 0 seconds"); return; } await ReplyAsync($"Timer has been set for {MessagingUtils.GetLengthString(length)}."); RuntimeInformation.Timers.CreateTimer(Context.User, message, length); }
public EmbedBuilder GetFormattedCurrentPage(IUser user) { var builder = MessagingUtils.GetShrimpbotEmbedBuilder(); builder.WithAuthor(user); builder.AddField(CurrentPage.PropertyName, $"{CurrentPage.PropertyDescription}\n\n" + $"Type...\n" + $"{CurrentPage.Prompt}\n" + $"to set this property."); builder.WithFooter($"'quit' - Exit; 'back' - Back"); return(builder); }
/// <summary> /// Checks the given activity for back channel messages and handles them, if detected. /// Currently the only back channel message supported is for creating connections /// (establishing 1:1 conversations). /// </summary> /// <param name="activity">The activity to check for back channel messages.</param> /// <returns> /// The result: /// * MessageRouterResultType.Connected: A connection (1:1 conversation) was created /// * MessageRouterResultType.NoActionTaken: No back channel message detected /// * MessageRouterResultType.Error: See the error message for details /// </returns> public virtual MessageRouterResult HandleBackChannelMessage(Activity activity) { MessageRouterResult messageRouterResult = new MessageRouterResult(); if (activity == null || string.IsNullOrEmpty(activity.Text)) { messageRouterResult.Type = MessageRouterResultType.Error; messageRouterResult.ErrorMessage = $"The given activity ({nameof(activity)}) is either null or the message is missing"; } else if (activity.Text.Equals(BackChannelId)) { if (activity.ChannelData == null) { messageRouterResult.Type = MessageRouterResultType.Error; messageRouterResult.ErrorMessage = "No channel data"; } else { // Handle accepted request and start 1:1 conversation Party conversationClientParty = null; try { conversationClientParty = ParsePartyFromChannelData(activity.ChannelData); } catch (Exception e) { messageRouterResult.Type = MessageRouterResultType.Error; messageRouterResult.ErrorMessage = $"Failed to parse the party information from the back channel message: {e.Message}"; } if (conversationClientParty != null) { Party conversationOwnerParty = MessagingUtils.CreateSenderParty(activity); messageRouterResult = _routingDataManager.ConnectAndClearPendingRequest( conversationOwnerParty, conversationClientParty); messageRouterResult.Activity = activity; } } } else { // No back channel message detected messageRouterResult.Type = MessageRouterResultType.NoActionTaken; } return(messageRouterResult); }
#pragma warning disable 1998 private async Task <Activity> HandleSystemMessageAsync(Activity message) { MessageRouterManager messageRouterManager = WebApiConfig.MessageRouterManager; if (message.Type == ActivityTypes.DeleteUserData) { // Implement user deletion here // If we handle user deletion, return a real message Party senderParty = MessagingUtils.CreateSenderParty(message); if (messageRouterManager.RemoveParty(senderParty)?.Count > 0) { return(message.CreateReply($"Data of user {senderParty.ChannelAccount?.Name} removed")); } } else if (message.Type == ActivityTypes.ConversationUpdate) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels if (message.MembersRemoved != null && message.MembersRemoved.Count > 0) { foreach (ChannelAccount channelAccount in message.MembersRemoved) { Party party = new Party( message.ServiceUrl, message.ChannelId, channelAccount, message.Conversation); if (messageRouterManager.RemoveParty(party)?.Count > 0) { System.Diagnostics.Debug.WriteLine($"Party {party.ToString()} removed"); } } } } else if (message.Type == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (message.Type == ActivityTypes.Typing) { // Handle knowing that the user is typing } else if (message.Type == ActivityTypes.Ping) { } return(null); }
private static void SendFatalException( [NotNull] Exception exception, IServerStreamWriter <StandaloneVerificationResponse> responseStream) { MessagingUtils.SendResponse(responseStream, new StandaloneVerificationResponse() { Message = new LogMsg() { Message = exception.Message, MessageLevel = Level.Error.Value }, ServiceCallStatus = (int)ServiceCallStatus.Failed }); }
/// <summary> /// Notifies the user that there are no aggregation channels setup /// </summary> /// <param name="messageRouterResult">The result to handle.</param> private static async Task <string> HandleNoAggregationChannelResultAsync(MessageRouterResult messageRouterResult) { string message = string.Empty; if (messageRouterResult.Activity != null) { MessageRouterManager messageRouterManager = WebApiConfig.MessageRouterManager; string botName = messageRouterManager.RoutingDataManager.ResolveBotNameInConversation( MessagingUtils.CreateSenderParty(messageRouterResult.Activity)); message = $"{(string.IsNullOrEmpty(messageRouterResult.ErrorMessage) ? "" : $"{messageRouterResult.ErrorMessage}: ")}The message router manager is not initialized; type \""; message += string.IsNullOrEmpty(botName) ? $"{Commands.CommandKeyword} " : $"@{botName} "; message += $"{Commands.CommandAddAggregationChannel}\" to setup the aggregation channel"; await MessagingUtils.ReplyToActivityAsync(messageRouterResult.Activity, message); }
public async Task Cute(string type = "all", string source = "curated") { var imageType = CuteService.ParseImageType(type); var imageSource = CuteService.ParseImageSource(source); if (Context.Guild != null) { var server = Database.GetServer(Context.Guild.Id); if (imageSource == ImageSource.Online && !server.AllowsPotentialNSFW) { await ReplyAsync(MessagingUtils.GetServerNoPermissionsString()); return; } } CuteService.GetImage(Database, imageSource, imageType).SendEmbed(Context); }
/// <summary> /// Notifies the user that there are no aggregation channels set up. /// </summary> /// <param name="messageRouterResult">The result to handle.</param> protected virtual async Task HandleNoAggregationChannelResultAsync(MessageRouterResult messageRouterResult) { if (messageRouterResult.Activity != null) { string messageText = string.IsNullOrEmpty(messageRouterResult.ErrorMessage) ? string.Format(ConversationText.NoAggregationChannel) : messageRouterResult.ErrorMessage; messageText += $" - "; messageText += string.Format( ConversationText.AddAggregationChannelCommandHint, $"{Command.ResolveFullCommand(messageRouterResult.Activity.Recipient?.Name, Commands.CommandAddAggregationChannel)}"); await MessagingUtils.ReplyToActivityAsync(messageRouterResult.Activity, messageText); } else { System.Diagnostics.Debug.WriteLine("The activity of the result is null"); } }