/// <summary> /// Creates a modmail thread with the given user and responds in the given thread with a link to the newly created channel. /// </summary> /// <param name="user">The <see cref="Discord.IUser"> to create the channel for</param> /// <param name="channel">The <see cref="Discord.ISocketMessageChannel"> in which the response should be posted to</param> /// <returns>The <see cref="Discord.Rest.RestChannel"> newly created channel</returns> public static async Task <RestTextChannel> ContactUser(IUser user, ISocketMessageChannel channel, bool createNote) { using (var db = new Database()) { var existingUser = db.Users.AsQueryable().Where(us => us.Id == user.Id).FirstOrDefault(); if (existingUser == null) { var newUser = new UserBuilder(user.Id).Build(); db.Users.Add(newUser); } else { existingUser.ModMailMuted = false; } db.SaveChanges(); } var createdChannel = await CreateModMailThread(user); ModMailThread createdModMailThread; using (var db = new Database()) { createdModMailThread = db.ModMailThreads.AsQueryable().Where(th => th.ChannelId == createdChannel.Id).First(); } await createdChannel.SendMessageAsync(embed : ModMailEmbedHandler.GetUserInfoHeader(createdModMailThread)); if (createNote) { var embedContainingLink = ModMailEmbedHandler.GetThreadHasBeendCreatedEmbed(createdModMailThread); await channel.SendMessageAsync(embed : embedContainingLink); } // we need to return the channel, because we *directly* need the channel after wards, and loading the channel by id again // resulted in null return(createdChannel); }
/// <summary> /// Creates a modmail thread for a user. This is initiated by the user when the user sends the bot a DM. /// This includes: /// Creating the channel, creating the records in the db and pinging staff /// </summary> /// <param name="message">The <see cref="Discord.WebSocket.SocketMessage"> object containing the message send by the user to initiate this</param> /// <returns>Task</returns> public async Task CreateModmailThread(SocketMessage message) { var userFromCache = Global.ModMailThreads.Where(th => th.UserId == message.Author.Id).FirstOrDefault(); if (userFromCache != null && userFromCache.ThreadUser.ModMailMuted && userFromCache.ThreadUser.ModMailMutedUntil > DateTime.Now) { if (!userFromCache.ThreadUser.ModMailMutedReminded) { await message.Channel.SendMessageAsync($"You are unable to contact modmail until {Extensions.FormatDateTime(userFromCache.ThreadUser.ModMailMutedUntil)}."); using (var db = new Database()) { db.Users.AsQueryable().Where(us => us.Id == message.Author.Id).First().ModMailMutedReminded = true; db.SaveChanges(); } Global.ReloadModmailThreads(); } return; } using (var db = new Database()) { var user = db.Users.AsQueryable().Where(us => us.Id == message.Author.Id).FirstOrDefault(); if (user == null) { var newUser = new UserBuilder(message.Author.Id).Build(); db.Users.Add(newUser); db.SaveChanges(); } } int pastThreads = 0; using (var db = new Database()) { pastThreads = db.ModMailThreads.AsQueryable().Where(ch => ch.UserId == message.Author.Id).Count(); } // when I tried to load the channel via getTextChannel, I got null in return, my only guess is that the channel // did not get peristent completely, so it did not find it // if we return the directly returned channel it worked var channel = await CreateModMailThread(message.Author); var guild = Global.Bot.GetGuild(Global.ServerID); await channel.SendMessageAsync(embed : ModMailEmbedHandler.GetUserInformation(pastThreads, message.Author)); ModMailThread modmailThread; using (var db = new Database()) { modmailThread = db.ModMailThreads.AsQueryable().Where(th => th.ChannelId == channel.Id).First(); } await channel.SendMessageAsync(embed : ModMailEmbedHandler.GetUserInfoHeader(modmailThread)); var channelMessage = await channel.SendMessageAsync(embed : ModMailEmbedHandler.GetReplyEmbed(message, "Initial message from user")); AddModMailMessage(channel.Id, channelMessage, null, message.Author.Id); await message.Author.SendMessageAsync(embed : ModMailEmbedHandler.GetInitialUserReply(message)); var modQueue = guild.GetTextChannel(Global.PostTargets[PostTarget.MODMAIL_NOTIFICATION]); var staffRole = guild.GetRole(Global.Roles["staff"]); await staffRole.ModifyAsync(x => x.Mentionable = true); try { await modQueue.SendMessageAsync(staffRole.Mention, embed : ModMailEmbedHandler.GetModqueueNotificationEmbed(message.Author, modmailThread)); } finally { await staffRole.ModifyAsync(x => x.Mentionable = false); } }