154 lines
4.9 KiB
Dart
154 lines
4.9 KiB
Dart
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<String, dynamic> 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<void> 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<void> 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<String, dynamic> body;
|
|
late String method;
|
|
|
|
if (hasResponded) {
|
|
url = "/webhooks/${this._client.app.id.toString()}/${this.interaction.token}/messages/@original";
|
|
body = <String, dynamic> {
|
|
"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 = <String, dynamic>{
|
|
"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<void> 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 = <String, dynamic> {
|
|
"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<void> _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;
|
|
}
|
|
}
|