public async Task NotifyWorkshopBeginsAsync(Workshop workShop) { await EnsureClientLoggedIn(); var discordMessage = GetDiscordMessage(workShop); var messageContext = await DiscordMessageContext.CreateAsync(_discordClient, discordMessage); if (messageContext.UserMessage == null) { return; } var mentions = await messageContext.UserMessage.GetReactionUsersAsync(ThumbsUpEmote, 1000) .SelectMany(x => x.ToAsyncEnumerable()) .Where(x => !x.IsBot && x.Id != _discordClient.CurrentUser.Id) .Select(x => x.GetMentionString()) .ToListAsync(); if (!mentions.Any()) { return; } var guild = await _discordClient.GetGuildAsync(_settings.GuildId); var channel = await guild.GetTextChannelAsync(_settings.ChannelId); await channel.SendMessageAsync($"Aufgepasst! Der Workshop {workShop.title} beginnt in Kürze! {string.Join(" ", mentions)}"); }
public Embed GetEmbed(DiscordMessageContext context) { var builer = new EmbedBuilder { Title = "Poll", Color = new Color(76, 175, 80), Description = $"Vote using `{CommandTools.GetCommandPrefix(context, context.Channel)}{(Anonymous ? $"anonvote {Id}" : "vote")} <option number|option text>`{(Anonymous ? $"\n**__ONLY VOTES FROM A DIRECT MESSAGE TO ME WILL BE COUNTED!__**\nThis is **anonymous poll number #{Id}.**" : "")}", Footer = new EmbedFooterBuilder { Text = $"The poll will end in {TimeSpan.FromMinutes(MinutesLeft).ToLongString()} unless stopped earlier with '{CommandTools.GetCommandPrefix(context, context.Channel)}endpoll'" }, Author = new EmbedAuthorBuilder { Name = Creator.NicknameOrUsername(), IconUrl = Creator.AvatarUrlOrDefaultAvatar() } }; for (int i = 0; i < Options.Count; i++) { builer.AddField((i + 1).ToString(), Options[i].Text, true); } if (TotalVotes > 0) { builer.AddField("Already Voted", string.Join(", ", Voters.Select(voter => voter.Key.NicknameOrUsername()))); } return(builer.Build()); }
public static async Task <ICommandResult> Help(DiscordMessageContext context, [DisplayName("page | command"), HelpText("Specifies page number or gets help for this specific command")] string command = null, [HelpText("Whether or not to show parameter descriptions")] Verbosity verbosity = Verbosity.Default) { const int pageSize = 5; string commandPrefix = CommandTools.GetCommandPrefix(context, context.Channel); var builder = new EmbedBuilder { Title = "Help", Color = new Color(33, 150, 243) }; bool paginate = int.TryParse(command, out int page); if (paginate) { command = null; } else if (command == null) { page = 1; paginate = true; } if (verbosity == Verbosity.Default) { verbosity = command != null ? Verbosity.Verbose : Verbosity.Standard; } var commands = command == null ? commandMethods.Where(method => method.GetCustomAttribute <CommandScopeAttribute>() ?.ChannelTypes.Contains(context.ChannelType) ?? true) .Where(method => method.GetCustomAttribute <PermissionsAttribute>()?.GetPermissionError(context) == null) .ToList() : GetCommands(command.StartsWith(commandPrefix) ? command.Substring(commandPrefix.Length) : command) .ToList(); if (commands.Count == 0 || commands[0] == null) { return(new ErrorResult($"The requested command {commandPrefix}{command} was not found")); } List <EmbedFieldBuilder> fields = new List <EmbedFieldBuilder>(); foreach (MethodInfo method in commands) { var title = new StringBuilder(); title.Append("`"); title.Append(string.Join("|", method.GetCustomAttribute <CommandAttribute>().Names.Select(name => $"{commandPrefix}{name}"))); title.Append(" "); title.Append(string.Join(" ", method.GetParameters() .Skip(1) .Select(param => param.IsOptional ? $"[{param.GetCustomAttribute<DisplayNameAttribute>()?.Name ?? param.Name}{(param.IsDefined(typeof(JoinRemainingParametersAttribute)) ? "..." : "")}{(param.DefaultValue == null ? "" : $" = {param.DefaultValue}")}]"
public static ICommandResult GetPoll(DiscordMessageContext context) { Poll po; if ((po = Poll.GetPoll(context.Channel)) != null) { return(new SuccessResult(embed: po.GetEmbed(context))); } else { return(new ErrorResult("There is no currently active poll in this channel")); } }
public static ICommandResult Timestamp(DiscordMessageContext context, [DisplayName("discord id")] ulong discordId) { long unixTime = (long)(((discordId >> 22) + 1420070400000) / 1000); try { return(new SuccessResult(TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTimeOffset.FromUnixTimeSeconds(unixTime), context.Bot.DefaultTimeZone).ToString())); } catch (Exception ex) when(ex is InvalidTimeZoneException || ex is TimeZoneNotFoundException) { return(new ErrorResult($"The time zone `{context.Bot.DefaultTimeZone}` is invalid", "Time Zone Error")); } }
public async Task <DiscordMessage> SendDiscordBotMessage ( Workshop currentWorkshop, Workshop dbWorkshop, DateTime date, Meeting existingMeeting ) { Embed embedMessageToSend; await EnsureClientLoggedIn(); var discordMessage = GetDiscordMessage(dbWorkshop); var messageContext = await DiscordMessageContext.CreateAsync(_discordClient, discordMessage); // We dont have any record in the db yet, so we cannot know wether there is a msg or not if (dbWorkshop == null || messageContext.UserMessage == null) { embedMessageToSend = BuildEmbed(currentWorkshop, date, true); await messageContext.SendAsync(embedMessageToSend); await messageContext.AddReactionAsync(ThumbsUpEmote); return(messageContext.Message); } if (!WorkshopChanged(dbWorkshop, currentWorkshop, existingMeeting)) { return(messageContext.Message); } embedMessageToSend = BuildEmbed(currentWorkshop, date, false); await messageContext.UpdateAsync(x => x.Embed = new Optional <Embed>(embedMessageToSend)); await ResetReactionsIfNecessary(currentWorkshop, ThumbsUpEmote, dbWorkshop, messageContext.UserMessage); return(discordMessage); }
public static async Task <ICommandResult> CreatePoll(DiscordMessageContext context, double minutes, List <string> args, bool anonymous) { if (minutes < 0.01 || minutes > 1440) { return(new ErrorResult("Please specify a valid positive number of minutes >= 0.01 and <= 1440.")); } Poll p = Create(context.Channel, context.MessageAuthor, context.Message, minutes, anonymous); if (p == null) { return(new ErrorResult($"There is already a{(Poll.GetPoll(context.Channel).Anonymous ? "n anonymous" : "")} poll in progress")); } foreach (string option in args) { p.Options.Add(new PollOption(option.TrimStart(), p)); } await context.Reply("", embed : p.GetEmbed(context)); return(await Task.Delay((int)(minutes * 60000)).ContinueWith(t => p.Active ? End(context.Channel) : new SuccessResult())); }
public string GetPermissionError(DiscordMessageContext context) { if (context.Bot.Settings.OwnerId == context.MessageAuthor.Id) { return(null); } if (botOwnerOnly && context.Bot.Settings.OwnerId != context.MessageAuthor.Id) { return("Only the bot owner can run that command"); } var guildChannel = context.Channel as IGuildChannel; if (guildChannel == null) { return("That command requires permissions that only exist in server channels"); } var missingChannelPermissions = channelPermissions.Where(perm => !((IGuildUser)context.MessageAuthor).GetPermissions((IGuildChannel)context.Channel).Has(perm)); var missingGuildPermissions = guildPermissions.Where(perm => !((IGuildUser)context.MessageAuthor).GuildPermissions.Has(perm)); var missingPermissionStrings = missingChannelPermissions.Select(perm => perm.ToString()).Concat(missingGuildPermissions.Select(perm => perm.ToString())).ToArray(); return(missingPermissionStrings.Length > 0 ? $"The following required permissions were missing: {string.Join(", ", missingPermissionStrings)}" : null); }
public static async Task SendPaginatedMessage(DiscordMessageContext context, string command, List <KeyValuePair <string, string> > content, int pageNumber, int pageSize, EmbedBuilder template = null) { IUserMessage message; if (context is DiscordPaginatedMessageContext p) { await p.Reply("", embed : GeneratePaginatedEmbed(command, content, pageNumber, pageSize, template)); message = p.Message; } else { message = await context.Channel.SendMessageAsync("", embed : GeneratePaginatedEmbed(command, content, pageNumber, pageSize, template)); } await message.RemoveAllReactionsAsync(); if (pageNumber > 2) { await message.AddReactionAsync(new Emoji("⏮")); } if (pageNumber > 1) { await message.AddReactionAsync(new Emoji("⬅")); } if (pageNumber < Math.Ceiling(content.Count / (float)pageSize)) { await message.AddReactionAsync(new Emoji("➡")); } if (pageNumber < Math.Ceiling(content.Count / (float)pageSize) - 1) { await message.AddReactionAsync(new Emoji("⏭")); } }
private async Task <DiscordMessageContext> TryGetDiscordUserMessage(DiscordMessage discordMessage) { return(await DiscordMessageContext.CreateAsync(_discordClient, discordMessage)); }
public static async Task <ICommandResult> Quote(DiscordMessageContext context, [DisplayName("message ID"), HelpText("The message to quote")] ulong id, [DisplayName("channel mention"), HelpText("The channel to search")] string channel = null) { IMessageChannel messageChannel = context.Channel; if (channel != null && context.Message.MentionedChannelIds.Count != 0) { messageChannel = (IMessageChannel)context.Bot.Client.GetChannel(context.Message.MentionedChannelIds.First()); } if (channel != null && !((IGuildUser)context.MessageAuthor).GetPermissions((IGuildChannel)messageChannel).ReadMessageHistory) { return(new ErrorResult("You do not have permission to read messages in that channel", "Permissions Error")); } IMessage msg = await messageChannel.GetMessageAsync(id); if (msg == null) { return(new ErrorResult("Message not found")); } var builder = new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = msg.Author.NicknameOrUsername(), IconUrl = msg.Author.AvatarUrlOrDefaultAvatar() }, Timestamp = msg.Timestamp, Footer = new EmbedFooterBuilder { Text = $"#{messageChannel.Name}" } }; switch (msg.Type) { case MessageType.Default: builder.Description = msg.Content; break; case MessageType.RecipientAdd: builder.Description = $"{msg.Author.Username} added a user to the group"; break; case MessageType.RecipientRemove: builder.Description = $"{msg.Author.Username} removed a user from the group"; break; case MessageType.Call: builder.Description = $"{msg.Author.Username} started a call"; break; case MessageType.ChannelNameChange: builder.Description = $"{msg.Author.Username} changed the name of the channel"; break; case MessageType.ChannelIconChange: builder.Description = $"{msg.Author.Username} changed the channel icon"; break; case MessageType.ChannelPinnedMessage: builder.Description = $"{msg.Author.Username} pinned a message to the channel"; break; case (Discord.MessageType) 7: builder.Description = $"{msg.Author.Username} joined the server"; break; } if (msg.Attachments.Count == 1) { builder.ImageUrl = msg.Attachments.First().Url; builder.Title = msg.Attachments.First().Filename; builder.Url = builder.ImageUrl; } else if (msg.Attachments.Count > 1) { foreach (Attachment attachment in msg.Attachments) { await context.Channel.SendMessageAsync("", embed : new EmbedBuilder { ImageUrl = attachment.Url, Title = attachment.Filename, Url = attachment.Url }.Build()); } } foreach (Embed embed in msg.Embeds.Where(x => x.Type == EmbedType.Rich)) { await context.Channel.SendMessageAsync("", embed : embed); } return(new SuccessResult(embed: builder.Build())); }