public async Task ClearOverwrite( [ParameterName("command")] [Required] string strId, [Required] string thingId) { await Interaction.AcknowledgeAsync(flags : InteractionResponseFlags.Ephemeral); if (!ulong.TryParse(thingId, out var id)) { await Interaction.FollowupAsync(":x: `thingId` must be a valid ulong of the user or role."); return; } var cmd = await getCommand(strId); if (cmd == null) { await Interaction.RespondAsync(":x: Command does not exist", ephemeral : true); return; } var existingPerms = await cmd.GetCommandPermissions(Interaction.Guild.Id); var permBuilder = SlashCommandPermsBuilder.From(existingPerms); permBuilder.Remove(id); await cmd.ModifyCommandPermissionsAsync(Interaction.Guild.Id, permBuilder.Build().ToArray()); await Interaction.FollowupAsync("Done!"); }
public async Task ToggleAdminDuty() { var adminRole = Interaction.Guild.Roles.FirstOrDefault(x => x.Name.StartsWith("Admin", StringComparison.OrdinalIgnoreCase) && x.Permissions.Administrator); if (adminRole == null) { await Interaction.RespondAsync(":x: No admin role setup for this guild.", ephemeral : true); return; } await Interaction.AcknowledgeAsync(Discord.InteractionResponseFlags.Ephemeral); var member = Interaction.User as SocketGuildUser; if (member.Roles.Any(x => x.Id == adminRole.Id)) { await member.RemoveRoleAsync(adminRole, new Discord.RequestOptions() { AuditLogReason = "Toggled admin duty" }); await Interaction.FollowupAsync("Your admin rights have been revoked."); } else { await member.AddRoleAsync(adminRole, new Discord.RequestOptions() { AuditLogReason = "Toggled admin duty." }); await Interaction.FollowupAsync("Your admin rights have been reinstated."); } }
public async Task SetDefaultOverwrite( [ParameterName("command")] [Required] string strId, [Required] bool value) { await Interaction.AcknowledgeAsync(flags : InteractionResponseFlags.Ephemeral); var cmd = await getCommand(strId); if (cmd == null) { await Interaction.FollowupAsync(":x: Command does not exist"); return; } if (cmd is RestGlobalCommand glb) { await glb.ModifyCommandPermissionsAsync(Interaction.Guild.Id, new SlashCommandPermsBuilder() .With(Interaction.Guild.Id, PermissionTarget.Role, value) // @everyone role .Build().ToArray()); await Interaction.FollowupAsync("Done!\r\nNote: due to a Discord bug, the command will appear greyed out but will still be executable."); } else if (cmd is RestGuildCommand gld) { await gld.ModifyAsync(x => x.DefaultPermission = value); await Interaction.FollowupAsync("Done!"); } }
public async Task ListCmdOverwrites([ParameterName("command")][Required] string strId) { try { await Interaction.AcknowledgeAsync(flags : InteractionResponseFlags.Ephemeral); var cmd = await getCommand(strId); if (cmd == null) { await Interaction.FollowupAsync(":x: Command does not exist."); return; } GuildApplicationCommandPermissions cmdPerms = null; if (cmd is RestGlobalCommand g) { cmdPerms = await g.GetCommandPermissions(Interaction.Guild.Id); } else if (cmd is RestGuildCommand u) { cmdPerms = await u.GetCommandPermissions(); } if (cmdPerms == null || cmdPerms.Permissions == null || cmdPerms.Permissions.Count == 0) { await Interaction.FollowupAsync("Default: " + emote(cmd.DefaultPermission) + "\r\n" + "Command has no specific permissions set"); return; } var embed = new EmbedBuilder(); embed.Title = $"{cmd.Name} Permissions"; var sb = new StringBuilder(); sb.Append("Default: " + emote(cmd.DefaultPermission) + "\r\n"); foreach (var thing in cmdPerms.Permissions) { if (thing.Type == PermissionTarget.User) { sb.Append($"User <@!{thing.Id}>"); } else { sb.Append($"Role <@&{thing.Id}>"); } sb.Append(" " + emote(thing.Value)); sb.Append("\r\n"); } embed.Description = sb.ToString(); await Interaction.FollowupAsync(embed : embed.Build(), allowedMentions : AllowedMentions.None); } catch (Exception ex) { Program.LogMsg(ex, "ListSlash"); } }
async Task manageThing(string strId, ulong thingId, PermissionTarget thingType, bool?value) { await Interaction.AcknowledgeAsync(flags : InteractionResponseFlags.Ephemeral); try { RestApplicationCommand command = await getCommand(strId); if (command == null) { await Interaction.FollowupAsync(":x: Command does not exist"); return; } GuildApplicationCommandPermissions existingPerms = null; if (command is RestGlobalCommand g) { existingPerms = await g.GetCommandPermissions(Interaction.Guild.Id); } else if (command is RestGuildCommand u) { existingPerms = await u.GetCommandPermissions(); } var permBuilder = SlashCommandPermsBuilder.From(existingPerms); var existingValue = permBuilder.Get(thingId); if (value.HasValue) { if (existingValue != value.Value) { permBuilder.With(thingId, thingType, value.Value); await command.ModifyCommandPermissionsAsync(Interaction.Guild.Id, permBuilder.Build().ToArray()); } await Interaction.FollowupAsync("Done!"); } else { if (!existingValue.HasValue) { await Interaction.FollowupAsync($"{thingType} has no explicit permission set."); } else { await Interaction.FollowupAsync($"{thingType} permission for command: " + emote(existingValue.Value)); } } } catch (Exception ex) { Program.LogMsg(ex, "a"); } }
public async Task MoveBatch([Required] int amount, [Required] SocketGuildChannel chnl) { if (!(chnl is SocketTextChannel to)) { await Interaction.RespondAsync(":x: You must select a text channel.", ephemeral : true); return; } var from = Interaction.Channel as ITextChannel; var fromPerms = (Interaction.User as SocketGuildUser).GetPermissions(from); if (!fromPerms.ManageMessages) { await Interaction.RespondAsync($":x: You do not have permission to move messages to {to.Mention}", type : InteractionResponseType.ChannelMessageWithSource, ephemeral : true); return; } await Interaction.AcknowledgeAsync(); var date = DateTimeOffset.Now.AddHours(-maximumHoursAgo); var messages = await fetchMessages(from, Math.Min(amount, maximumMoveCount), Discord.SnowflakeUtils.ToSnowflake(date)); var response = await Interaction.FollowupAsync($"Moving {messages.Count} messages.") as IUserMessage; DateTime last = DateTime.Now; int done = 0; foreach (var msg in messages.OrderBy(x => x.Id)) { // oldest first await MoveMsg(msg, to); done++; if ((DateTime.Now - last).TotalSeconds > 5) { last = DateTime.Now; await response.ModifyAsync(x => { x.Content = $"Moved {done}/{messages.Count} ({(done / messages.Count) * 100:00}%)"; }); } } await response.ModifyAsync(x => x.Content = $"Moved {messages.Count} messages."); }
public async Task ListCommands(string prefix = null, int page = 0) { try { await Interaction.AcknowledgeAsync(flags : InteractionResponseFlags.Ephemeral); var commands = await Program.Client.Rest.GetGuildApplicationCommands(Interaction.Guild.Id); var pages = new List <EmbedBuilder>(); var embed = new EmbedBuilder(); bool f = !string.IsNullOrWhiteSpace(prefix); embed.Title = "Slash Commands" + (f ? " /" + prefix : ""); embed.Description = ""; foreach (var cmd in commands) { var row = getCmdRow(cmd) + "\r\n"; if (embed.Description.Length + row.Length > 2048) { embed.WithFooter($"Page {pages.Count}"); pages.Add(embed); embed = new EmbedBuilder(); embed.Title = "Slash Commands" + (f ? " /" + prefix : ""); embed.Description = ""; } embed.Description += row; } embed.WithFooter($"Page {pages.Count}"); pages.Add(embed); if (page < 0 || page >= pages.Count) { await Interaction.FollowupAsync($":x: Index out of range: [0:{pages.Count - 1}]"); return; } await Interaction.FollowupAsync(embed : pages[page].Build()); } catch (Exception ex) { Program.LogMsg("CmdList", ex); throw ex; } }
public async Task MoveOne([Required] string message, [Required] SocketGuildChannel chnl) { if (!(chnl is SocketTextChannel to)) { await Interaction.RespondAsync(":x: You must select a text channel.", ephemeral : true); return; } var from = Interaction.Channel as ITextChannel; var fromPerms = (Interaction.User as SocketGuildUser).GetPermissions(from); if (!ulong.TryParse(message, out var messageId)) { await Interaction.RespondAsync(":x: You must enter a message id - a long number.", ephemeral : true); return; } if (!fromPerms.ManageMessages) { await Interaction.RespondAsync($":x: You do not have permission to move mesages to {to.Mention}", ephemeral : true); return; } await Interaction.AcknowledgeAsync(); var msg = await from.GetMessageAsync(messageId); if (msg == null || !(msg is IUserMessage umsg)) { await Interaction.FollowupAsync(":x: That message does not exist"); return; } await MoveMsg(umsg, to); await Interaction.FollowupAsync("Moved one message"); }
public async Task TranslateCmd([Required] string message, string language = null) { string fromLanguage = null; if (language != null) { fromLanguage = LanguageCodesUtils.ToCode(language); if (fromLanguage == null) { await Interaction.RespondAsync(":x: Language not recognised", ephemeral : true); return; } } await Interaction.AcknowledgeAsync(Discord.InteractionResponseFlags.Ephemeral); var client = TranslationClient.Create(); var response = await client.TranslateTextAsync(message, LanguageCodes.English, fromLanguage); var actualFrom = response.DetectedSourceLanguage == null ? fromLanguage : response.DetectedSourceLanguage; var name = LanguageCodesUtils.ToName(actualFrom); await Interaction.FollowupAsync($"Translate from {name}\r\n>>> {response.TranslatedText}"); }
public async Task AppId( [ParameterName("application-id")] [Required] string strid, [Required] [ParameterName("voice-channel")] SocketGuildChannel chnl) { if (!(chnl is SocketVoiceChannel vc)) { await Interaction.RespondAsync(":x: Channel must be a voice channel", ephemeral : true); return; } if (!ulong.TryParse(strid, out var id)) { await Interaction.RespondAsync(":x: Input was not a valid ulong. Must be a number", ephemeral : true); return; } await Interaction.AcknowledgeAsync(Discord.InteractionResponseFlags.Ephemeral); try { var invite = await createActivity(id, vc); await Interaction.FollowupAsync("Click to join below:\r\nhttps://discord.gg/" + invite.Code); } catch (Exception ex) { Program.LogMsg(ex, "ActivityId"); await Interaction.FollowupAsync(":x: Exception: " + ex.Message); } }
public async Task ChoiceActivity( [Choice("Poker Night", 0)] [Choice("Betrayal.io", 1)] [Choice("Youtube Together", 2)] [Choice("Fishington.io", 3)] [Required] int activity) { var vc = (Interaction.User as SocketGuildUser)?.VoiceChannel ?? null; if (vc == null) { await Interaction.RespondAsync(":x: You must be in a voice channel to run this command", ephemeral : true); return; } if (activity < 0 || activity > 3) { await Interaction.RespondAsync(":x: Invalid choice", ephemeral : true); return; } await Interaction.AcknowledgeAsync(); IInviteMetadata invite; string name; switch (activity) { case 0: name = "Poker Night"; invite = await createActivity(PokerNight, vc); break; case 1: name = "Betrayal.io"; invite = await createActivity(BetrayalIO, vc); break; case 2: name = "Youtube Together"; invite = await createActivity(YoutubeTogether, vc); break; case 3: name = "Fishington.io"; invite = await createActivity(FishingtonIO, vc); break; default: name = null; invite = null; break; } await Interaction.FollowupAsync($"Click on the link below to join **{name}**:\r\nhttps://discord.gg/{invite.Code}"); }
public async Task MoveAfter( [ParameterName("messageId")] [Required] string strMsgId, [Required] SocketGuildChannel chnl) { if (!(chnl is SocketTextChannel to)) { await Interaction.RespondAsync(":x: You must select a text channel.", ephemeral : true); return; } var from = Interaction.Channel as ITextChannel; var fromPerms = (Interaction.User as SocketGuildUser).GetPermissions(from); if (!ulong.TryParse(strMsgId, out var messageId)) { await Interaction.RespondAsync(":x: You must enter a message id - a long number.", ephemeral : true); return; } if (!fromPerms.ManageMessages) { await Interaction.RespondAsync($":x: You do not have permission to move mesages to {to.Mention}", ephemeral : true); return; } var date = Discord.SnowflakeUtils.FromSnowflake(messageId); if (Math.Abs((DateTime.Now - date).TotalHours) > maximumHoursAgo) { await Interaction.RespondAsync(":x: Message was sent too long ago.", ephemeral : true); return; } await Interaction.AcknowledgeAsync(); // oldest --> youngest // smallest --> largest; snowflake var messages = await fetchMessages(from, maximumMoveCount * 2, messageId); if (messages.Count > maximumMoveCount) { await Interaction.FollowupAsync(":x: Too many messages to move."); return; } var response = await Interaction.FollowupAsync($"Moving {messages.Count} messages.") as IUserMessage; DateTime last = DateTime.Now; int done = 0; foreach (var msg in messages.OrderBy(x => x.Id)) { // oldest first await MoveMsg(msg, to); done++; if ((DateTime.Now - last).TotalSeconds > 5) { last = DateTime.Now; await response.ModifyAsync(x => { x.Content = $"Moved {done}/{messages.Count} ({(done / (double)messages.Count) * 100:00}%)"; }); } } await response.ModifyAsync(x => x.Content = $"Moved {messages.Count} messages."); }
public async Task PurgeMessages([Required] int count, SocketGuildUser user = null) { IEnumerable <IMessage> messages; IMessage last = null; int done = 0; await Interaction.AcknowledgeAsync(); IUserMessage response = null; var lastSent = DateTimeOffset.Now; var bulkDelete = new List <IMessage>(); var manualDelete = new List <IMessage>(); do { if (last == null) { messages = await Interaction.Channel.GetMessagesAsync().FlattenAsync(); } else { messages = await Interaction.Channel.GetMessagesAsync(last, Direction.Before).FlattenAsync(); } if (messages.Count() == 0) { break; } last = messages.Last(); foreach (var msg in messages.OrderByDescending(x => x.Id)) { // we want to go newest (largest) to oldest (smallest), so descend if (user != null) { if (msg.Author.Id != user.Id) { continue; } } else { if (msg.Author.Id == Program.AppInfo.Id) { continue; } } var diff = DateTime.Now - msg.CreatedAt; if (bulkDelete.Count < 100 && diff.TotalDays < 14) // two weeks { bulkDelete.Add(msg); } else { manualDelete.Add(msg); } done++; if (done >= count) { break; } } if ((DateTime.Now - lastSent).TotalSeconds > 5) { response = await sendOrModify(response, $"Found {bulkDelete.Count + manualDelete.Count} messages to delete"); } } while (done < count); response = await sendOrModify(response, $"Removing {bulkDelete.Count + manualDelete.Count} messages"); if (bulkDelete.Count > 0) { if (Interaction.Channel is ITextChannel txt) { await bulkDelete.BulkDeleteAndTrackAsync(txt, $"bPurged by {Interaction.User.Mention}"); } else { // can't bulk delete in other types of text channels, it seems manualDelete.AddRange(bulkDelete); } } foreach (var msg in manualDelete) { await msg.DeleteAndTrackAsync($"Purged by {Interaction.User.Mention}"); } }