public DiscordEmbed Build(LaunchNotification launchNotification) { var oldLaunchState = launchNotification.OldLaunchState; var launch = launchNotification.NewLaunchState; var embed = new DiscordEmbedBuilder { Color = new DiscordColor(Constants.EmbedColor), Thumbnail = new DiscordEmbedBuilder.EmbedThumbnail { Url = launch.Links.Patch.Large ?? Constants.SpaceXLogoImage } }; var launchTme = launch.DateUtc ?? DateTime.MinValue; var now = DateTime.Now.ToUniversalTime(); var timeLeft = (launchTme - now).TotalMinutes; switch (launchNotification.Type) { case LaunchNotificationType.Reminder: { var timeLeftDescription = timeLeft > 60 ? Math.Ceiling(timeLeft / 60) + " hours" : Math.Ceiling(timeLeft) + " minutes"; var descriptionBuilder = new StringBuilder(); descriptionBuilder.Append($"**{timeLeftDescription}** to launch **{launch.Name}**! "); descriptionBuilder.Append($"Type `e!NextLaunch` to get more information."); embed.Title = ":rocket: Launch is coming!"; embed.Description = descriptionBuilder.ToString(); break; } case LaunchNotificationType.Scrub: { var oldLaunchDate = DateFormatter.GetDateStringWithPrecision( oldLaunchState.DateUtc ?? DateTime.MinValue, oldLaunchState.DatePrecision ?? DatePrecision.Year, true, true, true); var newLaunchDate = DateFormatter.GetDateStringWithPrecision( launch.DateUtc ?? DateTime.MinValue, launch.DatePrecision ?? DatePrecision.Year, true, true, true); var descriptionBuilder = new StringBuilder(); descriptionBuilder.Append($"**{launch.Name}** launch time has been changed from "); descriptionBuilder.Append($"**{oldLaunchDate}** to "); descriptionBuilder.Append($"**{newLaunchDate}**. "); descriptionBuilder.Append($"Type `e!NextLaunch` to get more information."); embed.Title = ":warning: Scrub!"; embed.Description = descriptionBuilder.ToString(); break; } case LaunchNotificationType.NewTarget: { var nextLaunchDate = DateFormatter.GetDateStringWithPrecision( launchNotification.NewLaunchState.DateUtc ?? DateTime.MinValue, launchNotification.NewLaunchState.DatePrecision ?? DatePrecision.Year, true, true, true); var descriptionBuilder = new StringBuilder(); descriptionBuilder.Append($"The next launch will be **{launchNotification.NewLaunchState.Name}** on **{nextLaunchDate}**. "); descriptionBuilder.Append($"Type `e!NextLaunch` to get more information."); embed.Title = ":rocket: New target!"; embed.Description = descriptionBuilder.ToString(); break; } } embed.AddField("\u200b", "*Click the reaction below to subscribe this flight and be notified on DM 10 minutes before the launch.*"); return(embed); }
private async void LaunchNotificationsOnLaunchNotificationAsync(object sender, LaunchNotification launchNotification) { var embed = _launchNotificationEmbedBuilder.Build(launchNotification); var channels = _subscriptionsService.GetSubscribedChannels(SubscriptionType.NextLaunch); var launchTime = launchNotification.NewLaunchState.DateUtc ?? DateTime.MinValue; if (launchTime == DateTime.MinValue) { return; } var timeLeft = (launchTime - DateTime.Now.ToUniversalTime()).TotalMinutes; var stopwatch = Stopwatch.StartNew(); foreach (var channelData in channels) { try { var channel = await Bot.Client.GetChannelAsync(ulong.Parse(channelData.ChannelId)); var sentMessage = await channel.SendMessageAsync(string.Empty, false, embed); await sentMessage.CreateReactionAsync(DiscordEmoji.FromName(Bot.Client, ":regional_indicator_s:")); await _launchNotificationsService.AddMessageToSubscribe(channel, sentMessage); if (launchNotification.Type == LaunchNotificationType.Reminder && timeLeft < 60 && launchNotification.NewLaunchState.Links.Webcast != null) { await channel.SendMessageAsync($"**YouTube stream:** {launchNotification.NewLaunchState.Links.Webcast}"); } } catch (UnauthorizedException ex) { await _subscriptionsService.RemoveAllSubscriptionsFromChannelAsync(ulong.Parse(channelData.ChannelId)); try { var guild = await Bot.Client.GetGuildAsync(ulong.Parse(channelData.GuildId)); var guildOwner = guild.Owner; _logger.Warn($"No permissions to send message to channel [{channelData.ChannelId}], " + $"removing all subscriptions and sending message to {guildOwner.Username} [{guildOwner.Id}]"); _logger.Warn($"JSON: {ex.JsonMessage}"); var ownerDm = await guildOwner.CreateDmChannelAsync(); var errorEmbed = _launchNotificationEmbedBuilder.BuildUnauthorizedError(); await ownerDm.SendMessageAsync(embed : errorEmbed); } catch (Exception e) { _logger.Fatal(e); } } catch (NotFoundException ex) { _logger.Warn($"Channel [{channelData.ChannelId}] not found, removing all subscriptions"); _logger.Warn($"JSON: {ex.JsonMessage}"); await _subscriptionsService.RemoveAllSubscriptionsFromChannelAsync(ulong.Parse(channelData.ChannelId)); } catch (Exception ex) { _logger.Error(ex, $"Can't send launch notification to the channel with id [{channelData.ChannelId}]"); } } _logger.Info($"Launch notifications sent to {channels.Count} channels " + $"in {stopwatch.Elapsed.TotalSeconds:0.0} seconds"); }