UNPKG

discord-bot-cdk-construct

Version:

A quick CDK Construct for creating a serverless Discord bot in AWS!

72 lines 9.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.verifyEvent = exports.handler = void 0; const DiscordSecrets_1 = require("./utils/DiscordSecrets"); const aws_sdk_1 = require("aws-sdk"); const EnvironmentProps_1 = require("./constants/EnvironmentProps"); const tweetnacl_1 = require("tweetnacl"); const lambda = new aws_sdk_1.Lambda(); /** * Handles incoming events from the Discord bot. * @param {IDiscordEventRequest} event The incoming request to handle. * @param {Context} _context The context this request was called with. * @param {Callback} _callback A callback to handle the request. * @return {IDiscordEventResponse} Returns a response to send back to Discord. */ async function handler(event, _context, _callback) { console.log(`Received event: ${JSON.stringify(event)}`); const verifyPromise = verifyEvent(event); if (event) { switch (event.jsonBody.type) { case 1: // Return pongs for pings if (await verifyPromise) { return { type: 1, }; } break; case 2: // Invoke the lambda to respond to the deferred message. const lambdaPromise = lambda.invoke({ FunctionName: EnvironmentProps_1.commandLambdaARN, Payload: JSON.stringify({ ...event, // Hacky workaround due to https://github.com/aws/jsii/issues/3468 guildId: event.jsonBody.data ? ['guild_id'] : undefined, targetId: event.jsonBody.data ? ['target_id'] : undefined, }), InvocationType: 'Event', }).promise(); // Call of the promises and ACK the interaction. // Note that all responses are deferred to meet Discord's 3 second // response time requirement. if (await Promise.all([verifyPromise, lambdaPromise])) { return { type: 5, }; } break; } } throw new Error('[UNAUTHORIZED] invalid request signature'); } exports.handler = handler; /** * Verifies that an event coming from Discord is legitimate. * @param {IDiscordEventRequest} event The event to verify from Discord. * @return {boolean} Returns true if the event was verified, false otherwise. */ async function verifyEvent(event) { try { const discordSecrets = await DiscordSecrets_1.getDiscordSecrets(); const isVerified = tweetnacl_1.sign.detached.verify(Buffer.from(event.timestamp + JSON.stringify(event.jsonBody)), Buffer.from(event.signature, 'hex'), Buffer.from(discordSecrets?.publicKey ?? '', 'hex')); return isVerified; } catch (exception) { console.log(exception); return false; } } exports.verifyEvent = verifyEvent; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGlzY29yZEJvdEZ1bmN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Z1bmN0aW9ucy9EaXNjb3JkQm90RnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsMkRBQXlEO0FBQ3pELHFDQUErQjtBQUMvQixtRUFBOEQ7QUFDOUQseUNBQStCO0FBRS9CLE1BQU0sTUFBTSxHQUFHLElBQUksZ0JBQU0sRUFBRSxDQUFDO0FBRTVCOzs7Ozs7R0FNRztBQUNJLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBMkIsRUFBRSxRQUFpQixFQUN4RSxTQUFtQjtJQUNyQixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUV4RCxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFekMsSUFBSSxLQUFLLEVBQUU7UUFDVCxRQUFRLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO1lBQzNCLEtBQUssQ0FBQztnQkFDSix5QkFBeUI7Z0JBQ3pCLElBQUksTUFBTSxhQUFhLEVBQUU7b0JBQ3ZCLE9BQU87d0JBQ0wsSUFBSSxFQUFFLENBQUM7cUJBQ1IsQ0FBQztpQkFDSDtnQkFDRCxNQUFNO1lBQ1IsS0FBSyxDQUFDO2dCQUNKLHdEQUF3RDtnQkFDeEQsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztvQkFDbEMsWUFBWSxFQUFFLG1DQUFnQjtvQkFDOUIsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7d0JBQ3RCLEdBQUcsS0FBSzt3QkFDUixrRUFBa0U7d0JBQ2xFLE9BQU8sRUFBRyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQVksQ0FBQSxDQUFDLENBQUEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUzt3QkFDOUQsUUFBUSxFQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBWSxDQUFBLENBQUMsQ0FBQSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO3FCQUNqRSxDQUFDO29CQUNGLGNBQWMsRUFBRSxPQUFPO2lCQUN4QixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBRWIsZ0RBQWdEO2dCQUNoRCxrRUFBa0U7Z0JBQ2xFLDZCQUE2QjtnQkFDN0IsSUFBSSxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUMsRUFBRTtvQkFDckQsT0FBTzt3QkFDTCxJQUFJLEVBQUUsQ0FBQztxQkFDUixDQUFDO2lCQUNIO2dCQUNELE1BQU07U0FDVDtLQUNGO0lBRUQsTUFBTSxJQUFJLEtBQUssQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO0FBQzlELENBQUM7QUExQ0QsMEJBMENDO0FBRUQ7Ozs7R0FJRztBQUNJLEtBQUssVUFBVSxXQUFXLENBQUMsS0FBMkI7SUFDM0QsSUFBSTtRQUNGLE1BQU0sY0FBYyxHQUFHLE1BQU0sa0NBQWlCLEVBQUUsQ0FBQztRQUNqRCxNQUFNLFVBQVUsR0FBRyxnQkFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQ25DLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUM3RCxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLEVBQ25DLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLFNBQVMsSUFBSSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQ3RELENBQUM7UUFDRixPQUFPLFVBQVUsQ0FBQztLQUNuQjtJQUFDLE9BQU8sU0FBUyxFQUFFO1FBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkIsT0FBTyxLQUFLLENBQUM7S0FDZDtBQUNILENBQUM7QUFiRCxrQ0FhQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29udGV4dCwgQ2FsbGJhY2t9IGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IHtJRGlzY29yZEV2ZW50UmVxdWVzdH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHtnZXREaXNjb3JkU2VjcmV0c30gZnJvbSAnLi91dGlscy9EaXNjb3JkU2VjcmV0cyc7XG5pbXBvcnQge0xhbWJkYX0gZnJvbSAnYXdzLXNkayc7XG5pbXBvcnQge2NvbW1hbmRMYW1iZGFBUk59IGZyb20gJy4vY29uc3RhbnRzL0Vudmlyb25tZW50UHJvcHMnO1xuaW1wb3J0IHtzaWdufSBmcm9tICd0d2VldG5hY2wnO1xuXG5jb25zdCBsYW1iZGEgPSBuZXcgTGFtYmRhKCk7XG5cbi8qKlxuICogSGFuZGxlcyBpbmNvbWluZyBldmVudHMgZnJvbSB0aGUgRGlzY29yZCBib3QuXG4gKiBAcGFyYW0ge0lEaXNjb3JkRXZlbnRSZXF1ZXN0fSBldmVudCBUaGUgaW5jb21pbmcgcmVxdWVzdCB0byBoYW5kbGUuXG4gKiBAcGFyYW0ge0NvbnRleHR9IF9jb250ZXh0IFRoZSBjb250ZXh0IHRoaXMgcmVxdWVzdCB3YXMgY2FsbGVkIHdpdGguXG4gKiBAcGFyYW0ge0NhbGxiYWNrfSBfY2FsbGJhY2sgQSBjYWxsYmFjayB0byBoYW5kbGUgdGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJuIHtJRGlzY29yZEV2ZW50UmVzcG9uc2V9IFJldHVybnMgYSByZXNwb25zZSB0byBzZW5kIGJhY2sgdG8gRGlzY29yZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IElEaXNjb3JkRXZlbnRSZXF1ZXN0LCBfY29udGV4dDogQ29udGV4dCxcbiAgICBfY2FsbGJhY2s6IENhbGxiYWNrKSB7XG4gIGNvbnNvbGUubG9nKGBSZWNlaXZlZCBldmVudDogJHtKU09OLnN0cmluZ2lmeShldmVudCl9YCk7XG5cbiAgY29uc3QgdmVyaWZ5UHJvbWlzZSA9IHZlcmlmeUV2ZW50KGV2ZW50KTtcblxuICBpZiAoZXZlbnQpIHtcbiAgICBzd2l0Y2ggKGV2ZW50Lmpzb25Cb2R5LnR5cGUpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgLy8gUmV0dXJuIHBvbmdzIGZvciBwaW5nc1xuICAgICAgICBpZiAoYXdhaXQgdmVyaWZ5UHJvbWlzZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0eXBlOiAxLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIC8vIEludm9rZSB0aGUgbGFtYmRhIHRvIHJlc3BvbmQgdG8gdGhlIGRlZmVycmVkIG1lc3NhZ2UuXG4gICAgICAgIGNvbnN0IGxhbWJkYVByb21pc2UgPSBsYW1iZGEuaW52b2tlKHtcbiAgICAgICAgICBGdW5jdGlvbk5hbWU6IGNvbW1hbmRMYW1iZGFBUk4sXG4gICAgICAgICAgUGF5bG9hZDogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgICAvLyBIYWNreSB3b3JrYXJvdW5kIGR1ZSB0byBodHRwczovL2dpdGh1Yi5jb20vYXdzL2pzaWkvaXNzdWVzLzM0NjhcbiAgICAgICAgICAgIGd1aWxkSWQ6IChldmVudC5qc29uQm9keS5kYXRhIGFzIGFueSk/WydndWlsZF9pZCddIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdGFyZ2V0SWQ6IChldmVudC5qc29uQm9keS5kYXRhIGFzIGFueSk/Wyd0YXJnZXRfaWQnXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBJbnZvY2F0aW9uVHlwZTogJ0V2ZW50JyxcbiAgICAgICAgfSkucHJvbWlzZSgpO1xuXG4gICAgICAgIC8vIENhbGwgb2YgdGhlIHByb21pc2VzIGFuZCBBQ0sgdGhlIGludGVyYWN0aW9uLlxuICAgICAgICAvLyBOb3RlIHRoYXQgYWxsIHJlc3BvbnNlcyBhcmUgZGVmZXJyZWQgdG8gbWVldCBEaXNjb3JkJ3MgMyBzZWNvbmRcbiAgICAgICAgLy8gcmVzcG9uc2UgdGltZSByZXF1aXJlbWVudC5cbiAgICAgICAgaWYgKGF3YWl0IFByb21pc2UuYWxsKFt2ZXJpZnlQcm9taXNlLCBsYW1iZGFQcm9taXNlXSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogNSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignW1VOQVVUSE9SSVpFRF0gaW52YWxpZCByZXF1ZXN0IHNpZ25hdHVyZScpO1xufVxuXG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgYW4gZXZlbnQgY29taW5nIGZyb20gRGlzY29yZCBpcyBsZWdpdGltYXRlLlxuICogQHBhcmFtIHtJRGlzY29yZEV2ZW50UmVxdWVzdH0gZXZlbnQgVGhlIGV2ZW50IHRvIHZlcmlmeSBmcm9tIERpc2NvcmQuXG4gKiBAcmV0dXJuIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgdGhlIGV2ZW50IHdhcyB2ZXJpZmllZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmVyaWZ5RXZlbnQoZXZlbnQ6IElEaXNjb3JkRXZlbnRSZXF1ZXN0KTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZGlzY29yZFNlY3JldHMgPSBhd2FpdCBnZXREaXNjb3JkU2VjcmV0cygpO1xuICAgIGNvbnN0IGlzVmVyaWZpZWQgPSBzaWduLmRldGFjaGVkLnZlcmlmeShcbiAgICAgICAgQnVmZmVyLmZyb20oZXZlbnQudGltZXN0YW1wICsgSlNPTi5zdHJpbmdpZnkoZXZlbnQuanNvbkJvZHkpKSxcbiAgICAgICAgQnVmZmVyLmZyb20oZXZlbnQuc2lnbmF0dXJlLCAnaGV4JyksXG4gICAgICAgIEJ1ZmZlci5mcm9tKGRpc2NvcmRTZWNyZXRzPy5wdWJsaWNLZXkgPz8gJycsICdoZXgnKSxcbiAgICApO1xuICAgIHJldHVybiBpc1ZlcmlmaWVkO1xuICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICBjb25zb2xlLmxvZyhleGNlcHRpb24pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19