Ejemplo n.º 1
0
        public async Task GetMonitorService(string serviceName)
        {
            ServiceEnum     serviceEnum = (ServiceEnum)Enum.Parse(typeof(ServiceEnum), serviceName.ToUpper());
            ILiveBotMonitor monitor     = _monitors.Where(m => m.ServiceType == serviceEnum).First();

            await ReplyAsync($"Loaded: {monitor.ServiceType}");
        }
Ejemplo n.º 2
0
        public async Task <RuntimeResult> MonitorStop_RequestURL()
        {
            string profileURL = await _RequestStreamUser();

            if (profileURL == null)
            {
                return(MonitorResult.FromError($"{Context.Message.Author.Mention}, Please provide a valid Stream URL for me to stop monitoring"));
            }
            ILiveBotMonitor monitor = _GetServiceMonitor(profileURL);
            ILiveBotUser    user    = await monitor.GetUser(profileURL : profileURL);

            return(await MonitorStop(user));
        }
Ejemplo n.º 3
0
        public async Task <RuntimeResult> MonitorStop(ILiveBotUser user)
        {
            ILiveBotMonitor monitor = _GetServiceMonitor(user);

            DiscordGuild discordGuild = new DiscordGuild
            {
                DiscordId = Context.Guild.Id,
                Name      = Context.Guild.Name,
                IconUrl   = Context.Guild.IconUrl
            };
            await _work.GuildRepository.AddOrUpdateAsync(discordGuild, g => g.DiscordId == Context.Guild.Id);

            discordGuild = await _work.GuildRepository.SingleOrDefaultAsync(g => g.DiscordId == Context.Guild.Id);

            StreamUser streamUser = new StreamUser()
            {
                ServiceType = user.ServiceType,
                SourceID    = user.Id,
                Username    = user.Username,
                DisplayName = user.DisplayName,
                AvatarURL   = user.AvatarURL,
                ProfileURL  = user.ProfileURL
            };
            await _work.UserRepository.AddOrUpdateAsync(streamUser, (i => i.ServiceType == user.ServiceType && i.SourceID == user.Id));

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

            Expression <Func <StreamSubscription, bool> > streamSubscriptionPredicate = (i =>
                                                                                         i.User == streamUser &&
                                                                                         i.DiscordGuild == discordGuild
                                                                                         );
            IEnumerable <StreamSubscription> streamSubscriptions = await _work.SubscriptionRepository.FindAsync(streamSubscriptionPredicate);

            try
            {
                foreach (StreamSubscription streamSubscription in streamSubscriptions)
                {
                    await _work.SubscriptionRepository.RemoveAsync(streamSubscription.Id);
                }
                await ReplyAsync($"{Context.Message.Author.Mention}, I have removed the Subscription for {user.DisplayName}");

                return(MonitorResult.FromSuccess());
            }
            catch (Exception e)
            {
                Log.Error($"Error running MonitorStop for {Context.Message.Author.Id} {Context.Message.Author.Username}#{Context.Message.Author.Discriminator} GuildID: {Context.Guild.Id} ChannelID: {Context.Channel.Id}\n{e}");
                return(MonitorResult.FromSuccess($"{Context.Message.Author.Mention}, I couldn't remove the Subscription for user {user.DisplayName}. Please try again or contact my owner"));
            }
        }
Ejemplo n.º 4
0
        public async Task CheckStream(ILiveBotUser user)
        {
            ILiveBotMonitor monitor = _GetServiceMonitor(user);
            ILiveBotStream  stream  = await monitor.GetStream(user);

            if (stream == null)
            {
                await ReplyAsync($"Doesn't look like the user {user.DisplayName} is live on {user.ServiceType}");

                return;
            }
            Embed streamEmbed = NotificationHelpers.GetStreamEmbed(stream: stream, user: stream.User, game: stream.Game);
            StreamSubscription bogusSubscription = new StreamSubscription()
            {
                Message = Defaults.NotificationMessage
            };
            string notificationMessage = NotificationHelpers.GetNotificationMessage(stream, bogusSubscription);

            await ReplyAsync(message : $"Service: `{stream.ServiceType}`\n{notificationMessage}", embed : streamEmbed);
        }
Ejemplo n.º 5
0
        /// <inheritdoc/>
        public override async Task <TypeReaderResult> ReadAsync(ICommandContext Context, string Input, IServiceProvider Services)
        {
            ILiveBotUser liveBotUser;

            Input = Input.Trim();

            const string URLPattern = "^(ht|f)tp(s?)\\:\\/\\/[0-9a-zA-Z]([-.\\w]*[0-9a-zA-Z])*(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\'\\/\\\\\\+&%\\$#_]*)?$";
            Regex        URLRegex   = new Regex(URLPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);

            // Check if Valid URL
            if (Regex.IsMatch(Input, URLPattern))
            {
                Match URLMatch = URLRegex.Match(Input);
                IEnumerable <ILiveBotMonitor> monitors = Services.GetServices <ILiveBotMonitor>();
                ILiveBotMonitor monitor = monitors.Where(m => m.IsValid(URLMatch.Groups[0].ToString())).FirstOrDefault();

                if (monitor == null)
                {
                    return(TypeReaderResult.FromError(CommandError.Unsuccessful,
                                                      $"{Context.Message.Author.Mention}, I couldn't process the link you provided. Please check the link and try again."));
                }

                liveBotUser = await monitor.GetUser(profileURL : Input);
            }
            else
            {
                return(TypeReaderResult.FromError(CommandError.ParseFailed,
                                                  $"{Context.Message.Author.Mention}, you must provide a valid link to the stream you want to monitor."));
            }

            if (liveBotUser == null)
            {
                return(TypeReaderResult.FromError(CommandError.ParseFailed,
                                                  $"{Context.Message.Author.Mention}, I couldn't determine what type of stream that was."));
            }

            return(TypeReaderResult.FromSuccess(liveBotUser));
        }
Ejemplo n.º 6
0
        public async Task <RuntimeResult> MonitorStart(ILiveBotUser user)
        {
            ILiveBotMonitor monitor = _GetServiceMonitor(user);

            DiscordGuild discordGuild = new DiscordGuild
            {
                DiscordId = Context.Guild.Id,
                Name      = Context.Guild.Name,
                IconUrl   = Context.Guild.IconUrl
            };
            await _work.GuildRepository.AddOrUpdateAsync(discordGuild, g => g.DiscordId == Context.Guild.Id);

            discordGuild = await _work.GuildRepository.SingleOrDefaultAsync(g => g.DiscordId == Context.Guild.Id);

            // Get Notification Channel
            DiscordChannel discordChannel = await _RequestNotificationChannel(discordGuild);

            if (discordChannel == null)
            {
                return(MonitorResult.FromError($"{Context.Message.Author.Mention}, Please re-run the command and be sure to mention a channel."));
            }

            // Get Notification Message
            string notificationMessage = await _RequestNotificationMessage();

            if (notificationMessage == null)
            {
                return(MonitorResult.FromError($"{Context.Message.Author.Mention}, Please re-run the command and provide a valid message for notifications"));
            }

            // Get Notification Role
            DiscordRole discordRole = await _RequestNotificationRole(discordGuild);

            // Process their answers
            StreamUser streamUser = new StreamUser()
            {
                ServiceType = user.ServiceType,
                SourceID    = user.Id,
                Username    = user.Username,
                DisplayName = user.DisplayName,
                AvatarURL   = user.AvatarURL,
                ProfileURL  = user.ProfileURL
            };
            await _work.UserRepository.AddOrUpdateAsync(streamUser, (i => i.ServiceType == user.ServiceType && i.SourceID == user.Id));

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

            Expression <Func <StreamSubscription, bool> > streamSubscriptionPredicate = (i =>
                                                                                         i.User == streamUser &&
                                                                                         i.DiscordGuild == discordGuild
                                                                                         );

            StreamSubscription newSubscription = new StreamSubscription()
            {
                User           = streamUser,
                DiscordGuild   = discordGuild,
                DiscordChannel = discordChannel,
                DiscordRole    = discordRole,
                Message        = notificationMessage
            };

            try
            {
                StreamSubscription existingSubscription = await _work.SubscriptionRepository.SingleOrDefaultAsync(streamSubscriptionPredicate);

                if (existingSubscription != null)
                {
                    existingSubscription.DiscordGuild   = newSubscription.DiscordGuild;
                    existingSubscription.DiscordChannel = newSubscription.DiscordChannel;
                    existingSubscription.DiscordRole    = newSubscription.DiscordRole;
                    existingSubscription.Message        = newSubscription.Message;
                    await _work.SubscriptionRepository.UpdateAsync(existingSubscription);
                }
                else
                {
                    await _work.SubscriptionRepository.AddOrUpdateAsync(newSubscription, streamSubscriptionPredicate);
                }

                StreamSubscription streamSubscription = await _work.SubscriptionRepository.SingleOrDefaultAsync(streamSubscriptionPredicate);

                monitor.AddChannel(user);
                string escapedMessage = NotificationHelpers.EscapeSpecialDiscordCharacters(streamSubscription.Message);
                await ReplyAsync($"{Context.Message.Author.Mention}, I have setup a subscription for {user.DisplayName} on {user.ServiceType} with message {escapedMessage}");

                return(MonitorResult.FromSuccess());
            }
            catch (Exception e)
            {
                Log.Error($"Error running MonitorStart for {Context.Message.Author.Id} {Context.Message.Author.Username}#{Context.Message.Author.Discriminator} GuildID: {Context.Guild.Id} ChannelID: {Context.Channel.Id}\n{e}");
                return(MonitorResult.FromError($"{Context.Message.Author.Mention}, I wasn't able to create a subscription for the user {user.DisplayName} on {user.ServiceType}. Please try again or contact my owner"));
            }
        }
Ejemplo n.º 7
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}");
                    }
                }
            }
        }
Ejemplo n.º 8
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 });
            }
        }