detritus-client
Version:
A Typescript NodeJS library to interact with Discord's API, both Rest and Gateway.
482 lines (481 loc) • 19 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InteractionDataComponent = exports.InteractionDataApplicationCommandResolved = exports.InteractionDataApplicationCommandOption = exports.InteractionDataApplicationCommand = exports.Interaction = void 0;
const basecollection_1 = require("../collections/basecollection");
const baseset_1 = require("../collections/baseset");
const constants_1 = require("../constants");
const utils_1 = require("../utils");
const basestructure_1 = require("./basestructure");
const channel_1 = require("./channel");
const member_1 = require("./member");
const message_1 = require("./message");
const role_1 = require("./role");
const user_1 = require("./user");
const DEFERRED_TYPES = Object.freeze([
constants_1.InteractionCallbackTypes.DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE,
constants_1.InteractionCallbackTypes.DEFERRED_UPDATE_MESSAGE,
]);
const keysInteraction = new baseset_1.BaseSet([
constants_1.DiscordKeys.APPLICATION_ID,
constants_1.DiscordKeys.CHANNEL_ID,
constants_1.DiscordKeys.DATA,
constants_1.DiscordKeys.GUILD_ID,
constants_1.DiscordKeys.ID,
constants_1.DiscordKeys.MEMBER,
constants_1.DiscordKeys.MESSAGE,
constants_1.DiscordKeys.TOKEN,
constants_1.DiscordKeys.TYPE,
constants_1.DiscordKeys.USER,
constants_1.DiscordKeys.VERSION,
]);
const keysMergeInteraction = new baseset_1.BaseSet([
constants_1.DiscordKeys.GUILD_ID,
constants_1.DiscordKeys.MEMBER,
constants_1.DiscordKeys.TYPE,
]);
/**
* Interaction Structure
* @category Structure
*/
class Interaction extends basestructure_1.BaseStructure {
constructor(client, data, isClone) {
super(client, undefined, isClone);
this._keys = keysInteraction;
this._keysMerge = keysMergeInteraction;
this._deleted = false;
this.applicationId = '';
this.id = '';
this.responded = false;
this.token = '';
this.type = constants_1.InteractionTypes.PING;
this.version = 0;
this.merge(data);
}
get channel() {
if (this.channelId) {
return this.client.channels.get(this.channelId) || null;
}
return null;
}
get createdAt() {
return new Date(this.createdAtUnix);
}
get createdAtUnix() {
return utils_1.Snowflake.timestamp(this.id);
}
get deleted() {
if (!this._deleted) {
const didTimeout = constants_1.INTERACTION_TIMEOUT <= (Date.now() - this.createdAtUnix);
if (didTimeout) {
Object.defineProperty(this, '_deleted', { value: didTimeout });
this.client.interactions.delete(this.id);
}
}
return this._deleted;
}
get guild() {
if (this.guildId) {
return this.client.guilds.get(this.guildId) || null;
}
return null;
}
get inDm() {
return !this.member;
}
get isFromApplicationCommand() {
return this.type === constants_1.InteractionTypes.APPLICATION_COMMAND;
}
get isFromMessageComponent() {
return this.type === constants_1.InteractionTypes.MESSAGE_COMPONENT;
}
get response() {
if (this.responseId) {
return this.client.messages.get(this.responseId) || null;
}
return null;
}
get userId() {
return this.user.id;
}
createMessage(options = {}) {
return this.client.rest.executeWebhook(this.applicationId, this.token, options);
}
async createResponse(options, data) {
this.responded = true;
try {
if (this.isFromMessageComponent) {
const toAssignData = (typeof (options) === 'object') ? options.data || data : data;
if (typeof (toAssignData) === 'object' && toAssignData.components) {
const listenerId = (this.message) ? this.message.id : '';
Object.assign(toAssignData, { listenerId });
}
}
return await this.client.rest.createInteractionResponse(this.id, this.token, options, data);
}
catch (error) {
this.responded = false;
throw error;
}
}
deleteMessage(messageId) {
return this.client.rest.deleteWebhookTokenMessage(this.applicationId, this.token, messageId);
}
deleteResponse() {
return this.deleteMessage('@original');
}
editMessage(messageId, options = {}) {
return this.client.rest.editWebhookTokenMessage(this.applicationId, this.token, messageId, options);
}
editResponse(options = {}) {
return this.editMessage('@original', options);
}
editOrRespond(options = {}) {
// try respond, try edit, try followup
if (this.responded) {
if (typeof (options) === 'string') {
options = { content: options };
}
return this.editResponse(options);
}
let type = constants_1.InteractionCallbackTypes.CHANNEL_MESSAGE_WITH_SOURCE;
switch (this.type) {
case constants_1.InteractionTypes.APPLICATION_COMMAND:
type = constants_1.InteractionCallbackTypes.CHANNEL_MESSAGE_WITH_SOURCE;
break;
case constants_1.InteractionTypes.MESSAGE_COMPONENT:
type = constants_1.InteractionCallbackTypes.UPDATE_MESSAGE;
break;
}
return this.respond(type, options);
}
fetchMessage(messageId) {
return this.client.rest.fetchWebhookTokenMessage(this.applicationId, this.token, messageId);
}
fetchResponse() {
return this.fetchMessage('@original');
}
reply(options = {}) {
return this.createMessage(options);
}
respond(options, data) {
return this.createResponse(options, data);
}
mergeValue(key, value) {
if (value !== undefined) {
switch (key) {
case constants_1.DiscordKeys.DATA:
{
switch (this.type) {
case constants_1.InteractionTypes.PING:
{
}
;
break;
case constants_1.InteractionTypes.APPLICATION_COMMAND:
{
value = new InteractionDataApplicationCommand(this, value);
}
;
break;
case constants_1.InteractionTypes.MESSAGE_COMPONENT:
{
value = new InteractionDataComponent(this, value);
}
;
break;
}
}
;
break;
case constants_1.DiscordKeys.MEMBER:
{
value.guild_id = this.guildId;
value = new member_1.Member(this.client, value, true);
this.user = value.user;
}
;
break;
case constants_1.DiscordKeys.MESSAGE:
{
value = new message_1.Message(this.client, value, true);
}
;
break;
case constants_1.DiscordKeys.USER:
{
value = new user_1.User(this.client, value, true);
}
;
break;
}
return super.mergeValue(key, value);
}
}
}
exports.Interaction = Interaction;
const keysInteractionDataApplicationCommand = new baseset_1.BaseSet([
constants_1.DiscordKeys.ID,
constants_1.DiscordKeys.NAME,
constants_1.DiscordKeys.OPTIONS,
constants_1.DiscordKeys.RESOLVED,
constants_1.DiscordKeys.TARGET_ID,
constants_1.DiscordKeys.TYPE,
]);
/**
* Interaction Data Application Command Structure
* @category Structure
*/
class InteractionDataApplicationCommand extends basestructure_1.BaseStructure {
constructor(interaction, data, isClone) {
super(interaction.client, undefined, isClone);
this._keys = keysInteractionDataApplicationCommand;
this.id = '';
this.name = '';
this.type = constants_1.ApplicationCommandTypes.CHAT_INPUT;
this.interaction = interaction;
this.merge(data);
Object.defineProperty(this, 'interaction', { enumerable: false });
}
get fullName() {
if (this.options && this.options.length) {
const option = this.options.first();
if (option.isSubCommand || option.isSubCommandGroup) {
return `${this.name} ${option.fullName}`;
}
}
return this.name;
}
get isContextCommand() {
return this.isContextCommandMessage || this.isContextCommandUser;
}
get isContextCommandMessage() {
return this.type === constants_1.ApplicationCommandTypes.MESSAGE;
}
get isContextCommandUser() {
return this.type === constants_1.ApplicationCommandTypes.USER;
}
get isSlashCommand() {
return this.type === constants_1.ApplicationCommandTypes.CHAT_INPUT;
}
mergeValue(key, value) {
if (value !== undefined) {
switch (key) {
case constants_1.DiscordKeys.OPTIONS:
{
if (!this.options) {
this.options = new basecollection_1.BaseCollection();
}
this.options.clear();
for (let raw of value) {
const option = new InteractionDataApplicationCommandOption(this, raw, this.isClone);
this.options.set(option.name, option);
}
}
;
return;
case constants_1.DiscordKeys.RESOLVED:
{
value = new InteractionDataApplicationCommandResolved(this, value, this.isClone);
}
;
break;
}
return super.mergeValue(key, value);
}
}
toString() {
return this.fullName;
}
}
exports.InteractionDataApplicationCommand = InteractionDataApplicationCommand;
const keysInteractionDataApplicationCommandOption = new baseset_1.BaseSet([
constants_1.DiscordKeys.NAME,
constants_1.DiscordKeys.OPTIONS,
constants_1.DiscordKeys.TYPE,
constants_1.DiscordKeys.VALUE,
]);
/**
* Interaction Data Application Command Option Structure
* @category Structure
*/
class InteractionDataApplicationCommandOption extends basestructure_1.BaseStructure {
constructor(interactionData, data, isClone) {
super(interactionData.client, undefined, isClone);
this._keys = keysInteractionDataApplicationCommandOption;
this.name = '';
this.type = constants_1.ApplicationCommandOptionTypes.SUB_COMMAND;
this.interactionData = interactionData;
this.merge(data);
Object.defineProperty(this, 'interactionData', { enumerable: false });
}
get fullName() {
if (this.isSubCommandGroup && this.options && this.options.length) {
const option = this.options.first();
return `${this.name} ${option.fullName}`;
}
return this.name;
}
get isSubCommand() {
return this.type === constants_1.ApplicationCommandOptionTypes.SUB_COMMAND;
}
get isSubCommandGroup() {
return this.type === constants_1.ApplicationCommandOptionTypes.SUB_COMMAND_GROUP;
}
mergeValue(key, value) {
if (value !== undefined) {
switch (key) {
case constants_1.DiscordKeys.OPTIONS:
{
if (!this.options) {
this.options = new basecollection_1.BaseCollection();
}
this.options.clear();
for (let raw of value) {
const option = new InteractionDataApplicationCommandOption(this.interactionData, raw, this.isClone);
this.options.set(option.name, option);
}
}
;
return;
}
return super.mergeValue(key, value);
}
}
}
exports.InteractionDataApplicationCommandOption = InteractionDataApplicationCommandOption;
const keysInteractionDataApplicationCommandResolved = new baseset_1.BaseSet([
constants_1.DiscordKeys.CHANNELS,
constants_1.DiscordKeys.MEMBERS,
constants_1.DiscordKeys.MESSAGES,
constants_1.DiscordKeys.ROLES,
constants_1.DiscordKeys.USERS,
]);
const keysMergeInteractionDataApplicationCommandResolved = new baseset_1.BaseSet([
constants_1.DiscordKeys.USERS,
]);
/**
* Interaction Data Application Command Resolved Structure
* @category Structure
*/
class InteractionDataApplicationCommandResolved extends basestructure_1.BaseStructure {
constructor(interactionData, data, isClone) {
super(interactionData.client, undefined, isClone);
this._keys = keysInteractionDataApplicationCommandResolved;
this._keysMerge = keysMergeInteractionDataApplicationCommandResolved;
this.interactionData = interactionData;
this.merge(data);
Object.defineProperty(this, 'interactionData', { enumerable: false });
}
get guildId() {
return this.interactionData.interaction.guildId || null;
}
mergeValue(key, value) {
if (value !== undefined) {
switch (key) {
case constants_1.DiscordKeys.CHANNELS:
{
if (!this.channels) {
this.channels = new basecollection_1.BaseCollection();
}
this.channels.clear();
for (let channelId in value) {
let channel;
if (this.client.channels.has(channelId)) {
channel = this.client.channels.get(channelId);
// do we want to just create it like below? or merge the values?
// not sure if discord verifies the data
}
else {
value[channelId][constants_1.DiscordKeys.GUILD_ID] = this.guildId;
channel = channel_1.createChannelFromData(this.client, value[channelId]);
}
this.channels.set(channelId, channel);
}
}
;
return;
case constants_1.DiscordKeys.MEMBERS:
{
if (!this.members) {
this.members = new basecollection_1.BaseCollection();
}
this.members.clear();
for (let userId in value) {
value[userId][constants_1.DiscordKeys.GUILD_ID] = this.guildId;
const member = new member_1.Member(this.client, value[userId], true);
if (!member.user) {
member.user = (this.users) ? this.users.get(userId) : this.client.users.get(userId);
}
this.members.set(userId, member);
}
}
;
return;
case constants_1.DiscordKeys.MESSAGES:
{
if (!this.messages) {
this.messages = new basecollection_1.BaseCollection();
}
this.messages.clear();
for (let messageId in value) {
value[messageId][constants_1.DiscordKeys.GUILD_ID] = this.guildId;
const message = new message_1.Message(this.client, value[messageId], true);
this.messages.set(messageId, message);
}
}
;
return;
case constants_1.DiscordKeys.ROLES:
{
if (!this.roles) {
this.roles = new basecollection_1.BaseCollection();
}
this.roles.clear();
for (let roleId in value) {
value[roleId][constants_1.DiscordKeys.GUILD_ID] = this.guildId;
const role = new role_1.Role(this.client, value[roleId]);
this.roles.set(roleId, role);
}
}
;
return;
case constants_1.DiscordKeys.USERS:
{
if (!this.users) {
this.users = new basecollection_1.BaseCollection();
}
this.users.clear();
for (let userId in value) {
const user = new user_1.User(this.client, value[userId]);
this.users.set(userId, user);
}
}
;
return;
}
return super.mergeValue(key, value);
}
}
}
exports.InteractionDataApplicationCommandResolved = InteractionDataApplicationCommandResolved;
const keysInteractionDataComponent = new baseset_1.BaseSet([
constants_1.DiscordKeys.COMPONENT_TYPE,
constants_1.DiscordKeys.CUSTOM_ID,
constants_1.DiscordKeys.VALUES,
]);
/**
* Interaction Data Component Structure
* @category Structure
*/
class InteractionDataComponent extends basestructure_1.BaseStructure {
constructor(interaction, data, isClone) {
super(interaction.client, undefined, isClone);
this._keys = keysInteractionDataComponent;
this.componentType = constants_1.MessageComponentTypes.BUTTON;
this.customId = '';
this.interaction = interaction;
this.merge(data);
Object.defineProperty(this, 'interaction', { enumerable: false });
}
}
exports.InteractionDataComponent = InteractionDataComponent;