public InteractionResponse(InteractionResponseType type, string content = null, bool?tts = null, Embed embed = null, AllowedMentions mentions = null, InteractionResponseFlags flags = InteractionResponseFlags.None) { Type = type; Data = new InteractionApplicationCommandCallbackData() { TTS = tts, Content = content, Embeds = embed == null ? null : new Embed[1] { embed }, AllowedMentions = mentions, Flags = flags }; if (Type == InteractionResponseType.Pong || Data.IsEmpty) { Data = null; } }
/// <summary> /// Responds to an Interaction. /// </summary> /// <param name="text">The text of the message to be sent.</param> /// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/>.</param> /// <param name="embed">A <see cref="Embed"/> to send with this response.</param> /// <param name="type">The type of response to this Interaction.</param> /// <param name="allowedMentions">The allowed mentions for this response.</param> /// <param name="flags"></param> /// <param name="options">The request options for this response.</param> /// <returns> /// The <see cref="IMessage"/> sent as the response. If this is the first acknowledgement, it will return null. /// </returns> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="InvalidOperationException">The parameters provided were invalid or the token was invalid.</exception> public async Task <IMessage> RespondAsync(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType type = InteractionResponseType.ChannelMessageWithSource, AllowedMentions allowedMentions = null, int?flags = null, RequestOptions options = null) { if (type == InteractionResponseType.Pong) { throw new InvalidOperationException($"Cannot use {Type} on a send message function"); } if (!IsValidToken) { throw new InvalidOperationException("Interaction token is no longer valid"); } Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed."); Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed."); // check that user flag and user Id list are exclusive, same with role flag and role Id list if (allowedMentions?.AllowedTypes != null) { if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Users) && allowedMentions.UserIds != null && allowedMentions.UserIds.Count > 0) { throw new ArgumentException("The Users flag is mutually exclusive with the list of User Ids.", nameof(allowedMentions)); } if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Roles) && allowedMentions.RoleIds != null && allowedMentions.RoleIds.Count > 0) { throw new ArgumentException("The Roles flag is mutually exclusive with the list of Role Ids.", nameof(allowedMentions)); } } var callbackData = new InteractionApplicationCommandCallbackData(text) { TTS = isTTS }; if (allowedMentions != null) { callbackData.AllowedMentions = allowedMentions.ToModel(); } if (embed != null) { callbackData.Embeds = new[] { embed.ToModel() } } ; if (flags.HasValue) { callbackData.Flags = flags.Value; } var response = new InteractionResponse { Type = type, Data = callbackData }; await Discord.Rest.ApiClient.CreateInteractionResponse(response, Id, Token, options).ConfigureAwait(false); return(null); }
private void SetResponded(InteractionResponseType type) { HasResponded = true; ResponseType = type; }
public async static Task MySlashCommandHandler(SocketInteraction arg) { InteractionResponseType param = InteractionResponseType.ChannelMessageWithSource; switch ((arg as SocketSlashCommand).Data.Name) { case "help": { try { var ct = new ComponentBuilder() .WithButton("Previous page", $"id.0|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Danger, null, null, true) .WithButton("Next page", $"id.1|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Success) .WithButton("Our website", null, ButtonStyle.Link, null, "https://terrariabuilders.com/") .WithButton("Become a voter!", $"id.voter|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Primary); var eb = new EmbedBuilder() { Title = "Development & Source", Color = Color.Blue, Description = $"The Grand Design has been developed by the Terraria Builders Community to bring utility in Terraria and Discord to new heights!", ThumbnailUrl = "https://cdn.discordapp.com/attachments/694988142616379432/849374178343518238/sbcdetailed.gif", Author = new EmbedAuthorBuilder() { IconUrl = $"{Utils.BotUser.GetAvatarUrl()}", Name = "TGD Help | Scroll through pages with the buttons below.", }, Footer = new EmbedFooterBuilder() { Text = $"Page 1 • The Grand Design!", }, Fields = { new EmbedFieldBuilder() { Name = "Commands", Value = "All commands are featured in `!commands`. Check it out! \nTGD also introduces slashcommands for easy access. \nType `'/'` to get a preview of all commands!" }, new EmbedFieldBuilder() { Name = "DM Support", Value = "To get into contact with the staff of this server in an easy way, \nsend a DM to the Grand Design!" }, new EmbedFieldBuilder() { Name = "About TBC", Value = "All information about the Terraria Builders Community is provided on other pages. \nUse the buttons to navigate them!" } } }; await arg.RespondAsync("", false, eb.Build(), param, false, null, null, ct.Build()); } catch { Console.WriteLine("Error executing slash command"); } } break; case "vote": { try { var ct = new ComponentBuilder() .WithButton("Click here to vote", null, ButtonStyle.Link, null, "https://terrariabuilders.com/vote") .WithButton("Become a voter!", $"id.voter|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Primary); var eb = new EmbedBuilder() { Color = Color.Blue, Description = $"Thank you for your contribution! You can get the voter role through the buttons below to be reminded to vote every day.", Author = new EmbedAuthorBuilder() { IconUrl = $"{Utils.BotUser.GetAvatarUrl()}", Name = "Vote for TBC!", }, Footer = new EmbedFooterBuilder() { Text = $"{DateTime.Now}", }, }; await arg.RespondAsync("", false, eb.Build(), param, false, null, null, ct.Build()); } catch { Console.WriteLine("Error executing slash command"); } } break; case "notifications": { try { IEmote eEvent = new Emoji("🗓"); IEmote eAnnounce = new Emoji("📣"); IEmote eVoter = new Emoji("🎫"); var ct = new ComponentBuilder() .WithButton("Events", $"id.event|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Primary, eEvent) .WithButton("Announcements", $"id.announce|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Primary, eAnnounce) .WithButton("Voting", $"id.voter|{(arg as SocketSlashCommand).User.Id}", ButtonStyle.Primary, eVoter); var eb = new EmbedBuilder() { Color = Color.Blue, Description = $"You can assign any of the below roles to be mentioned when updates/reminders are sent in respective channels!", Author = new EmbedAuthorBuilder() { IconUrl = $"{Utils.BotUser.GetAvatarUrl()}", Name = "Notification Roles & Reminders", }, Footer = new EmbedFooterBuilder() { Text = $"{DateTime.Now}", }, }; await arg.RespondAsync("", false, eb.Build(), param, false, null, null, ct.Build()); } catch { Console.WriteLine("Error executing slash command"); } } break; case "ping": { try { var eb = new EmbedBuilder() { Description = $"The Grand Design's latency is about: `{Handler._Client.Latency}` milliseconds.", Author = new EmbedAuthorBuilder() { IconUrl = $"{Utils.BotUser.GetAvatarUrl()}", Name = "Ping/Latency", }, Footer = new EmbedFooterBuilder() { Text = $"{DateTime.Now}", }, }; await arg.RespondAsync("", false, eb.Build(), param, true); } catch { Console.WriteLine("Error executing slash command"); } } break; case "8ball": { try { var input = (arg as SocketSlashCommand).Data.Options.First(x => x.Name == "question"); string[] mystrings = ("No.|Yes.|Not at all, degenerate scum.|Your mother might agree.|Bistol says no.|I muster with all my strength, a fart in your face.|Lick my balls and call it a day.|A Discord moderator disagrees.|The kids in my basement.|Former president obama might know the answer, I am just an 8ball|S******g in your mouth and saying 'Yeehaw!'.|F**k no.|F*****g hell, weirdo.|I tried to think, didn't work out.|Yes daddy!").Split('|'); Random randomInt = new Random(); var eb = new EmbedBuilder() { Author = new EmbedAuthorBuilder() { IconUrl = $"{Utils.BotUser.GetAvatarUrl()}", Name = $"{input.Value}", }, Description = new string(mystrings[randomInt.Next(mystrings.Length)]), Footer = new EmbedFooterBuilder() { Text = $"{DateTime.Now}" } }; await arg.RespondAsync("", false, eb.Build(), param, true); } catch { Console.WriteLine("Error executing slash command"); } } break; case "avatar": { try { SocketUser user; var options = arg as SocketSlashCommand; if (options.Data.Options != null && options.Data.Options.Count > 0) { string userdata = options.Data?.Options?.FirstOrDefault()?.Value?.ToString(); ulong userid = Convert.ToUInt64(userdata); user = Utils.Guild.GetUser(userid); var eb = new EmbedBuilder() { ImageUrl = $"{user.GetAvatarUrl(ImageFormat.Auto, 256)}", Author = new EmbedAuthorBuilder() { IconUrl = $"{user.GetAvatarUrl()}", Name = $"{user.Username}#{user.Discriminator}", }, Footer = new EmbedFooterBuilder() { Text = $"{DateTime.Now}", } }; await arg.RespondAsync("", false, eb.Build()); } else { user = options.User; var eb = new EmbedBuilder() { ImageUrl = $"{user.GetAvatarUrl(ImageFormat.Auto, 256)}", Author = new EmbedAuthorBuilder() { IconUrl = $"{user.GetAvatarUrl()}", Name = $"{user.Username}#{user.Discriminator}", }, Footer = new EmbedFooterBuilder() { Text = $"{DateTime.Now}", } }; await arg.RespondAsync("", false, eb.Build(), param, true); } } catch { Console.WriteLine("Error executing slash command"); } } break; } }
public async Task <IMessage> Reply(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType Type = InteractionResponseType.ChannelMessageWithSource, AllowedMentions allowedMentions = null, RequestOptions options = null) { if (Interaction is SocketInteraction) { return(await(Interaction as SocketInteraction).FollowupAsync(text, isTTS, embed, Type, allowedMentions, options)); } return(null); }
/// <summary> /// Creates a response to this interaction. /// </summary> /// <param name="type">The type of the response.</param> /// <param name="builder">The data, if any, to send.</param> public Task CreateResponseAsync(InteractionResponseType type, DiscordInteractionResponseBuilder builder = null) => this.Discord.ApiClient.CreateInteractionResponseAsync(this.Id, this.Token, type, builder);
/// <summary> /// Sends a followup message for this interaction /// </summary> /// <param name="text">The text of the message to be sent</param> /// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/></param> /// <param name="embed">A <see cref="Embed"/> to send with this response</param> /// <param name="Type">The type of response to this Interaction</param> /// <param name="allowedMentions">The allowed mentions for this response</param> /// <param name="options">The request options for this response</param> /// <returns> /// The sent message /// </returns> public async Task <IMessage> FollowupAsync(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType Type = InteractionResponseType.ChannelMessageWithSource, AllowedMentions allowedMentions = null, RequestOptions options = null) { if (Type == InteractionResponseType.ACKWithSource || Type == InteractionResponseType.ACKWithSource || Type == InteractionResponseType.Pong) { throw new InvalidOperationException($"Cannot use {Type} on a send message function"); } if (!IsValidToken) { throw new InvalidOperationException("Interaction token is no longer valid"); } var args = new API.Rest.CreateWebhookMessageParams(text) { IsTTS = isTTS, Embeds = embed != null ? new API.Embed[] { embed.ToModel() } : Optional <API.Embed[]> .Unspecified, }; return(await InteractionHelper.SendFollowupAsync(Discord.Rest, args, Token, Channel, options)); }
/// <summary> /// Responds to an Interaction. /// <para> /// If you have <see cref="DiscordSocketConfig.AlwaysAcknowledgeInteractions"/> set to <see langword="true"/>, You should use /// <see cref="FollowupAsync(string, bool, Embed, InteractionResponseType, AllowedMentions, RequestOptions)"/> instead. /// </para> /// </summary> /// <param name="text">The text of the message to be sent</param> /// <param name="isTTS"><see langword="true"/> if the message should be read out by a text-to-speech reader, otherwise <see langword="false"/></param> /// <param name="embed">A <see cref="Embed"/> to send with this response</param> /// <param name="Type">The type of response to this Interaction</param> /// <param name="allowedMentions">The allowed mentions for this response</param> /// <param name="options">The request options for this response</param> /// <returns> /// The <see cref="IMessage"/> sent as the response. If this is the first acknowledgement, it will return null; /// </returns> /// <exception cref="ArgumentOutOfRangeException">Message content is too long, length must be less or equal to <see cref="DiscordConfig.MaxMessageSize"/>.</exception> /// <exception cref="InvalidOperationException">The parameters provided were invalid or the token was invalid</exception> public async Task <IMessage> RespondAsync(string text = null, bool isTTS = false, Embed embed = null, InteractionResponseType Type = InteractionResponseType.ChannelMessageWithSource, AllowedMentions allowedMentions = null, RequestOptions options = null) { if (Type == InteractionResponseType.Pong) { throw new InvalidOperationException($"Cannot use {Type} on a send message function"); } if (!IsValidToken) { throw new InvalidOperationException("Interaction token is no longer valid"); } if (Discord.AlwaysAcknowledgeInteractions) { return(await FollowupAsync()); } Preconditions.AtMost(allowedMentions?.RoleIds?.Count ?? 0, 100, nameof(allowedMentions.RoleIds), "A max of 100 role Ids are allowed."); Preconditions.AtMost(allowedMentions?.UserIds?.Count ?? 0, 100, nameof(allowedMentions.UserIds), "A max of 100 user Ids are allowed."); // check that user flag and user Id list are exclusive, same with role flag and role Id list if (allowedMentions != null && allowedMentions.AllowedTypes.HasValue) { if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Users) && allowedMentions.UserIds != null && allowedMentions.UserIds.Count > 0) { throw new ArgumentException("The Users flag is mutually exclusive with the list of User Ids.", nameof(allowedMentions)); } if (allowedMentions.AllowedTypes.Value.HasFlag(AllowedMentionTypes.Roles) && allowedMentions.RoleIds != null && allowedMentions.RoleIds.Count > 0) { throw new ArgumentException("The Roles flag is mutually exclusive with the list of Role Ids.", nameof(allowedMentions)); } } var response = new API.InteractionResponse() { Type = Type, Data = new API.InteractionApplicationCommandCallbackData(text) { AllowedMentions = allowedMentions?.ToModel(), Embeds = embed != null ? new API.Embed[] { embed.ToModel() } : Optional <API.Embed[]> .Unspecified, TTS = isTTS } }; await Discord.Rest.ApiClient.CreateInteractionResponse(response, this.Id, Token, options); return(null); }
public InteractionResponseBuilder WithType(InteractionResponseType type) { Type = type; return(this); }
public static TResponse WithType <TResponse>(this TResponse response, InteractionResponseType type) where TResponse : LocalInteractionResponse { response.Type = type; return(response); }