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);
        }
Example #2
0
        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");
        }