diff --git a/src/App.ts b/src/App.ts index 8f1f837f2..58b379ae0 100644 --- a/src/App.ts +++ b/src/App.ts @@ -62,6 +62,7 @@ const packageJson = require('../package.json'); // tslint:disable-line:no-requir export interface AppOptions { signingSecret?: ExpressReceiverOptions['signingSecret']; endpoints?: ExpressReceiverOptions['endpoints']; + processBeforeResponse?: ExpressReceiverOptions['processBeforeResponse']; agent?: Agent; clientTls?: Pick; convoStore?: ConversationStore | false; @@ -184,6 +185,7 @@ export default class App { logLevel = undefined, ignoreSelf = true, clientOptions = undefined, + processBeforeResponse = false, }: AppOptions = {}) { if (typeof logger === 'undefined') { @@ -249,6 +251,7 @@ export default class App { this.receiver = new ExpressReceiver({ signingSecret, endpoints, + processBeforeResponse, logger: this.logger, }); } diff --git a/src/ExpressReceiver.spec.ts b/src/ExpressReceiver.spec.ts index e25deb8bd..327474fcf 100644 --- a/src/ExpressReceiver.spec.ts +++ b/src/ExpressReceiver.spec.ts @@ -40,6 +40,7 @@ describe('ExpressReceiver', () => { signingSecret: 'my-secret', logger: noopLogger, endpoints: { events: '/custom-endpoint' }, + processBeforeResponse: true, }); assert.isNotNull(receiver); }); @@ -58,7 +59,7 @@ describe('ExpressReceiver', () => { }); describe('built-in middleware', () => { - describe('ssl_check requset handler', () => { + describe('ssl_check request handler', () => { it('should handle valid requests', async () => { // Arrange // tslint:disable-next-line: no-object-literal-type-assertion diff --git a/src/ExpressReceiver.ts b/src/ExpressReceiver.ts index 19a37ea7c..f125bfafa 100644 --- a/src/ExpressReceiver.ts +++ b/src/ExpressReceiver.ts @@ -17,6 +17,7 @@ export interface ExpressReceiverOptions { endpoints?: string | { [endpointType: string]: string; }; + processBeforeResponse?: boolean; } /** @@ -30,11 +31,13 @@ export default class ExpressReceiver implements Receiver { private server: Server; private bolt: App | undefined; private logger: Logger; + private processBeforeResponse: boolean; constructor({ signingSecret = '', logger = new ConsoleLogger(), endpoints = { events: '/slack/events' }, + processBeforeResponse = false, }: ExpressReceiverOptions) { this.app = express(); // TODO: what about starting an https server instead of http? what about other options to create the server? @@ -47,6 +50,7 @@ export default class ExpressReceiver implements Receiver { this.requestHandler.bind(this), ]; + this.processBeforeResponse = processBeforeResponse; this.logger = logger; const endpointList: string[] = typeof endpoints === 'string' ? [endpoints] : Object.values(endpoints); for (const endpoint of endpointList) { @@ -64,25 +68,41 @@ export default class ExpressReceiver implements Receiver { // tslint:disable-next-line: align }, 3001); + let storedResponse = undefined; const event: ReceiverEvent = { body: req.body, - ack: async (response: any): Promise => { + ack: async (response): Promise => { if (isAcknowledged) { throw new ReceiverMultipleAckError(); } isAcknowledged = true; - if (!response) { - res.send(''); - } else if (typeof response === 'string') { - res.send(response); + if (this.processBeforeResponse) { + if (!response) { + storedResponse = ''; + } else { + storedResponse = response; + } } else { - res.json(response); + if (!response) { + res.send(''); + } else if (typeof response === 'string') { + res.send(response); + } else { + res.json(response); + } } }, }; try { await this.bolt?.processEvent(event); + if (storedResponse !== undefined) { + if (typeof storedResponse === 'string') { + res.send(storedResponse); + } else { + res.json(storedResponse); + } + } } catch (err) { res.send(500); throw err;