This commit is contained in:
Gus Caplan 2020-12-11 13:25:04 -06:00
parent c6f87aa32d
commit a626dc8c41
No known key found for this signature in database
GPG key ID: F00BD11880E82F0E
3 changed files with 57 additions and 28 deletions

View file

@ -1,6 +1,7 @@
'use strict';
const BaseClient = require('./BaseClient');
const APIMessage = require('../structures/APIMessage');
const Interaction = require('../structures/Interaction');
const { ApplicationCommandOptionType, InteractionType, InteractionResponseType } = require('../util/Constants');
@ -37,6 +38,7 @@ class InteractionClient extends BaseClient {
super(options);
this.client = client || this;
this.handler = handler;
this.token = options.token;
this.publicKey = options.publicKey ? Buffer.from(options.publicKey, 'hex') : undefined;
}
@ -87,44 +89,72 @@ class InteractionClient extends BaseClient {
type: InteractionResponseType.PONG,
};
case InteractionType.APPLICATION_COMMAND: {
try {
const interaction = new Interaction(this.client, data);
const result = await this.handler(interaction);
if (result === null) {
return {
type: InteractionResponseType.ACKNOWLEDGE,
};
const interaction = new Interaction(this.client, data);
let done = false;
const r0 = new Promise(resolve => {
this.client.setTimeout(() => {
done = true;
resolve({
type: InteractionResponseType.ACKNOWLEDGE_WITH_SOURCE,
});
}, 500);
});
const r1 = this.handler(interaction).then(async r => {
if (done) {
interaction.reply(r).catch(e => {
this.client.emit('error', e);
});
return undefined;
}
// handle result as message resolvable here, probably DRY this branch with code in
// `Interaction#reply`, except `Interaction#reply` obviously does a POST and this just
// returns the data.
throw new Error('fucc');
} catch (e) {
this.client.emit('error', e);
let apiMessage;
if (r instanceof APIMessage) {
apiMessage = r.resolveData();
} else {
apiMessage = APIMessage.create(interaction, r).resolveData();
if (Array.isArray(apiMessage.data.content)) {
throw new Error();
}
}
const resolved = await apiMessage.resolveFiles();
return {
type: InteractionResponseType.ACKNOWLEDGE,
type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
data: resolved.data,
};
}
});
const result = await Promise.race([r0, r1]);
return result;
}
default:
throw new RangeError('Invalid interaction data');
}
}
async handleFromHTTP(body, signature) {
async handleFromHTTP(body, signature, timestamp) {
if (sodium === undefined) {
sodium = require('../util/Sodium');
}
if (!sodium.methods.verify(Buffer.from(signature, 'hex'), Buffer.from(body), this.publicKey)) {
throw new Error('Invalid signature');
if (!sodium.methods.verify(Buffer.from(signature, 'hex'), Buffer.from(timestamp + body), this.publicKey)) {
return { status: 400, body: '' };
}
const data = JSON.parse(body);
const result = await this.handle(data);
return JSON.stringify(result);
return {
status: 200,
body: JSON.stringify(result),
};
}
async handleFromGateway(data) {
await this.handle(data);
const interaction = new Interaction(this.client, data);
await this.handler(interaction);
}
}

View file

@ -50,19 +50,19 @@ class Interaction extends Base {
* The channel this interaction was sent in.
* @type {Channel}
*/
this.channel = this.client.channels.cache.get(data.channel_id);
this.channel = this.client.channels?.cache.get(data.channel_id);
/**
* The guild this interaction was sent in, if any.
* @type {?Guild}
*/
this.guild = data.guild_id ? this.client.guilds.cache.get(data.guild_id) : null;
this.guild = data.guild_id ? this.client.guilds?.cache.get(data.guild_id) : null;
/**
* If this interaction was sent in a guild, the member which sent it.
* @type {?Member}
*/
this.member = data.member ? this.guild.members.add(data.member, false) : null;
this.member = data.member ? this.guild?.members.add(data.member, false) : null;
}
/**
@ -99,11 +99,9 @@ class Interaction extends Base {
const { data, files } = await apiMessage.resolveFiles();
return this.client.api.interactions(this.id, this.token).callback.post({
data: {
type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
data,
},
return this.client.api.webhooks(this.id, this.token).post({
auth: false,
data,
files,
});
}

View file

@ -700,6 +700,7 @@ exports.InteractionResponseType = {
ACKNOWLEDGE: 2,
CHANNEL_MESSAGE: 3,
CHANNEL_MESSAGE_WITH_SOURCE: 4,
ACKNOWLEDGE_WITH_SOURCE: 5,
};
function keyMirror(arr) {