part of nyxx_interactions; /// The event that you receive when a user types a slash command. class InteractionEvent { late final Nyxx _client; /// The interaction data, includes the args, name, guild, channel, etc. late final Interaction interaction; /// The DateTime the interaction was received by the Nyxx Client. final DateTime receivedAt = DateTime.now(); /// If the Client has sent a response to the Discord API. Once the API was received a response you cannot send another. bool hasResponded = false; InteractionEvent._new(this._client, Map rawJson) { this.interaction = Interaction._new(this._client, rawJson); if (this.interaction.type == 1) { this._pong(); } } /// Used to acknowledge a Interaction but not send any response yet. /// Once this is sent you can then only send ChannelMessages. /// You can also set showSource to also print out the command the user entered. Future acknowledge() async { if (DateTime.now().isAfter(this.receivedAt.add(const Duration(minutes: 15)))) { return Future.error(InteractionExpiredError()); } if (hasResponded) { return Future.error(AlreadyRespondedError()); } final url = "/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback"; final response = await this._client.httpEndpoints.sendRawRequest( url, "POST", body: { "type": 5, "data": null, }, ); if (response is HttpResponseError) { return Future.error(response); } hasResponded = true; } /// Used to acknowledge a Interaction and send a response. /// Once this is sent you can then only send ChannelMessages. /// You can also set showSource to also print out the command the user entered. Future respond({ dynamic content, EmbedBuilder? embed, bool? tts, AllowedMentions? allowedMentions, bool hidden = false}) async { if (DateTime.now().isAfter(this.receivedAt.add(const Duration(minutes: 15)))) { return Future.error(InteractionExpiredError()); } late String url; late Map body; late String method; if (hasResponded) { url = "/webhooks/${this._client.app.id.toString()}/${this.interaction.token}/messages/@original"; body = { "content": content, "embeds": embed != null ? [BuilderUtility.buildRawEmbed(embed)] : null, "allowed_mentions": allowedMentions != null ? BuilderUtility.buildRawAllowedMentions(allowedMentions) : null, "tts": content != null && tts != null && tts }; method = "PATCH"; } else { url = "/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback"; body = { "type": 4, "data": { if (hidden) "flags": 1 << 6, "content": content, "embeds": embed != null ? [BuilderUtility.buildRawEmbed(embed)] : null, "allowed_mentions": allowedMentions != null ? BuilderUtility.buildRawAllowedMentions(allowedMentions) : null, "tts": content != null && tts != null && tts }, }; method = "POST"; } final response = await this._client.httpEndpoints.sendRawRequest( url, method, body: body, ); if (response is HttpResponseError) { return Future.error(response); } hasResponded = true; } /// Create a followup message for an Interaction Future sendFollowup({ dynamic content, EmbedBuilder? embed, bool? tts, AllowedMentions? allowedMentions, bool hidden = false}) async { final url = "/webhooks/${this._client.app.id.toString()}/${this.interaction.token}"; final body = { "content": content, "embeds": embed != null ? [BuilderUtility.buildRawEmbed(embed)] : null, "allowed_mentions": allowedMentions != null ? BuilderUtility.buildRawAllowedMentions(allowedMentions) : null, "tts": content != null && tts != null && tts }; final response = await this._client.httpEndpoints.sendRawRequest( url, "POST", body: body, ); if (response is HttpResponseError) { return Future.error(response); } } /// Should be sent when you receive a ping from interactions. /// Used to acknowledge a ping. Internal to the InteractionEvent. Future _pong() async { if (DateTime.now().isAfter(this.receivedAt.add(const Duration(minutes: 15)))) { return Future.error(InteractionExpiredError()); } if (hasResponded) { return Future.error(InteractionExpiredError()); } final response = await this._client.httpEndpoints.sendRawRequest( "/interactions/${this.interaction.id.toString()}/${this.interaction.token}/callback", "POST", body: { "type": 1, "data": null, }, ); if (response is HttpResponseError) { return Future.error(response); } hasResponded = true; } }