public virtual async void HandleMessage(FullMessage message) { if (TemporaryCommandHandlers.TryGetValue(message.Channel.ID, out TemporaryCommandHandler tempHandler)) { if (tempHandler.HandleMessage(message)) { // If the temporary handler reads a command, skip any other command handling Logger.LogInfo($"TempHandler handled command: {message.Content}\nIn channel: {message.Channel}"); return; } } if (ParseCommand(message, out var command, out var parameters)) { if (BotCommands.TryGetValue(command.ToLower(), out BotCommand botCommand)) { CommandInfo commandInfo = new CommandInfo() { Message = message, Command = command, Arguments = parameters, CommandHandler = this, }; TemporaryCommandHandlers.Remove(message.Channel.ID); botCommand.Execute(commandInfo, commandInfo.ApiClient); } else { await ApiClient.PostMessage($"There is no command for {command}", message.Channel.ID); } }
private async ValueTask HandleProxyDeleteReaction(MessageReactionAddEvent evt, FullMessage msg) { if (!(await _cache.PermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages)) { return; } var system = await _repo.GetSystemByAccount(evt.UserId); // Can only delete your own message if (msg.System?.Id != system?.Id && msg.Message.Sender != evt.UserId) { return; } try { await _rest.DeleteMessage(evt.ChannelId, evt.MessageId); } catch (NotFoundException) { // Message was deleted by something/someone else before we got to it } await _repo.DeleteMessage(evt.MessageId); }
private async ValueTask HandleQueryReaction(MessageReactionAddEvent evt, FullMessage msg) { var guild = await _cache.GetGuild(evt.GuildId !.Value); // Try to DM the user info about the message try { var dm = await _dmCache.GetOrCreateDmChannel(evt.UserId); var embeds = new List <Embed>(); if (msg.Member != null) { embeds.Add(await _embeds.CreateMemberEmbed( msg.System, msg.Member, guild, LookupContext.ByNonOwner, DateTimeZone.Utc )); } embeds.Add(await _embeds.CreateMessageInfoEmbed(msg, true)); await _rest.CreateMessage(dm, new MessageRequest { Embeds = embeds.ToArray() }); } catch (ForbiddenException) { } // No permissions to DM, can't check for this :( await TryRemoveOriginalReaction(evt); }
private void ProducerHelper_OnSendAMessageEvent(object sender, FullMessage e) { if (instance.LastMessage != e) { instance.LastMessage = e; if (Services.TodoActions.Mapping.HasAction(e.Message.Action)) { Services.TodoActions.db.Add(Newtonsoft.Json.JsonConvert.SerializeObject(e.Message)); } if (Services.TimeActions.Mapping.HasAction(e.Message.Action)) { Services.TimeActions.db.Add(Newtonsoft.Json.JsonConvert.SerializeObject(e.Message)); } if (Services.GroupActions.Mapping.HasAction(e.Message.Action)) { Services.GroupActions.db.Add(Newtonsoft.Json.JsonConvert.SerializeObject(e.Message)); } if (Services.MemoryActions.Mapping.HasAction(e.Message.Action)) { Services.MemoryActions.db.Add(Newtonsoft.Json.JsonConvert.SerializeObject(e.Message)); } if (Services.LocationActions.Mapping.HasAction(e.Message.Action)) { Services.LocationActions.db.Add(Newtonsoft.Json.JsonConvert.SerializeObject(e.Message)); } if (Services.AssistantActions.Mapping.HasAction(e.Message.Action)) { Services.AssistantActions.db.Add(Newtonsoft.Json.JsonConvert.SerializeObject(e.Message)); } } }
public override bool Equals(object obj) { var otherObj = obj as TaskErrorModel; if (null == otherObj) { return(false); } return(FullMessage.Replace('/', '\\') == otherObj.FullMessage.Replace('/', '\\')); }
private async ValueTask HandlePingReaction(MessageReactionAddEvent evt, FullMessage msg) { if (!_bot.PermissionsIn(evt.ChannelId).HasFlag(PermissionSet.ManageMessages)) { return; } // Check if the "pinger" has permission to send messages in this channel // (if not, PK shouldn't send messages on their behalf) var member = await _rest.GetGuildMember(evt.GuildId !.Value, evt.UserId); var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages; if (member == null || !_cache.PermissionsFor(evt.ChannelId, member).HasFlag(requiredPerms)) { return; } if (msg.System.PingsEnabled) { // If the system has pings enabled, go ahead var embed = new EmbedBuilder().Description($"[Jump to pinged message]({evt.JumpLink()})"); await _rest.CreateMessage(evt.ChannelId, new() { Content = $"Psst, **{msg.Member.DisplayName()}** (<@{msg.Message.Sender}>), you have been pinged by <@{evt.UserId}>.", Embed = embed.Build(), AllowedMentions = new AllowedMentions { Users = new[] { msg.Message.Sender } } }); } else { // If not, tell them in DMs (if we can) try { var dm = await _cache.GetOrCreateDmChannel(_rest, evt.UserId); await _rest.CreateMessage(dm.Id, new MessageRequest { Content = $"{Emojis.Error} {msg.Member.DisplayName()}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:" }); await _rest.CreateMessage(dm.Id, new MessageRequest { Content = $"<@{msg.Message.Sender}>".AsCode() }); } catch (ForbiddenException) { } } await TryRemoveOriginalReaction(evt); }
public async Task <Embed> CreateMessageInfoEmbed(FullMessage msg) { var channel = await _client.GetChannelAsync(msg.Message.Channel) as ITextChannel; var serverMsg = channel != null ? await channel.GetMessageAsync(msg.Message.Mid) : null; var memberStr = $"{msg.Member.Name} (`{msg.Member.Hid}`)"; var userStr = $"*(deleted user {msg.Message.Sender})*"; ICollection <IRole> roles = null; if (channel != null) { // Look up the user with the REST client // this ensures we'll still get the information even if the user's not cached, // even if this means an extra API request (meh, it'll be fine) var shard = ((DiscordShardedClient)_client).GetShardFor(channel.Guild); var guildUser = await shard.Rest.GetGuildUserAsync(channel.Guild.Id, msg.Message.Sender); if (guildUser != null) { if (guildUser.RoleIds.Count > 0) { roles = guildUser.RoleIds .Select(roleId => channel.Guild.GetRole(roleId)) .Where(role => role.Name != "@everyone") .OrderByDescending(role => role.Position) .ToList(); } userStr = guildUser.Nickname != null ? $"**Username:** {guildUser?.NameAndMention()}\n**Nickname:** {guildUser.Nickname}" : guildUser?.NameAndMention(); } } var eb = new EmbedBuilder() .WithAuthor(msg.Member.Name, msg.Member.AvatarUrl) .WithDescription(serverMsg?.Content ?? "*(message contents deleted or inaccessible)*") .WithImageUrl(serverMsg?.Attachments?.FirstOrDefault()?.Url) .AddField("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true) .AddField("Member", memberStr, true) .AddField("Sent by", userStr, inline: true) .WithTimestamp(SnowflakeUtils.FromSnowflake(msg.Message.Mid)); if (roles != null && roles.Count > 0) { eb.AddField($"Account roles ({roles.Count})", string.Join(", ", roles.Select(role => role.Name))); } return(eb.Build()); }
public static Task SendToSelf(this IMessageHandlerContext context, Messages.ICommand command) { var container = context.Extensions.Get <IContainer>(); var dispatcher = container.Resolve <IMessageDispatcher>(); var message = new FullMessage { Headers = context.MessageHeaders.Where(x => x.Key != $"{Defaults.PrefixHeader}.{Defaults.MessageIdHeader}").ToDictionary(kv => kv.Key, kv => kv.Value), Message = command }; Task.Run(() => dispatcher.SendLocal(message)); return(Task.CompletedTask); }
private async ValueTask HandleQueryReaction(MessageReactionAddEventArgs evt, FullMessage msg) { // Try to DM the user info about the message var member = await evt.Guild.GetMember(evt.User.Id); try { await member.SendMessageAsync(embed : await _embeds.CreateMemberEmbed(msg.System, msg.Member, evt.Guild, LookupContext.ByNonOwner)); await member.SendMessageAsync(embed : await _embeds.CreateMessageInfoEmbed(evt.Client, msg)); } catch (UnauthorizedException) { } // No permissions to DM, can't check for this :( await TryRemoveOriginalReaction(evt); }
void OnMessageCreate(DiscordGatewayPayload payload) { try { Message message = payload.EventData.ToObject <Message>(); FullMessage fullMessage = new FullMessage(this, message); CommandHandler?.HandleMessage(fullMessage); } catch (Exception ex) { Logger.LogException(ex); } }
private async ValueTask HandleQueryReaction(MessageReactionAddEventArgs evt, FullMessage msg) { // Try to DM the user info about the message var member = await evt.Guild.GetMemberAsync(evt.User.Id); try { await member.SendMessageAsync(embed : await _embeds.CreateMemberEmbed(msg.System, msg.Member, evt.Guild, LookupContext.ByNonOwner)); await member.SendMessageAsync(embed : await _embeds.CreateMessageInfoEmbed(evt.Client, msg)); } catch (UnauthorizedException) { } // No permissions to DM, can't check for this :( // And finally remove the original reaction (if we can) if (evt.Channel.BotHasAllPermissions(Permissions.ManageMessages)) { await evt.Message.DeleteReactionAsync(evt.Emoji, evt.User); } }
private async ValueTask HandlePingReaction(MessageReactionAddEventArgs evt, FullMessage msg) { if (!evt.Channel.BotHasAllPermissions(Permissions.SendMessages)) { return; } // Check if the "pinger" has permission to send messages in this channel // (if not, PK shouldn't send messages on their behalf) var guildUser = await evt.Guild.GetMemberAsync(evt.User.Id); var requiredPerms = Permissions.AccessChannels | Permissions.SendMessages; if ((guildUser.PermissionsIn(evt.Channel) & requiredPerms) != requiredPerms) { return; } if (msg.System.PingsEnabled) { // If the system has pings enabled, go ahead var embed = new DiscordEmbedBuilder().WithDescription($"[Jump to pinged message]({evt.Message.JumpLink})"); await evt.Channel.SendMessageFixedAsync($"Psst, **{msg.Member.DisplayName()}** (<@{msg.Message.Sender}>), you have been pinged by <@{evt.User.Id}>.", embed : embed.Build(), new IMention[] { new UserMention(msg.Message.Sender) }); } else { // If not, tell them in DMs (if we can) try { await guildUser.SendMessageFixedAsync($"{Emojis.Error} {msg.Member.DisplayName()}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:"); await guildUser.SendMessageFixedAsync($"`<@{msg.Message.Sender}>`"); } catch (UnauthorizedException) { } } // Finally, remove the original reaction (if we can) if (evt.Channel.BotHasAllPermissions(Permissions.ManageMessages)) { await evt.Message.DeleteReactionAsync(evt.Emoji, evt.User); } }
public virtual bool HandleMessage(FullMessage message) { if (ParseCommand(message, out var command, out var parameters)) { if (BotCommands.TryGetValue(command, out BotCommand botCommand)) { CommandInfo commandInfo = new CommandInfo() { Message = message, Command = command, Arguments = parameters, CommandHandler = ParentCommandHandler, }; botCommand.Execute(commandInfo, commandInfo.ApiClient); return true; } else { return false; } }
private async ValueTask HandleQueryReaction(MessageReactionAddEvent evt, FullMessage msg) { var guild = _cache.GetGuild(evt.GuildId !.Value); // Try to DM the user info about the message try { var dm = await _cache.GetOrCreateDmChannel(_rest, evt.UserId); await _rest.CreateMessage(dm.Id, new MessageRequest { Embed = await _embeds.CreateMemberEmbed(msg.System, msg.Member, guild, LookupContext.ByNonOwner) }); await _rest.CreateMessage(dm.Id, new MessageRequest { Embed = await _embeds.CreateMessageInfoEmbed(msg) }); } catch (ForbiddenException) { } // No permissions to DM, can't check for this :( await TryRemoveOriginalReaction(evt); }
private async ValueTask HandlePingReaction(MessageReactionAddEvent evt, FullMessage msg) { if (!(await _cache.PermissionsIn(evt.ChannelId)).HasFlag(PermissionSet.ManageMessages)) { return; } // Check if the "pinger" has permission to send messages in this channel // (if not, PK shouldn't send messages on their behalf) var member = await _rest.GetGuildMember(evt.GuildId !.Value, evt.UserId); var requiredPerms = PermissionSet.ViewChannel | PermissionSet.SendMessages; if (member == null || !(await _cache.PermissionsFor(evt.ChannelId, member)).HasFlag(requiredPerms)) { return; } if (msg.Member == null) { return; } var config = await _repo.GetSystemConfig(msg.System.Id); if (config.PingsEnabled) { // If the system has pings enabled, go ahead await _rest.CreateMessage(evt.ChannelId, new MessageRequest { Content = $"Psst, **{msg.Member.DisplayName()}** (<@{msg.Message.Sender}>), you have been pinged by <@{evt.UserId}>.", Components = new[] { new MessageComponent { Type = ComponentType.ActionRow, Components = new[] { new MessageComponent { Style = ButtonStyle.Link, Type = ComponentType.Button, Label = "Jump", Url = evt.JumpLink() } } } }, AllowedMentions = new AllowedMentions { Users = new[] { msg.Message.Sender } } }); } else { // If not, tell them in DMs (if we can) try { var dm = await _dmCache.GetOrCreateDmChannel(evt.UserId); await _rest.CreateMessage(dm, new MessageRequest { Content = $"{Emojis.Error} {msg.Member.DisplayName()}'s system has disabled reaction pings. If you want to mention them anyway, you can copy/paste the following message:" }); await _rest.CreateMessage( dm, new MessageRequest { Content = $"<@{msg.Message.Sender}>".AsCode() } ); } catch (ForbiddenException) { } } await TryRemoveOriginalReaction(evt); }
public async Task <DiscordEmbed> CreateMessageInfoEmbed(DiscordClient client, FullMessage msg) { var ctx = LookupContext.ByNonOwner; var channel = await _client.GetChannel(msg.Message.Channel); var serverMsg = channel != null ? await channel.GetMessage(msg.Message.Mid) : null; // Need this whole dance to handle cases where: // - the user is deleted (userInfo == null) // - the bot's no longer in the server we're querying (channel == null) // - the member is no longer in the server we're querying (memberInfo == null) DiscordMember memberInfo = null; DiscordUser userInfo = null; if (channel != null) { memberInfo = await channel.Guild.GetMember(msg.Message.Sender); } if (memberInfo != null) { userInfo = memberInfo; // Don't do an extra request if we already have this info from the member lookup } else { userInfo = await client.GetUser(msg.Message.Sender); } // Calculate string displayed under "Sent by" string userStr; if (memberInfo != null && memberInfo.Nickname != null) { userStr = $"**Username:** {memberInfo.NameAndMention()}\n**Nickname:** {memberInfo.Nickname}"; } else if (userInfo != null) { userStr = userInfo.NameAndMention(); } else { userStr = $"*(deleted user {msg.Message.Sender})*"; } // Put it all together var eb = new DiscordEmbedBuilder() .WithAuthor(msg.Member.NameFor(ctx), iconUrl: DiscordUtils.WorkaroundForUrlBug(msg.Member.AvatarFor(ctx))) .WithDescription(serverMsg?.Content?.NormalizeLineEndSpacing() ?? "*(message contents deleted or inaccessible)*") .WithImageUrl(serverMsg?.Attachments?.FirstOrDefault()?.Url) .AddField("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true) .AddField("Member", $"{msg.Member.NameFor(ctx)} (`{msg.Member.Hid}`)", true) .AddField("Sent by", userStr, inline: true) .WithTimestamp(DiscordUtils.SnowflakeToInstant(msg.Message.Mid).ToDateTimeOffset()); var roles = memberInfo?.Roles?.ToList(); if (roles != null && roles.Count > 0) { eb.AddField($"Account roles ({roles.Count})", string.Join(", ", roles.Select(role => role.Name))); } return(eb.Build()); }
private async ValueTask HandleDeleteReaction(MessageReactionAddEventArgs evt, FullMessage msg) { if (!evt.Channel.BotHasAllPermissions(Permissions.ManageMessages)) { return; } // Can only delete your own message if (msg.Message.Sender != evt.User.Id) { return; } try { await evt.Message.DeleteAsync(); } catch (NotFoundException) { // Message was deleted by something/someone else before we got to it } await _db.Execute(c => _repo.DeleteMessage(c, evt.Message.Id)); }
public override int GetHashCode() { int result = 17; unchecked { if (RuleId != null) { result = (result * 31) + RuleId.GetHashCode(); } result = (result * 31) + Kind.GetHashCode(); if (FullMessage != null) { result = (result * 31) + FullMessage.GetHashCode(); } if (ShortMessage != null) { result = (result * 31) + ShortMessage.GetHashCode(); } if (FormattedMessage != null) { result = (result * 31) + FormattedMessage.GetHashCode(); } if (Locations != null) { foreach (var value_0 in Locations) { result = result * 31; if (value_0 != null) { result = (result * 31) + value_0.GetHashCode(); } } } if (ToolFingerprint != null) { result = (result * 31) + ToolFingerprint.GetHashCode(); } if (Stacks != null) { foreach (var value_1 in Stacks) { result = result * 31; if (value_1 != null) { foreach (var value_2 in value_1) { result = result * 31; if (value_2 != null) { result = (result * 31) + value_2.GetHashCode(); } } } } } if (CodeFlows != null) { foreach (var value_3 in CodeFlows) { result = result * 31; if (value_3 != null) { foreach (var value_4 in value_3) { result = result * 31; if (value_4 != null) { result = (result * 31) + value_4.GetHashCode(); } } } } } if (RelatedLocations != null) { foreach (var value_5 in RelatedLocations) { result = result * 31; if (value_5 != null) { result = (result * 31) + value_5.GetHashCode(); } } } result = (result * 31) + IsSuppressedInSource.GetHashCode(); if (Fixes != null) { foreach (var value_6 in Fixes) { result = result * 31; if (value_6 != null) { result = (result * 31) + value_6.GetHashCode(); } } } if (Properties != null) { // Use xor for dictionaries to be order-independent. int xor_0 = 0; foreach (var value_7 in Properties) { xor_0 ^= value_7.Key.GetHashCode(); if (value_7.Value != null) { xor_0 ^= value_7.Value.GetHashCode(); } } result = (result * 31) + xor_0; } if (Tags != null) { foreach (var value_8 in Tags) { result = result * 31; if (value_8 != null) { result = (result * 31) + value_8.GetHashCode(); } } } } return(result); }
/// <summary> /// Returns the hashcode of this Object /// </summary> /// <returns>Hash code (int)</returns> public override int GetHashCode() { // Credit: http://stackoverflow.com/a/263416/677735 unchecked // Overflow is fine, just wrap { int hash = 41; // Suitable nullity checks etc, of course :) if (Id != null) { hash = hash * 59 + Id.GetHashCode(); } if (LogMessageTypeId != null) { hash = hash * 59 + LogMessageTypeId.GetHashCode(); } if (ApplicationName != null) { hash = hash * 59 + ApplicationName.GetHashCode(); } if (ApplicationMethod != null) { hash = hash * 59 + ApplicationMethod.GetHashCode(); } if (IpAddress != null) { hash = hash * 59 + IpAddress.GetHashCode(); } if (LoginToken != null) { hash = hash * 59 + LoginToken.GetHashCode(); } if (ShortMessage != null) { hash = hash * 59 + ShortMessage.GetHashCode(); } if (RequestHttpMethod != null) { hash = hash * 59 + RequestHttpMethod.GetHashCode(); } if (RequestUri != null) { hash = hash * 59 + RequestUri.GetHashCode(); } if (RequestParams != null) { hash = hash * 59 + RequestParams.GetHashCode(); } if (RequestBody != null) { hash = hash * 59 + RequestBody.GetHashCode(); } if (StatusCode != null) { hash = hash * 59 + StatusCode.GetHashCode(); } if (ResponseContent != null) { hash = hash * 59 + ResponseContent.GetHashCode(); } if (FullMessage != null) { hash = hash * 59 + FullMessage.GetHashCode(); } if (Exception != null) { hash = hash * 59 + Exception.GetHashCode(); } if (Trace != null) { hash = hash * 59 + Trace.GetHashCode(); } if (Logged != null) { hash = hash * 59 + Logged.GetHashCode(); } return(hash); } }
public async Task <Embed> CreateMessageInfoEmbed(FullMessage msg) { var channel = await _cache.GetOrFetchChannel(_rest, msg.Message.Channel); var ctx = LookupContext.ByNonOwner; Message serverMsg = null; try { serverMsg = await _rest.GetMessage(msg.Message.Channel, msg.Message.Mid); } catch (ForbiddenException) { // no permission, couldn't fetch, oh well } // Need this whole dance to handle cases where: // - the user is deleted (userInfo == null) // - the bot's no longer in the server we're querying (channel == null) // - the member is no longer in the server we're querying (memberInfo == null) // TODO: optimize ordering here a bit with new cache impl; and figure what happens if bot leaves server -> channel still cached -> hits this bit and 401s? GuildMemberPartial memberInfo = null; User userInfo = null; if (channel != null) { GuildMember member = null; try { member = await _rest.GetGuildMember(channel.GuildId !.Value, msg.Message.Sender); } catch (ForbiddenException) { // no permission, couldn't fetch, oh well } if (member != null) { // Don't do an extra request if we already have this info from the member lookup userInfo = member.User; } memberInfo = member; } if (userInfo == null) { userInfo = await _cache.GetOrFetchUser(_rest, msg.Message.Sender); } // Calculate string displayed under "Sent by" string userStr; if (memberInfo != null && memberInfo.Nick != null) { userStr = $"**Username:** {userInfo.NameAndMention()}\n**Nickname:** {memberInfo.Nick}"; } else if (userInfo != null) { userStr = userInfo.NameAndMention(); } else { userStr = $"*(deleted user {msg.Message.Sender})*"; } // Put it all together var eb = new EmbedBuilder() .Author(new(msg.Member.NameFor(ctx), IconUrl: DiscordUtils.WorkaroundForUrlBug(msg.Member.AvatarFor(ctx)))) .Description(serverMsg?.Content?.NormalizeLineEndSpacing() ?? "*(message contents deleted or inaccessible)*") .Image(new(serverMsg?.Attachments?.FirstOrDefault()?.Url)) .Field(new("System", msg.System.Name != null ? $"{msg.System.Name} (`{msg.System.Hid}`)" : $"`{msg.System.Hid}`", true)) .Field(new("Member", $"{msg.Member.NameFor(ctx)} (`{msg.Member.Hid}`)", true)) .Field(new("Sent by", userStr, true)) .Timestamp(DiscordUtils.SnowflakeToInstant(msg.Message.Mid).ToDateTimeOffset().ToString("O")); var roles = memberInfo?.Roles?.ToList(); if (roles != null && roles.Count > 0) { // TODO: what if role isn't in cache? figure out a fallback var rolesString = string.Join(", ", roles.Select(id => _cache.GetRole(id)) .OrderByDescending(role => role.Position) .Select(role => role.Name)); eb.Field(new($"Account roles ({roles.Count})", rolesString.Truncate(1024))); } return(eb.Build()); }
public override int GetHashCode() { return(FullMessage.GetHashCode()); }
private async ValueTask HandleProxyDeleteReaction(MessageReactionAddEvent evt, FullMessage msg) { if (!_bot.PermissionsIn(evt.ChannelId).HasFlag(PermissionSet.ManageMessages)) { return; } // Can only delete your own message if (msg.Message.Sender != evt.UserId) { return; } try { await _rest.DeleteMessage(evt.ChannelId, evt.MessageId); } catch (NotFoundException) { // Message was deleted by something/someone else before we got to it } await _db.Execute(c => _repo.DeleteMessage(c, evt.MessageId)); }
public void showMessageInLogViewer(string type, string taskName, int workCurr) { FullMessage.WriteLine("[GitProgress] {0} : {1} : {2}".info(type, taskName, workCurr)); }