using SharedClasses.SharedModels; using System.Net.Http; using static System.Net.Mime.MediaTypeNames; using System.Text.Json; using System.Text; using Lieb.Models.GuildWars2.Raid; using Microsoft.EntityFrameworkCore; namespace Lieb.Data { public class DiscordService { private readonly IHttpClientFactory _httpClientFactory; private readonly IDbContextFactory _contextFactory; private readonly JsonSerializerOptions _serializerOptions; public DiscordService(IHttpClientFactory httpClientFactory, IDbContextFactory contextFactory) { _httpClientFactory = httpClientFactory; _contextFactory = contextFactory; _serializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; } public async Task PostRaidMessage(int raidId) { using var context = _contextFactory.CreateDbContext(); Raid raid = context.Raids .Include(r => r.Roles) .Include(r => r.SignUps) .ThenInclude(s => s.LiebUser) .Include(r => r.SignUps) .ThenInclude(s => s.GuildWars2Account) .Include(r => r.SignUps) .ThenInclude(s => s.RaidRole) .Include(r => r.DiscordRaidMessages) .FirstOrDefault(r => r.RaidId == raidId); await PostRaidMessage(raid); } public async Task PostRaidMessage(Raid raid) { var httpClient = _httpClientFactory.CreateClient(Constants.HttpClientName); ApiRaid apiRaid = ConvertRaid(raid); var raidItemJson = new StringContent( JsonSerializer.Serialize(apiRaid), Encoding.UTF8, Application.Json); string json = JsonSerializer.Serialize(apiRaid); var httpResponseMessage = await httpClient.PostAsync("raid/PostRaidMessage", raidItemJson); if (httpResponseMessage.IsSuccessStatusCode) { using var contentStream = await httpResponseMessage.Content.ReadAsStreamAsync(); ApiRaid returnedRaid = await JsonSerializer.DeserializeAsync(contentStream, _serializerOptions); await UpdateDiscordMessages(returnedRaid.DisocrdMessages, raid); } } public async Task DeleteRaidMessages(Raid raid) { await DeleteRaidMessages(raid.DiscordRaidMessages); } public async Task DeleteRaidMessages(IEnumerable messages) { var httpClient = _httpClientFactory.CreateClient(Constants.HttpClientName); IEnumerable apiMessages = ConvertMessages(messages); var messageItemJson = new StringContent( JsonSerializer.Serialize(apiMessages), Encoding.UTF8, Application.Json); var httpResponseMessage = await httpClient.PostAsync("raid/DeleteRaidMessage", messageItemJson); httpResponseMessage.EnsureSuccessStatusCode(); } public async Task> GetServers() { try { var httpClient = _httpClientFactory.CreateClient(Constants.HttpClientName); var httpResponseMessage = await httpClient.GetAsync("raid/GetServers"); if (httpResponseMessage.IsSuccessStatusCode) { using var contentStream = await httpResponseMessage.Content.ReadAsStreamAsync(); return await JsonSerializer.DeserializeAsync>(contentStream, _serializerOptions); } } catch(Exception e) { } return new List(); } public async Task SendUserReminder(RaidReminder reminder) { using var context = _contextFactory.CreateDbContext(); var httpClient = _httpClientFactory.CreateClient(Constants.HttpClientName); Raid raid = context.Raids .Include(r => r.SignUps) .ThenInclude(s => s.LiebUser) .FirstOrDefault(r => r.RaidId == reminder.RaidId); if(raid == null) return; ApiUserReminder apiReminder = ConvertUserReminder(reminder, raid); var raidItemJson = new StringContent( JsonSerializer.Serialize(apiReminder), Encoding.UTF8, Application.Json); var httpResponseMessage = await httpClient.PostAsync("raid/SendUserReminder", raidItemJson); if (httpResponseMessage.IsSuccessStatusCode) { reminder.Sent = true; context.Update(reminder); await context.SaveChangesAsync(); } } public async Task SendChannelReminder(RaidReminder reminder) { var httpClient = _httpClientFactory.CreateClient(Constants.HttpClientName); ApiChannelReminder apiReminder = ConvertChannelReminder(reminder); var raidItemJson = new StringContent( JsonSerializer.Serialize(apiReminder), Encoding.UTF8, Application.Json); var httpResponseMessage = await httpClient.PostAsync("raid/SendChannelReminder", raidItemJson); if (httpResponseMessage.IsSuccessStatusCode) { reminder.Sent = true; using var context = _contextFactory.CreateDbContext(); context.Update(reminder); await context.SaveChangesAsync(); } } private async Task UpdateDiscordMessages(IEnumerable messages, Raid raid) { foreach(ApiRaid.DiscordMessage message in messages) { if(raid.DiscordRaidMessages.Where(m => m.DiscordRaidMessageId == message.WebsiteDatabaseId).Any()) { raid.DiscordRaidMessages.FirstOrDefault(m => m.DiscordRaidMessageId == message.WebsiteDatabaseId).DiscordMessageId = message.MessageId; } } using var context = _contextFactory.CreateDbContext(); context.Update(raid.DiscordRaidMessages); await context.SaveChangesAsync(); } private ApiRaid ConvertRaid(Raid raid) { ApiRaid apiRaid = new ApiRaid(){ Title = raid.Title, Description = raid.Description, Guild = raid.Guild, Organizer = raid.Organizer, VoiceChat = raid.VoiceChat, StartTimeUTC = raid.StartTimeUTC, EndTimeUTC = raid.EndTimeUTC, RaidId = raid.RaidId }; apiRaid.DisocrdMessages = ConvertMessages(raid.DiscordRaidMessages); apiRaid.Roles = new List(); foreach(RaidRole role in raid.Roles) { ApiRaid.Role apiRole = new ApiRaid.Role(){ Description = role.Description, Name = role.Name, Spots = role.Spots }; apiRole.Users = new List(); foreach(RaidSignUp signUp in raid.SignUps.Where(x => x.RaidRoleId == role.RaidRoleId)) { apiRole.Users.Add(new ApiRaid.Role.User(){ AccountName = signUp.GuildWars2Account.AccountName, Status = signUp.SignUpType.ToString(), UserName = signUp.LiebUser.Name }); } apiRaid.Roles.Add(apiRole); } return apiRaid; } private List ConvertMessages(IEnumerable messages) { List apiMessages = new List(); foreach(DiscordRaidMessage message in messages) { apiMessages.Add(new ApiRaid.DiscordMessage(){ ChannelId = message.DiscordChannelId, GuildId = message.DiscordGuildId, MessageId = message.DiscordMessageId, WebsiteDatabaseId = message.DiscordRaidMessageId }); } return apiMessages; } private ApiUserReminder ConvertUserReminder(RaidReminder reminder, Raid raid) { ApiUserReminder apiReminder = new ApiUserReminder() { Message = reminder.Message }; apiReminder.UserIds = new List(); foreach(RaidSignUp signUp in raid.SignUps) { apiReminder.UserIds.Add(signUp.LiebUserId); } return apiReminder; } private ApiChannelReminder ConvertChannelReminder(RaidReminder reminder) { return new ApiChannelReminder() { DiscordServerId = reminder.DiscordServerId, DiscordChannelId = reminder.DiscordChannelId, Message = reminder.Message }; } } }