Пример #1
0
        private async Task AddMember(params string[] args)
        {
            if (args.Length != 2)
            {
                await ReplyAsync("Provide 2 arguments, group id and discord user id");

                return;
            }

            if (!int.TryParse(args[0], out int groupId))
            {
                await ReplyAsync($"Unable to parse {args[0]} as group id");

                return;
            }

            if (!ulong.TryParse(args[1], out ulong discordUserId))
            {
                await ReplyAsync($"Unable to parse {args[1]} as discord user id");
            }

            await BrobotService.AddDiscordUserToSecretSantaGroup(groupId, discordUserId);

            await ReplyAsync("Added");
        }
Пример #2
0
        internal async override Task ExecuteJobAsync(CancellationToken stoppingToken)
        {
            try
            {
                var today = DateTime.Now;
                foreach (var channel in Job.Channels)
                {
                    var discordChannel = DiscordClient.GetChannel(channel.ChannelId);
                    if (!(discordChannel is SocketTextChannel socketTextChannel))
                    {
                        continue;
                    }
                    var channelUsers = await BrobotService.GetDiscordUsersForChannel(channel.ChannelId);

                    foreach (var user in channelUsers.Where(cu => cu.Birthdate.HasValue &&
                                                            cu.Birthdate.Value.Month == today.Month &&
                                                            cu.Birthdate.Value.Day == today.Day))
                    {
                        var discordUser = socketTextChannel.GetUser(user.DiscordUserId);
                        if (discordUser == null)
                        {
                            continue;
                        }
                        await socketTextChannel.SendMessageAsync($"Happy Birthday {discordUser.Mention}! :birthday:");

                        NumberOfFailures = 0;
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Failed to execute birthday job.");
                NumberOfFailures++;
            }
        }
Пример #3
0
        private async Task CreateEvent(string[] args)
        {
            if (args.Length != 1)
            {
                await ReplyAsync("Provide 1 argument, the group to create the event for");

                return;
            }

            if (!int.TryParse(args[0], out int groupId))
            {
                await ReplyAsync($"Unable to parse {args[0]} as group id");

                return;
            }

            var newEvent = await BrobotService.CreateSecretSantaEvent(groupId, DateTime.Now.Year, Context.User.Id);

            foreach (var pairing in newEvent.SecretSantaPairings)
            {
                var user      = Context.Client.GetUser(pairing.Giver.DiscordUserId);
                var dmChannel = await user.GetOrCreateDMChannelAsync();

                await dmChannel.SendMessageAsync($":santa: You have {pairing.Recipient.Username}");
            }

            await ReplyAsync("Pairings sent!");
        }
Пример #4
0
        private async Task CreateGroup(params string[] args)
        {
            if (args.Length < 1 || args.Length > 2)
            {
                await ReplyAsync("Invalid arguments. Supply a group name and optional check past year");

                return;
            }

            var checkPastYear = false;

            if (args.Length == 2)
            {
                if (!bool.TryParse(args[1], out checkPastYear))
                {
                    await ReplyAsync($"Unable to parse {args[1]} for use past year value. Use true or false");
                }
            }

            var secretSantaGroup = new SecretSantaGroup
            {
                Name = args[0],
                CheckPastYearPairings = checkPastYear
            };

            var newSecretSantaGroup = await BrobotService.CreateSecretSantaGroup(secretSantaGroup);

            await ReplyAsync($"Created group {newSecretSantaGroup.Name} with an ID of {newSecretSantaGroup.SecretSantaGroupId}");
        }
Пример #5
0
        public async Task Reminder(string reminderDateTime, string reminderMessage)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(reminderDateTime) || string.IsNullOrWhiteSpace(reminderMessage))
                {
                    await ReplyAsync("Invalid arguments. Please supply two arguments: a date in yyyy-MM-dd HH:mm format and a reminder message");

                    return;
                }

                if (!DateTime.TryParse(reminderDateTime, out DateTime dateTimeResult))
                {
                    await ReplyAsync($"{reminderDateTime} is not in the format. Please use yyyy-MM-dd HH:mm format (ex: 2020-01-01 18:00)");

                    return;
                }

                var reminder = new Reminder
                {
                    ChannelId       = Context.Channel.Id,
                    OwnerId         = Context.Message.Author.Id,
                    Message         = reminderMessage,
                    ReminderDateUtc = dateTimeResult
                };
                await BrobotService.PostReminder(reminder);
                await ReplyAsync("Reminder has been set");
            }
            catch (Exception)
            {
                await ReplyAsync("Failed to set reminder message");
            }
        }
Пример #6
0
        internal override async Task ExecuteJobAsync(CancellationToken stoppingToken)
        {
            try
            {
                var activeReminders = await BrobotService.GetReminders(reminderDateUtc : DateTime.UtcNow);

                foreach (var channel in Job.Channels)
                {
                    var discordChannel = DiscordClient.GetChannel(channel.ChannelId);
                    if (!(discordChannel is SocketTextChannel socketTextChannel))
                    {
                        continue;
                    }

                    foreach (var reminder in activeReminders.Where(r => r.ChannelId == channel.ChannelId && r.SentDateUtc == null))
                    {
                        await socketTextChannel.SendMessageAsync($"@everyone {reminder.Message}");

                        reminder.SentDateUtc = DateTime.UtcNow;
                        await BrobotService.UpdateReminder(reminder);
                    }
                }
                NumberOfFailures = 0;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Failed to start reminders job");
                NumberOfFailures++;
            }
        }
Пример #7
0
        internal async override Task ExecuteJobAsync(CancellationToken stoppingToken)
        {
            try
            {
                var containsParameter  = Job.JobParameters.FirstOrDefault(p => p.Name.Equals("contains", StringComparison.OrdinalIgnoreCase));
                var handlerParameter   = Job.JobParameters.FirstOrDefault(p => p.Name.Equals("twitterhandle", StringComparison.OrdinalIgnoreCase));
                var lastCheckParameter = Job.JobParameters.FirstOrDefault(p => p.Name.Equals("lastcheckdatetimeutc", StringComparison.OrdinalIgnoreCase));

                if (string.IsNullOrWhiteSpace(handlerParameter?.Value))
                {
                    Logger.LogError($"Job {Job.Name} does not contain required parameter TwitterHandler. Exiting job");
                    NumberOfFailures = MaxNumberOfFailures;
                    return;
                }

                if (string.IsNullOrWhiteSpace(lastCheckParameter?.Value))
                {
                    Logger.LogError($"Job {Job.Name} does not contain required parameter LatestTweetId. Exiting job");
                    NumberOfFailures = MaxNumberOfFailures;
                    return;
                }

                if (!DateTime.TryParse(lastCheckParameter.Value, out DateTime latestCheck))
                {
                    Logger.LogError($"Job {Job.Name}: {lastCheckParameter.Name} is not a datetime. Exiting job");
                    NumberOfFailures = MaxNumberOfFailures;
                    return;
                }


                var tweets = await _twitterService.GetTweetsAsync(from : handlerParameter?.Value, contains : containsParameter?.Value, startTime : latestCheck.ToUniversalTime());

                var newCheckTime = DateTime.UtcNow;

                foreach (var channel in Job.Channels)
                {
                    var discordChannel = DiscordClient.GetChannel(channel.ChannelId);
                    if (!(discordChannel is SocketTextChannel socketTextChannel))
                    {
                        continue;
                    }

                    foreach (var tweet in tweets.OrderBy(t => t.CreatedAt))
                    {
                        await socketTextChannel.SendMessageAsync($"https://www.twitter.com/{handlerParameter.Value}/status/{tweet.Id}");
                    }
                }

                lastCheckParameter.Value = newCheckTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
                await BrobotService.UpdateJobParameter(Job.JobId, lastCheckParameter.JobParameterId, lastCheckParameter);


                NumberOfFailures = 0;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Failed to start reminders job");
                NumberOfFailures++;
            }
        }
Пример #8
0
        public async Task HotOp()
        {
            try
            {
                var hotOpScoreboards = await BrobotService.GetHotOpScoreboards(Context.Channel.Id);

                if (hotOpScoreboards.Count() == 0)
                {
                    await ReplyAsync("No current hot ops");

                    return;
                }

                foreach (var hotOpScoreboard in hotOpScoreboards)
                {
                    var builder = new EmbedBuilder
                    {
                        Color       = new Color(114, 137, 218),
                        Description = $"Operation Hot {hotOpScoreboard.HotOpOwnerName}"
                    };

                    foreach (var score in hotOpScoreboard.Scores.OrderByDescending(s => s.Score))
                    {
                        builder.AddField(x =>
                        {
                            x.Name     = score.DiscordUserName;
                            x.Value    = score.Score;
                            x.IsInline = false;
                        });
                    }

                    await ReplyAsync("", false, builder.Build());
                }
            }
            catch (Exception)
            {
                await ReplyAsync("Failed to get hot op scores");
            }
        }
Пример #9
0
        public async Task SecretSanta(string subcommand, params string[] args)
        {
            try
            {
                var discordUser = await BrobotService.GetDiscordUser(Context.Message.Author.Id);

                if (!discordUser.BrobotAdmin)
                {
                    return;
                }
                var subcommandLower = subcommand.ToLower();
                if (!_subcommands.ContainsKey(subcommandLower))
                {
                    await ReplyAsync($"{subcommand} is not a valid subcommand");

                    return;
                }

                await _subcommands[subcommandLower](args);
            }
            catch (BrobotServiceException bsEx)
            {
                if (!string.IsNullOrWhiteSpace(bsEx.MessageFromServer))
                {
                    await ReplyAsync(bsEx.MessageFromServer);
                }
                else
                {
                    await ReplyAsync(bsEx.Message);
                }
            }
            catch (Exception ex)
            {
                await ReplyAsync($"Failed to execute secret santa command: {ex.Message}");
            }
        }
Пример #10
0
        internal override async Task ExecuteJobAsync(CancellationToken stoppingToken)
        {
            try
            {
                var wordCloudParameter = Job.JobParameters.FirstOrDefault(jp => jp.Name.Equals("GenerateWordCloud", StringComparison.OrdinalIgnoreCase));
                bool.TryParse(wordCloudParameter?.Value ?? "false", out bool generateWordCloud);
                HashSet <string> stopWords = null;

                var now = DateTime.UtcNow;
                var startOfThisMonth = new DateTime(now.Year, now.Month, 1, 0, 0, 0);
                var startOfLastMonth = startOfThisMonth.AddMonths(-1);

                if (generateWordCloud)
                {
                    stopWords = new HashSet <string>((await BrobotService.GetStopWords()).Select(sw => sw.Word));
                }
                string[] separatingStrings = { " ", "\t", "\n", "\r\n", ",", ":", ".", "!", "/", "\\", "%", "&", "?", "(", ")", "\"", "@" };


                foreach (var channel in Job.Channels)
                {
                    TimeSpan lastMonthOffset = TimeSpan.Zero, currentOffset = TimeSpan.Zero;
                    if (!string.IsNullOrWhiteSpace(channel.PrimaryTimezone))
                    {
                        var tzInfo = TZConvert.GetTimeZoneInfo(channel.PrimaryTimezone);
                        lastMonthOffset = tzInfo.GetUtcOffset(startOfLastMonth);
                        currentOffset   = tzInfo.GetUtcOffset(startOfThisMonth);
                    }
                    var startDateTime = new DateTimeOffset(startOfLastMonth, lastMonthOffset);
                    var endDateTime   = new DateTimeOffset(startOfThisMonth, currentOffset);

                    var discordChannel = DiscordClient.GetChannel(channel.ChannelId);
                    if (!(discordChannel is SocketTextChannel socketTextChannel))
                    {
                        continue;
                    }

                    var messageCount = new Dictionary <ulong, (string UserName, int MessageCount)>();
                    var words        = new Dictionary <string, int>();
                    foreach (var user in discordChannel.Users)
                    {
                        messageCount.Add(user.Id, (UserName: user.Username, MessageCount: 0));
                    }

                    foreach (var message in await socketTextChannel.GetMessagesAsync(startDateTime, endDateTime))
                    {
                        if (messageCount.TryGetValue(message.Author.Id, out var count))
                        {
                            count.MessageCount++;
                            messageCount[message.Author.Id] = count;
                        }

                        if (generateWordCloud)
                        {
                            foreach (var word in message.Content.Split(separatingStrings, StringSplitOptions.RemoveEmptyEntries).Where(w => !stopWords.Contains(w, StringComparer.OrdinalIgnoreCase)))
                            {
                                if (!words.ContainsKey(word.ToLower()))
                                {
                                    words.Add(word.ToLower(), 0);
                                }
                                words[word.ToLower()]++;
                            }
                        }
                    }

                    var builder = new StringBuilder();
                    foreach (var count in messageCount.Values.OrderByDescending(c => c.MessageCount))
                    {
                        builder.AppendLine($"{count.UserName}: {count.MessageCount}");
                    }

                    await socketTextChannel.SendMessageAsync(builder.ToString());

                    if (generateWordCloud)
                    {
                        try
                        {
                            var wc          = new WordCloud(1280, 720);
                            var frequencies = words
                                              .OrderByDescending(w => w.Value)
                                              .Take(100)
                                              .Select(w => new { Frequency = w.Value, Word = w.Key });
                            wc.Draw(frequencies.Select(f => f.Word).ToList(), frequencies.Select(f => f.Frequency).ToList()).Save(_wordcloudPath);
                            await socketTextChannel.SendFileAsync(_wordcloudPath, string.Empty);

                            File.Delete(_wordcloudPath);
                        }
                        catch (Exception ex) // if there was an error with the word cloud, don't kill the entire process
                        {
                            Logger.LogWarning(ex, "Failed to generate word cloud");
                        }
                    }
                }
            }
            catch (ArgumentException argEx)
            {
                Logger.LogError(argEx, "Invalid argument, stopping job");
                await StopAsync();
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Failed to execute stats job.");
                NumberOfFailures++;
            }
        }
Пример #11
0
        internal override async Task ExecuteJobAsync(CancellationToken stoppingToken)
        {
            try
            {
                var startingHotOps = await BrobotService.GetHotOps(startDateTimeUtc : DateTime.UtcNow);

                foreach (var hotOp in startingHotOps.Where(ho => ho.PrimaryChannelId.HasValue && Job.Channels.Any(c => c.ChannelId == ho.PrimaryChannelId.Value)))
                {
                    var channel = DiscordClient.GetChannel(hotOp.PrimaryChannelId.Value);
                    if (!(channel is SocketTextChannel textChannel))
                    {
                        continue;
                    }

                    await textChannel.SendMessageAsync($"Operation Hot {hotOp.Owner.Username} has begun!");
                }

                var expiringHotOps = await BrobotService.GetHotOps(endDateTimeUtc : DateTime.UtcNow);

                foreach (var hotOp in expiringHotOps)
                {
                    var utcNow = DateTime.UtcNow;
                    foreach (var openSession in hotOp.Sessions.Where(s => s.EndDateTimeUtc == null))
                    {
                        openSession.EndDateTimeUtc = utcNow;
                        await BrobotService.UpdateHotOpSession(hotOp.Id, openSession);
                    }

                    if (hotOp.PrimaryChannelId == null || !Job.Channels.Any(c => c.ChannelId == hotOp.PrimaryChannelId))
                    {
                        continue;
                    }

                    var channel = DiscordClient.GetChannel(hotOp.PrimaryChannelId.Value);
                    if (!(channel is SocketTextChannel textChannel))
                    {
                        continue;
                    }

                    var scoreboard = await BrobotService.GetHotOpScoreboard(hotOp.Id);

                    var scores = new List <HotOpScore>(scoreboard.Scores);
                    foreach (var user in textChannel.Users.Where(u => !u.IsBot && u.Id != scoreboard.HotOpOwnerId && !scoreboard.Scores.Any(s => s.DiscordUserId == u.Id)))
                    {
                        scores.Add(new HotOpScore
                        {
                            DiscordUserId   = user.Id,
                            DiscordUserName = user.Username,
                            Score           = 0
                        });
                    }

                    var builder = new EmbedBuilder
                    {
                        Color       = new Color(114, 137, 218),
                        Description = $"Operation Hot {scoreboard.HotOpOwnerName}"
                    };

                    foreach (var score in scores.OrderByDescending(s => s.Score))
                    {
                        builder.AddField(x =>
                        {
                            x.Name     = score.DiscordUserName;
                            x.Value    = score.Score;
                            x.IsInline = false;
                        });
                    }

                    await textChannel.SendMessageAsync($"Operation Hot Op {scoreboard.HotOpOwnerName} has finished. Final score:", false, builder.Build());
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Failed to start hot op job");
                NumberOfFailures++;
            }
        }