コード例 #1
0
        public async Task Consume(ConsumeContext <IStreamOnline> context)
        {
            ILiveBotStream  stream  = context.Message.Stream;
            ILiveBotMonitor monitor = _monitors.Where(i => i.ServiceType == stream.ServiceType).FirstOrDefault();

            if (monitor == null)
            {
                return;
            }

            ILiveBotUser user = stream.User ?? await monitor.GetUserById(stream.UserId);

            ILiveBotGame game = stream.Game ?? await monitor.GetGame(stream.GameId);

            Expression <Func <StreamGame, bool> > templateGamePredicate = (i => i.ServiceType == stream.ServiceType && i.SourceId == "0");
            var templateGame = await _work.GameRepository.SingleOrDefaultAsync(templateGamePredicate);

            var streamUser = await _work.UserRepository.SingleOrDefaultAsync(i => i.ServiceType == stream.ServiceType && i.SourceID == user.Id);

            var streamSubscriptions = await _work.SubscriptionRepository.FindAsync(i => i.User == streamUser);

            StreamGame streamGame;

            if (game.Id == "0" || string.IsNullOrEmpty(game.Id))
            {
                if (templateGame == null)
                {
                    StreamGame newStreamGame = new StreamGame
                    {
                        ServiceType  = stream.ServiceType,
                        SourceId     = "0",
                        Name         = "[Not Set]",
                        ThumbnailURL = ""
                    };
                    await _work.GameRepository.AddOrUpdateAsync(newStreamGame, templateGamePredicate);

                    templateGame = await _work.GameRepository.SingleOrDefaultAsync(templateGamePredicate);
                }
                streamGame = templateGame;
            }
            else
            {
                StreamGame newStreamGame = new StreamGame
                {
                    ServiceType  = stream.ServiceType,
                    SourceId     = game.Id,
                    Name         = game.Name,
                    ThumbnailURL = game.ThumbnailURL
                };
                await _work.GameRepository.AddOrUpdateAsync(newStreamGame, i => i.ServiceType == stream.ServiceType && i.SourceId == stream.GameId);

                streamGame = await _work.GameRepository.SingleOrDefaultAsync(i => i.ServiceType == stream.ServiceType && i.SourceId == stream.GameId);
            }

            if (streamSubscriptions.Count() == 0)
            {
                return;
            }

            foreach (StreamSubscription streamSubscription in streamSubscriptions)
            {
                if (streamSubscription.DiscordGuild == null || streamSubscription.DiscordChannel == null)
                {
                    await _work.SubscriptionRepository.RemoveAsync(streamSubscription.Id);

                    continue;
                }

                var discordChannel = streamSubscription.DiscordChannel;
                var discordRole    = streamSubscription.DiscordRole;
                var discordGuild   = streamSubscription.DiscordGuild;

                var guild = _client.GetGuild(streamSubscription.DiscordGuild.DiscordId);
                SocketTextChannel channel = (SocketTextChannel)_client.GetChannel(streamSubscription.DiscordChannel.DiscordId);;

                string notificationMessage = NotificationHelpers.GetNotificationMessage(stream: stream, subscription: streamSubscription, user: user, game: game);
                Embed  embed = NotificationHelpers.GetStreamEmbed(stream: stream, user: user, game: game);

                StreamNotification newStreamNotification = new StreamNotification
                {
                    ServiceType = stream.ServiceType,
                    Success     = false,
                    Message     = notificationMessage,

                    User_SourceID    = streamUser.SourceID,
                    User_Username    = streamUser.Username,
                    User_DisplayName = streamUser.DisplayName,
                    User_AvatarURL   = streamUser.AvatarURL,
                    User_ProfileURL  = streamUser.ProfileURL,

                    Stream_SourceID     = stream.Id,
                    Stream_Title        = stream.Title,
                    Stream_StartTime    = stream.StartTime,
                    Stream_ThumbnailURL = stream.ThumbnailURL,
                    Stream_StreamURL    = stream.StreamURL,

                    Game_SourceID     = streamGame?.SourceId,
                    Game_Name         = streamGame?.Name,
                    Game_ThumbnailURL = streamGame?.ThumbnailURL,

                    DiscordGuild_DiscordId = discordGuild.DiscordId,
                    DiscordGuild_Name      = discordGuild.Name,

                    DiscordChannel_DiscordId = discordChannel.DiscordId,
                    DiscordChannel_Name      = discordChannel.Name,

                    DiscordRole_DiscordId = discordRole == null ? 0 : discordRole.DiscordId,
                    DiscordRole_Name      = discordRole?.Name
                };

                Expression <Func <StreamNotification, bool> > notificationPredicate = (i =>
                                                                                       i.User_SourceID == newStreamNotification.User_SourceID &&
                                                                                       i.Stream_SourceID == newStreamNotification.Stream_SourceID &&
                                                                                       i.Stream_StartTime == newStreamNotification.Stream_StartTime &&
                                                                                       i.DiscordGuild_DiscordId == newStreamNotification.DiscordGuild_DiscordId &&
                                                                                       i.DiscordChannel_DiscordId == newStreamNotification.DiscordChannel_DiscordId &&
                                                                                       i.Game_SourceID == newStreamNotification.Game_SourceID
                                                                                       );

                Expression <Func <StreamNotification, bool> > previousNotificationPredicate = (i =>
                                                                                               i.User_SourceID == streamUser.SourceID &&
                                                                                               i.DiscordGuild_DiscordId == discordGuild.DiscordId &&
                                                                                               i.DiscordChannel_DiscordId == discordChannel.DiscordId
                                                                                               );

                var previousNotifications = await _work.NotificationRepository.FindAsync(previousNotificationPredicate);

                previousNotifications = previousNotifications.Where(i =>
                                                                    stream.StartTime.Subtract(i.Stream_StartTime).TotalMinutes <= 60 && // If within an hour of their last start time
                                                                    i.Success == true // Only pull Successful notifications
                                                                    );

                // If there is already 1 or more notifications that were successful in the past hour
                // mark this current one as a success
                if (previousNotifications.Count() > 0)
                {
                    newStreamNotification.Success = true;
                }

                // Do some checks to see if the channel can be found. If not, just mark as a success
                // and move on
                int channelCheckCount = 0;
                while (channel == null && _client.LoginState == LoginState.LoggedIn)
                {
                    if (channelCheckCount >= 12) // Ends up being 10 seconds
                    {
                        string errorMessage = $"Unable to get a Discord Channel for {streamSubscription.DiscordChannel.DiscordId} after {channelCheckCount} attempts";
                        Log.Error(errorMessage);
                        newStreamNotification.Success = true;
                        var streamSubscriptionJSON = JsonConvert.SerializeObject(streamSubscription);
                        newStreamNotification.LogMessage = $"{errorMessage}\n{streamSubscriptionJSON}";
                        break;
                    }
                    channel            = (SocketTextChannel)_client.GetChannel(streamSubscription.DiscordChannel.DiscordId);
                    channelCheckCount += 1;
                    await Task.Delay(TimeSpan.FromSeconds(5)); // Delay check for 5 seconds
                }

                await _work.NotificationRepository.AddOrUpdateAsync(newStreamNotification, notificationPredicate);

                StreamNotification streamNotification = await _work.NotificationRepository.SingleOrDefaultAsync(notificationPredicate);

                // If the current notification was marked as a success, end processing
                if (streamNotification.Success == true)
                {
                    continue;
                }

                try
                {
                    var discordMessage = await channel.SendMessageAsync(text : notificationMessage, embed : embed);

                    streamNotification.DiscordMessage_DiscordId = discordMessage.Id;
                    streamNotification.Success = true;
                    await _work.NotificationRepository.UpdateAsync(streamNotification);
                }
                catch (Exception e)
                {
                    if (e is HttpException)
                    {
                        HttpException discordError = (HttpException)e;
                        // You lack permissions to perform that action
                        if (discordError.DiscordCode == 50013 || discordError.DiscordCode == 50001)
                        {
                            // I'm tired of seeing errors for Missing Permissions
                            continue;
                        }
                    }
                    else
                    {
                        Log.Error($"Error sending notification for {streamNotification.Id} {streamNotification.ServiceType} {streamNotification.User_Username} {streamNotification.DiscordGuild_DiscordId} {streamNotification.DiscordChannel_DiscordId} {streamNotification.DiscordRole_DiscordId} {streamNotification.Message}\n{e}");
                    }
                }
            }
        }
コード例 #2
0
        public async Task Consume(ConsumeContext <IStreamUpdate> context)
        {
            ILiveBotStream  stream  = context.Message.Stream;
            ILiveBotMonitor monitor = _monitors.Where(i => i.ServiceType == stream.ServiceType).FirstOrDefault();

            if (monitor == null)
            {
                return;
            }

            ILiveBotUser user = stream.User ?? await monitor.GetUserById(stream.UserId);

            ILiveBotGame game = stream.Game ?? await monitor.GetGame(stream.GameId);

            Expression <Func <StreamGame, bool> > templateGamePredicate = (i => i.ServiceType == stream.ServiceType && i.SourceId == "0");
            var templateGame = await _work.GameRepository.SingleOrDefaultAsync(templateGamePredicate);

            var streamUser = await _work.UserRepository.SingleOrDefaultAsync(i => i.ServiceType == stream.ServiceType && i.SourceID == user.Id);

            var streamSubscriptions = await _work.SubscriptionRepository.FindAsync(i => i.User == streamUser);

            StreamGame streamGame;

            if (game.Id == "0" || string.IsNullOrEmpty(game.Id))
            {
                if (templateGame == null)
                {
                    StreamGame newStreamGame = new StreamGame
                    {
                        ServiceType  = stream.ServiceType,
                        SourceId     = "0",
                        Name         = "[Not Set]",
                        ThumbnailURL = ""
                    };
                    await _work.GameRepository.AddOrUpdateAsync(newStreamGame, templateGamePredicate);

                    templateGame = await _work.GameRepository.SingleOrDefaultAsync(templateGamePredicate);
                }
                streamGame = templateGame;
            }
            else
            {
                StreamGame newStreamGame = new StreamGame
                {
                    ServiceType  = stream.ServiceType,
                    SourceId     = game.Id,
                    Name         = game.Name,
                    ThumbnailURL = game.ThumbnailURL
                };
                await _work.GameRepository.AddOrUpdateAsync(newStreamGame, i => i.ServiceType == stream.ServiceType && i.SourceId == stream.GameId);

                streamGame = await _work.GameRepository.SingleOrDefaultAsync(i => i.ServiceType == stream.ServiceType && i.SourceId == stream.GameId);
            }

            if (streamSubscriptions.Count() == 0)
            {
                return;
            }

            List <StreamSubscription> unsentSubscriptions = new List <StreamSubscription>();

            foreach (StreamSubscription streamSubscription in streamSubscriptions)
            {
                if (streamSubscription.DiscordGuild == null || streamSubscription.DiscordChannel == null)
                {
                    await _work.SubscriptionRepository.RemoveAsync(streamSubscription.Id);

                    continue;
                }

                var discordChannel = streamSubscription.DiscordChannel;
                var discordRole    = streamSubscription.DiscordRole;
                var discordGuild   = streamSubscription.DiscordGuild;

                Expression <Func <StreamNotification, bool> > previousNotificationPredicate = (i =>
                                                                                               i.User_SourceID == streamUser.SourceID &&
                                                                                               i.DiscordGuild_DiscordId == discordGuild.DiscordId &&
                                                                                               i.DiscordChannel_DiscordId == discordChannel.DiscordId &&
                                                                                               i.Stream_StartTime == stream.StartTime &&
                                                                                               i.Stream_SourceID == stream.Id &&
                                                                                               i.Success == true
                                                                                               );

                var previousNotifications = await _work.NotificationRepository.FindAsync(previousNotificationPredicate);

                if (previousNotifications.Count() > 0)
                {
                    continue;
                }

                unsentSubscriptions.Add(streamSubscription);
            }

            if (unsentSubscriptions.Count() > 0)
            {
                await _bus.Publish <IStreamOnline>(new { Stream = stream });
            }
        }