Esempio n. 1
0
        private async Task OnUserUnbanned(SocketUser socketUser, SocketGuild socketGuild)
        {
            var modlog = socketGuild.GetTextChannel(Global.Channels["banlog"]);

            var restAuditLogs = await socketGuild.GetAuditLogsAsync(10).FlattenAsync();

            var unbanLog = restAuditLogs.FirstOrDefault(x => x.Action == ActionType.Unban);


            await modlog.EmbedAsync(new EmbedBuilder()
                                    .WithColor(9896005)
                                    .WithTitle("♻️ Unbanned User")
                                    .AddField(efb => efb
                                              .WithName("Username")
                                              .WithValue(socketUser.ToString())
                                              .WithIsInline(true))
                                    .AddField(efb => efb
                                              .WithName("ID")
                                              .WithValue(socketUser.Id.ToString())
                                              .WithIsInline(true))
                                    .AddField(efb => efb
                                              .WithName("By")
                                              .WithValue(unbanLog.User)
                                              .WithIsInline(true)));
        }
Esempio n. 2
0
        private async Task OnUserBanned(SocketUser socketUser, SocketGuild socketGuild)
        {
            var modlog = socketGuild.GetTextChannel(Global.Channels["modlog"]);

            var restAuditLogs = await socketGuild.GetAuditLogsAsync(10).FlattenAsync(); //As above, might be unnecessary as requests come in packs of 100.

            var banLog = restAuditLogs.FirstOrDefault(x => x.Action == ActionType.Ban);


            await modlog.EmbedAsync(new EmbedBuilder()
                                    .WithColor(9896005)
                                    .WithTitle("⛔️ Banned User")
                                    .AddField(efb => efb
                                              .WithName("Username")
                                              .WithValue(socketUser.ToString())
                                              .WithIsInline(true))
                                    .AddField(efb => efb
                                              .WithName("ID")
                                              .WithValue(socketUser.Id.ToString())
                                              .WithIsInline(true))
                                    .AddField(efb => efb
                                              .WithName("Reason")
                                              .WithValue(banLog.Reason)
                                              .WithIsInline(true))
                                    .AddField(efb => efb
                                              .WithName("By")
                                              .WithValue(banLog.User)
                                              .WithIsInline(true)));
        }
Esempio n. 3
0
        public async Task <string[]> GetRoleUpdates(ShardedCommandContext context, SocketUser user)
        {
            SocketGuild guild  = context.Guild;
            ActionType  action = ActionType.MemberRoleUpdated;

            string[] entries = { };
            IEnumerable <RestAuditLogEntry> auditSearch = await guild.GetAuditLogsAsync(int.MaxValue, null, null, user.Id, action).FlattenAsync();

            foreach (RestAuditLogEntry AuditLogEntry in auditSearch)
            {
                if (AuditLogEntry.Data is MemberRoleAuditLogData data)
                {
                    if (data.Target == user)
                    {
                        // IReadOnlyCollection<MemberRoleEditInfo> beforeRoles = ; //Woork on
                        DateTime date = AuditLogEntry.CreatedAt.DateTime;

                        // after roles
                        // taken roles
                        // added roles

                        //checks
                    }
                }
            }

            return(entries);
        }
Esempio n. 4
0
        private static async Task UserBanned(SocketUser user, SocketGuild guild)
        {
            if (_DiscordClient.GetChannel(WubbysFunHouse.UserLogsChannelId) is IMessageChannel userLogChannel)
            {
                await userLogChannel.SendMessageAsync($"`[{DateTime.UtcNow.ToString(Constants.DateTimeFormatMedium)}]` :no_entry: {user} (`{user.Id}`) was banned.");
            }

            try {
                // Lookup audit log event
                Task runner = Task.Run(async() => {
                    await Task.Delay(4000);

                    if (_DiscordClient.GetChannel(WubbysFunHouse.ModLogsChannelId) is IMessageChannel modLogChannel)
                    {
                        IEnumerable <RestAuditLogEntry> userBans = await guild.GetAuditLogsAsync(10, actionType: ActionType.Ban).FlattenAsync();
                        RestAuditLogEntry bannedEvent            = userBans.Where(x => x.Data is BanAuditLogData data && data.Target.Id == user.Id).FirstOrDefault();

                        if (string.IsNullOrEmpty(bannedEvent.Reason))
                        {
                            await modLogChannel.SendMessageAsync($":no_entry: {user} (`{user.Id}`) was banned by {bannedEvent.User} (`{bannedEvent.User.Id}`) with no reason specified.");
                        }
                        else
                        {
                            await modLogChannel.SendMessageAsync($":no_entry: {user} (`{user.Id}`) was banned by {bannedEvent.User} (`{bannedEvent.User.Id}`) with reason: **{bannedEvent.Reason}**");
                        }
                    }
                });
            } catch (Exception ex) {
                LoggingManager.Log.Error(ex);
            }
        }
Esempio n. 5
0
        /// <summary>
        ///     Fired whenever a user is unbanned from the server.
        /// </summary>
        private async Task UserUnbanned(SocketUser unbannedUser, SocketGuild guild)
        {
            //Retrieve guild settings
            var guildSettings = _botContext.Guilds.AsNoTracking().FirstOrDefault(x => x.GuildId == guild.Id);

            if (guildSettings is null)
            {
                return;
            }

            //Check if guild has moderation functionality enabled
            if (guildSettings.ModerationChannel == 0)
            {
                return;
            }

            IEnumerable <RestAuditLogEntry> logs = null;

            try
            {
                logs = await guild.GetAuditLogsAsync(5).FlattenAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            var entry             = logs?.FirstOrDefault(x => (x.Data as UnbanAuditLogData)?.Target.Id == unbannedUser.Id);
            var moderationChannel = guild.GetTextChannel(guildSettings.ModerationChannel);
            await moderationChannel.SendMessageAsync(embed : ModerationFormats.UnbanEmbed(unbannedUser, entry?.User));
        }
Esempio n. 6
0
        private async Task <RestAuditLogEntry> GetAuditLogEntry(SocketGuild guild)
        {
            IAsyncEnumerable <IReadOnlyCollection <RestAuditLogEntry> > auditLog  = guild.GetAuditLogsAsync(1);
            List <IReadOnlyCollection <RestAuditLogEntry> >             auditList = await auditLog.ToList();

            RestAuditLogEntry[] restAuditLogs = auditList[0].ToArray();
            RestAuditLogEntry   logEntry      = restAuditLogs[0];

            return(logEntry);
        }
Esempio n. 7
0
        /// <summary>
        ///     Fired whenever a user is banned from the server.
        /// </summary>
        private async Task UserBanned(SocketUser bannedUser, SocketGuild guild)
        {
            //Retrieve guild settings
            var guildSettings = _botContext.Guilds.AsNoTracking().FirstOrDefault(x => x.GuildId == guild.Id);

            if (guildSettings is null)
            {
                return;
            }

            //Check if guild has moderation channel enabled
            var moderationChannel = guild.GetTextChannel(guildSettings.ModerationChannel);

            if (moderationChannel == null)
            {
                return;
            }

            //Check if we have already sent a mod log by accessing the ban cache
            if (_banCache.TryGetValue(bannedUser.Id, out CacheModel value) && value.CacheType == CacheType.BanReject)
            {
                return;
            }

            //If we haven't sent a mod log already, set a cache entry for 5 seconds
            _banCache.Set(bannedUser.Id, new CacheModel(guild.Id), TimeSpan.FromSeconds(5));

            IEnumerable <RestAuditLogEntry> logs = null;

            try
            {
                logs = await guild.GetAuditLogsAsync(5).FlattenAsync();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

            var entry = logs?.FirstOrDefault(x => (x.Data as BanAuditLogData)?.Target.Id == bannedUser.Id);

            var caseId = await GenerateModCaseId(guild.Id);

            var modCase = entry != null
                ? new ModCase(entry.User, guild.Id, bannedUser, caseId, PunishmentType.Ban, entry.Reason)
                : new ModCase(guild.Id, bannedUser, caseId, PunishmentType.Ban);

            await _botContext.AddAsync(modCase);

            await _botContext.SaveChangesAsync();

            await SendModLog(moderationChannel, modCase);
        }
Esempio n. 8
0
        public async Task <string[]> GetchannelUpdates(ShardedCommandContext context, SocketTextChannel channel)
        {
            SocketGuild guild  = context.Guild;
            ActionType  action = ActionType.ChannelUpdated;

            string[] entries = { };
            IEnumerable <RestAuditLogEntry> auditSearch = await guild.GetAuditLogsAsync(int.MaxValue, null, null, null, action).FlattenAsync();

            foreach (RestAuditLogEntry AuditLogEntry in auditSearch)
            {
                if (AuditLogEntry.Data is ChannelUpdateAuditLogData data)
                {
                }
            }

            return(entries);
        }
Esempio n. 9
0
        private IUser GetBanningUserFromAuditLog(SocketGuild server, ulong bannedId)
        {
            IUser banningUser = null;

            server.GetAuditLogsAsync(5).ForEach(logEntries =>
            {
                foreach (var logEntry in logEntries)
                {
                    if (logEntry.Action == ActionType.Ban)
                    {
                        if ((logEntry.Data as BanAuditLogData).Target.Id == bannedId)
                        {
                            banningUser = logEntry.User;
                            break;
                        }
                    }
                }
            });
            return(banningUser);
        }
Esempio n. 10
0
        private async Task OnUserBanned(SocketUser user, SocketGuild guild)
        {
            Server server;

            if (!this.Client.Servers.ContainsKey(guild.Id) || (server = this.Client.Servers[guild.Id]) == null ||
                this.RecentlyBannedUserIDs.Contains(user.Id))
            {
                return;
            }

            BanAuditLogData   auditData  = null;
            RestAuditLogEntry auditEntry = null;

            if (guild.CurrentUser.GuildPermissions.ViewAuditLog)
            {
                await Task.Delay(500);

                try
                {
                    auditEntry = await guild.GetAuditLogsAsync(10)?.Flatten()?.FirstOrDefault(e => e != null && e.Action == ActionType.Ban && (auditData = e.Data as BanAuditLogData) != null && auditData.Target.Id == user.Id);

                    //One huge line because black magic from .NET Core?
                }
                catch (Exception) { }
            }

            string  reason = "unknown";
            RestBan ban    = await server.Guild.GetBanAsync(user);

            if (ban != null)
            {
                reason = ban.Reason;
                await this.Client.Events.AddBan(guild.Id, user.Id, TimeSpan.Zero, reason);
            }
            await LogBan(server, user.GetUsername(), user.Id, reason, "permanently", auditEntry?.User as SocketGuildUser);
        }
Esempio n. 11
0
        public static async Task AuditUpdate(SocketGuild guild)
        {
            foreach (SocketTextChannel chan in guild.TextChannels)
            {
                if (chan.Name.ToLower().Contains("security"))
                {
                    ConsolePrint("Security channel found in " + guild.Name);
                    IAsyncEnumerable <IReadOnlyCollection <RestAuditLogEntry> > auditLog  = guild.GetAuditLogsAsync(10);
                    List <IReadOnlyCollection <RestAuditLogEntry> >             auditList = await auditLog.ToList();

                    IAsyncEnumerable <IReadOnlyCollection <IMessage> > messages = chan.GetMessagesAsync(1);
                    List <IReadOnlyCollection <IMessage> >             msgList  = await messages.ToList();

                    IMessage mesg = null;
                    if (msgList[1].Count > 0)
                    {
                        mesg = msgList[1].ToArray()[0];// Newest Message
                    }
                    RestAuditLogEntry[] restAuditLogs = auditList[0].ToArray();
                    if (mesg != null)
                    {
                        if (mesg.Embeds.Count > 0)
                        {
                            if (restAuditLogs[0].Id.ToString() == mesg.Embeds.FirstOrDefault().Footer.Value.Text)
                            {
                                break;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    for (int i = restAuditLogs.Length - 1; i >= 0; i--)
                    {
                        if (mesg != null)
                        {
                            if (mesg.Embeds.Count > 0)
                            {
                                int dif = DateTimeOffset.Compare(mesg.Embeds.FirstOrDefault().Timestamp.Value, restAuditLogs[i].CreatedAt);
                                if (dif >= 0)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        RestAuditLogEntry logEntry = restAuditLogs[i];
                        bool         send          = false;
                        EmbedBuilder embed         = new EmbedBuilder();
                        string       adminUsername = "******" + logEntry.User + "**";
                        string       title         = "Server Report";
                        embed.WithTimestamp(logEntry.CreatedAt);
                        string msg = "";
                        if (logEntry.Action == ActionType.MemberRoleUpdated)
                        {
                            MemberRoleAuditLogData data = (MemberRoleAuditLogData)logEntry.Data;
                            string targetUsername       = "******" + data.Target + "** _(" + data.Target.Id + ")_";
                            string roles = "";
                            foreach (MemberRoleEditInfo role in data.Roles)
                            {
                                roles += string.Format(((role.Added) ? " Added role {0} to " : " Removed role {0} from "), "**_" + role.Name + "_**");
                            }

                            msg = adminUsername + roles + targetUsername;
                            embed.WithColor(new Color(255, 190, 0));
                            send = true;
                        }// end if log entry role updated
                        else if (logEntry.Action == ActionType.MemberUpdated)
                        {
                            MemberUpdateAuditLogData data = (MemberUpdateAuditLogData)logEntry.Data;
                            string targetUsername         = "******" + data.Target + "** _(" + data.Target.Id + ")_";
                            if (data.Before.Deaf != data.After.Deaf)
                            {
                                msg += string.Format(adminUsername + " {0} " + targetUsername + "\n", (data.After.Deaf.Value) ? "deafened" : "undeafened");
                            }

                            if (data.Before.Mute != data.After.Mute)
                            {
                                msg += string.Format(adminUsername + " {0} " + targetUsername + "\n", (data.After.Mute.Value) ? "muted" : "unmuted");
                            }


                            if (data.Before.Nickname != data.After.Nickname)
                            {
                                msg += string.Format(adminUsername + " changed {0}'s nickname from *{1}* to *{2}*\n", targetUsername,
                                                     (data.Before.Nickname == null) ? data.Target.Username : data.Before.Nickname,
                                                     (data.After.Nickname == null) ? data.Target.Username : data.After.Nickname);
                            }

                            Console.WriteLine(msg);
                            embed.WithColor(255, 255, 0);
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.Kick)
                        {
                            KickAuditLogData data           = (KickAuditLogData)logEntry.Data;
                            string           targetUsername = "******" + data.Target + "** _(" + data.Target.Id + ")_";
                            msg = targetUsername + " was kicked by " + adminUsername +
                                  "\nReason: " + logEntry.Reason;

                            embed.WithColor(new Color(255, 0, 0));
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.Ban)
                        {
                            BanAuditLogData data           = (BanAuditLogData)logEntry.Data;
                            string          targetUsername = "******" + data.Target + "** _(" + data.Target.Id + ")_";
                            msg = targetUsername + " was banned by " + adminUsername +
                                  "\nReason: " + logEntry.Reason;

                            embed.WithColor(new Color(255, 0, 0));
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.Unban)
                        {
                            UnbanAuditLogData data           = (UnbanAuditLogData)logEntry.Data;
                            string            targetUsername = "******" + data.Target + "** _(" + data.Target.Id + ")_";
                            msg = targetUsername + " was unbanned by " + adminUsername +
                                  "\nReason: " + logEntry.Reason;

                            embed.WithColor(new Color(255, 255, 0));
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.Prune)
                        {
                            PruneAuditLogData data = (PruneAuditLogData)logEntry.Data;
                            msg = adminUsername + " removed " + data.MembersRemoved + " users in a " + data.PruneDays + " day prune" +
                                  "\nReason: " + logEntry.Reason;

                            embed.WithColor(new Color(255, 0, 0));
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.MessageDeleted)
                        {
                            MessageDeleteAuditLogData data = (MessageDeleteAuditLogData)logEntry.Data;
                            msg = adminUsername + " deleted _" + data.MessageCount + "_ messages in **#" + guild.GetChannel(data.ChannelId).Name + "** channel";

                            embed.WithColor(new Color(255, 190, 0));
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.InviteCreated)
                        {
                            InviteCreateAuditLogData data = (InviteCreateAuditLogData)logEntry.Data;
                            string creatorUsername        = "******" + data.Creator + "** _(" + data.Creator.Id + ")_";
                            msg = creatorUsername + " created invite **" + data.Code + "**\n" +
                                  "Channel: " + guild.GetChannel(data.ChannelId).Name + "\n" +
                                  "Max Uses: " + data.MaxUses + "\n" +
                                  "Max Age: " + (data.MaxAge / 60 / 60 / 24) + "\n" +
                                  "Temporary: " + data.Temporary;

                            embed.WithColor(new Color(255, 255, 0));
                            send = true;
                        }
                        else if (logEntry.Action == ActionType.InviteDeleted)
                        {
                            InviteDeleteAuditLogData data = (InviteDeleteAuditLogData)logEntry.Data;
                            string creatorUsername        = "******" + data.Creator + "** _(" + data.Creator.Id + ")_";
                            msg = adminUsername + " deleted invite **" + data.Code + "** created by " + creatorUsername + "\n" +
                                  "Channel: " + guild.GetChannel(data.ChannelId).Name + "\n" +
                                  "Uses: " + data.Uses + "\n" +
                                  "Max Uses: " + data.MaxUses + "\n" +
                                  "Max Age: " + (data.MaxAge / 60 / 60 / 24) + "\n" +
                                  "Temporary: " + data.Temporary;

                            embed.WithColor(new Color(255, 255, 0));
                            send = true;
                        }
                        else
                        {
                            ConsolePrint("LE_Action: " + logEntry.Action + "; LE_Data: " + logEntry.Data.ToString() + "; ");
                        }
                        embed.WithAuthor(title, logEntry.User.GetAvatarUrl());
                        embed.WithDescription(msg);
                        embed.WithFooter(logEntry.Id.ToString());
                        if (send)
                        {
                            await chan.SendMessageAsync("", false, embed.Build());
                        }
                        if (send)
                        {
                            ConsolePrint("Sent " + embed.Description);
                        }
                    }//end restAuditLog loop
                    ConsolePrint("Finished Audit Log for " + guild.Name);
                    break;
                } // end if security channel
            }     // end for each text channel in guild
        }
Esempio n. 12
0
 public static async Task <List <RestAuditLogEntry> > GetAuditLogDataAsync(this SocketGuild guild, int count = 5, ActionType?actionType = null)
 {
     return((await guild.GetAuditLogsAsync(count, actionType: actionType).FlattenAsync().ConfigureAwait(false)).ToList());
 }
 public virtual IAsyncEnumerable <IReadOnlyCollection <RestAuditLogEntry> > GetAuditLogsAsync(int limit, RequestOptions?options = null, ulong?beforeId = null, ulong?userId = null, ActionType?actionType = null)
 {
     return(_socketGuild.GetAuditLogsAsync(limit, options, beforeId, userId, actionType));
 }
Esempio n. 14
0
        static Logging()
        {
            Program.Initialize += delegate(object?sender, DiscordSocketClient client)
            {
                client.ChannelDestroyed += delegate(SocketChannel channel)
                {
                    //Only currently needed for Logs at the moment
                    //Will try to remove the pair if it exists in the list
                    SaveHandler.LogSave.Remove(new KeyValuePair <ulong, ulong>(((SocketGuildChannel)channel).Guild.Id,
                                                                               channel.Id));
                    SaveHandler.LockdownSave[((SocketGuildChannel)channel).Guild.Id]
                    .Remove(((SocketGuildChannel)channel).Id);
                    return(Task.CompletedTask);
                };

                client.MessageUpdated += async delegate(Cacheable <IMessage, ulong> oldMessage, SocketMessage newMessage,
                                                        ISocketMessageChannel channel)
                {
                    if (!oldMessage.HasValue || newMessage.Author.IsBot)
                    {
                        return;
                    }

                    SocketGuild guild = ((SocketTextChannel)channel).Guild;
                    if (SaveHandler.LogSave.ContainsKey(guild.Id))
                    {
                        SocketTextChannel logChannel = guild.GetTextChannel(SaveHandler.LogSave[guild.Id]);
                        if (oldMessage.Value.Content != newMessage.Content)
                        {
                            EmbedBuilder builder = new EmbedBuilder
                            {
                                Color       = Color.Teal,
                                Title       = "Message Edited",
                                Url         = newMessage.GetJumpUrl(),
                                Description =
                                    $"From {newMessage.Author.Mention} in <#{channel.Id}>:\n**Before:**\n{oldMessage.Value.Content}\n**After:**\n{newMessage.Content}"
                            };

                            if (builder.Length > EmbedBuilder.MaxDescriptionLength)
                            {
                                string[] msgs = Misc.ConvertToDiscordSendable(builder.Description);
                                for (int i = 0; i < msgs.Length; i++)
                                {
                                    string msg = msgs[i];
                                    builder.Description = msg;
                                    if (msgs.Length - 1 == i)
                                    {
                                        builder.WithCurrentTimestamp();
                                    }

                                    await logChannel.SendMessageAsync(embed : builder.Build());

                                    if (i == 0)
                                    {
                                        builder.Title = null;
                                    }
                                }
                            }
                            else
                            {
                                builder.WithCurrentTimestamp();
                                await logChannel.SendMessageAsync(embed : builder.Build());
                            }
                        }
                    }
                };

                client.UserLeft += async delegate(SocketGuildUser user)
                {
                    if (SaveHandler.LogSave.ContainsKey(user.Guild.Id))
                    {
                        SocketTextChannel logChannel = user.Guild.GetTextChannel(SaveHandler.LogSave[user.Guild.Id]);
                        RestAuditLogEntry lastKick   = (await user.Guild.GetAuditLogsAsync(3, actionType: ActionType.Kick).FlattenAsync()).FirstOrDefault(l => (l.Data as KickAuditLogData).Target == user);
                        EmbedBuilder      builder    = new EmbedBuilder
                        {
                            Color = Color.Teal
                        };

                        if (lastKick != null)
                        {
                            string msg = $"You were kicked from {user.Guild.Name}";
                            if (lastKick.Reason != null)
                            {
                                msg += $"\nReason: {lastKick.Reason}";
                            }
                            try
                            {
                                await user.SendMessageAsync(msg);
                            }
                            catch { }
                            builder.WithCurrentTimestamp();
                            builder.Title       = "User Kicked";
                            builder.Description = $"{lastKick.User.Mention} kicked {user.Mention} | {user}";
                            if (lastKick.Reason != null)
                            {
                                builder.Description += $"\n__Reason__: \"{lastKick.Reason}\"";
                            }
                            await logChannel.SendMessageAsync(embed : builder.Build());
                        }

                        builder.WithCurrentTimestamp();
                        builder.Title       = "User Left";
                        builder.Description = $"{user.Mention} | {user}";
                        await logChannel.SendMessageAsync(embed : builder.Build());
                    }
                };

                client.UserBanned += async delegate(SocketUser user, SocketGuild guild)
                {
                    if (SaveHandler.LogSave.ContainsKey(guild.Id))
                    {
                        RestAuditLogEntry lastBan =
                            (await guild.GetAuditLogsAsync(3, actionType: ActionType.Ban).FlattenAsync()).FirstOrDefault(l => (l.Data as BanAuditLogData).Target == user);
                        if (lastBan != null)
                        {
                            string msg = $"You were banned from {guild.Name}";
                            if (lastBan.Reason != null)
                            {
                                msg += $"\nReason: {lastBan.Reason}";
                            }
                            try
                            {
                                await user.SendMessageAsync(msg);
                            }
                            catch { }

                            SocketTextChannel logChannel = guild.GetTextChannel(SaveHandler.LogSave[guild.Id]);
                            EmbedBuilder      builder    = new EmbedBuilder
                            {
                                Color       = Color.Teal,
                                Title       = "User Banned",
                                Description = $"{lastBan.User.Mention} banned {user.Mention} | {user}"
                            };
                            builder.WithCurrentTimestamp();
                            if (!string.IsNullOrWhiteSpace(lastBan.Reason))
                            {
                                builder.Description += $"\n__Reason__: \"{lastBan.Reason}\"";
                            }
                            await logChannel.SendMessageAsync(embed : builder.Build());
                        }
                    }
                };
                client.MessageDeleted +=
                    async delegate(Cacheable <IMessage, ulong> message, ISocketMessageChannel channel)
                {
                    if (!message.HasValue || message.Value.Author.IsBot)
                    {
                        return;
                    }

                    SocketGuild guild = ((SocketGuildChannel)channel).Guild;
                    if (SaveHandler.LogSave.ContainsKey(guild.Id))
                    {
                        SocketTextChannel logChannel = guild.GetTextChannel(SaveHandler.LogSave[guild.Id]);
                        if (logChannel.Id != channel.Id &&
                            (!string.IsNullOrWhiteSpace(message.Value.Content) || message.Value.Attachments.Any()))
                        {
                            EmbedBuilder builder = new EmbedBuilder
                            {
                                Description = "",
                                Color       = Color.Teal,
                                Title       = "Message Deleted",
                            };
                            RestAuditLogEntry messageDeleted = (await guild.GetAuditLogsAsync(3, actionType: ActionType.MessageDeleted).FlattenAsync()).FirstOrDefault(l => (l.Data as MessageDeleteAuditLogData).Target.Id == message.Value.Author.Id);

                            if (!string.IsNullOrWhiteSpace(message.Value.Content))
                            {
                                builder.Description += $"From {message.Value.Author.Mention}, in <#{channel.Id}>";
                            }

                            if (messageDeleted != null)
                            {
                                builder.Description += $", deleted by {messageDeleted.User.Mention}";
                            }

                            builder.Description += $":\n{message.Value.Content}";

                            if (message.Value.Attachments.Any())
                            {
                                builder.Description += "\n\nAttachments:\n";
                                foreach (IAttachment attachment in message.Value.Attachments)
                                {
                                    builder.Description += $"{attachment.Url}\n";
                                }
                            }

                            if (builder.Length > EmbedBuilder.MaxDescriptionLength)
                            {
                                string[] msgs = Misc.ConvertToDiscordSendable(builder.Description);
                                for (int i = 0; i < msgs.Length; i++)
                                {
                                    string msg = msgs[i];
                                    builder.Description = msg;
                                    if (msgs.Length - 1 == i)
                                    {
                                        builder.WithCurrentTimestamp();
                                    }

                                    await logChannel.SendMessageAsync(embed : builder.Build());

                                    if (i == 0)
                                    {
                                        builder.Title = null;
                                    }
                                }
                            }
                            else
                            {
                                builder.WithCurrentTimestamp();
                                await logChannel.SendMessageAsync(embed : builder.Build());
                            }
                        }
                    }
                };

                client.GuildMemberUpdated += async delegate(SocketGuildUser before, SocketGuildUser after)
                {
                    if (before.IsBot)
                    {
                        return;
                    }

                    if (SaveHandler.LogSave.ContainsKey(after.Guild.Id))
                    {
                        SocketTextChannel logChannel = after.Guild.GetTextChannel(SaveHandler.LogSave[after.Guild.Id]);
                        if (logChannel != null)
                        {
                            if (before.Nickname != after.Nickname)
                            {
                                EmbedBuilder builder = new EmbedBuilder
                                {
                                    Color = Color.Teal
                                };
                                builder.WithCurrentTimestamp();
                                if (string.IsNullOrWhiteSpace(after.Nickname))
                                {
                                    builder.Title       = "Nickname Removal";
                                    builder.Description = $"{after.Mention}:\n`{before.Nickname}` -> `None`";
                                }
                                else if (string.IsNullOrWhiteSpace(before.Nickname))
                                {
                                    builder.Title       = "Nickname Changed";
                                    builder.Description = $"{after.Mention}:\n`None` -> `{after.Nickname}`";
                                }
                                else
                                {
                                    builder.Title       = "Nickname Changed";
                                    builder.Description =
                                        $"{after.Mention}:\n`{before.Nickname}` -> `{after.Nickname}`";
                                }

                                await logChannel.SendMessageAsync(embed : builder.Build());
                            }
                        }
                    }
                };
            };
        }