I'm writing a serverless slack application and have been looking at using interactive-messages.
It seems quite tightly coupled with running a server.
dispatch() is marked as an internal method, however it seems like there should be a way for a serverless setup to manually pass a payload to the dispatcher.
Is this use case documented anywhere?
x in one of the [ ])x in each of the [ ])Filling out the following details about bugs will help us solve your issue sooner.
Select all that apply:
@slack/web-api@slack/events-api@slack/interactive-messages@slack/rtm-api@slack/webhooksUnfortunately, there is no documentation for the use case at the moment.
If your Lambda functions directly use the dispatch method, the functions must remember to do request signature verification like this before dispatching requests.
Considering the circumstances, creating an Express instance and converting it to a Lambda handler (we can use this npm modle by AWS or other options) may be simpler. Also, it makes testing the function on a local machine pretty easy.
The @slack/interactive-messages package exposes a standard node request listener.
You simply called the .requestListener() method on the adapter. You'll find an example in the documentation under the section for "Using an existing HTTP server".
I believe that for most serverless environments, you can implement the function the environment expects by calling the function you get from the method. This is essentially how the popular aws-serverless-express package works. In fact, there's likely some way to use that package to wrap the request listener returned by the adapter in this package, to make it compatible with AWS Lambda. i'm not an expert on this, but it would be great if you shared what you found!
Thanks all,
I managed to get around limitations using the requestListener, but I had to essentially write a mock Response object that聽@slack/interactive-mesages would call on as it is coupled to an http response object in the sendResponse() method
Here's the mock adaptor, I just instantiate it with the callback i'd like called when .end() is hit and the data being set by the sendResponse() is passed to that instead
// emulate a stripped down http response adapter for slack
class ResponseAdapter {
聽 constructor(callback) {
聽 聽 this.callback = callback;
聽 聽 this.headers = {};
聽 聽 this._statusCode = 200;
聽 }
聽 set statusCode(val) {
聽 聽 this._statusCode = val;
聽 }
聽 setHeader(key, val) {
聽 聽 this.headers[key] = val;
聽 }
聽 end(content) {
聽 聽 const data = {
聽 聽 聽 status: this._statusCode,
聽 聽 聽 json: content,
聽 聽 聽 headers: this.headers,
聽 聽 };
聽 聽 this.callback(data);
聽 }
}
and used something like this:
const handler = (req) {
const interactions = createMessageAdapter(process.env.SIGNING_SECRET);
const listen = interactions.requestListener();
// setup handlers
interactions.action(
/*...*/
);
const customResponseCreator = (status, json, headers) => {
// create and process the response I actually need to send
};
const res = new ResponseAdapter(customResponseCreator);
listen(req, res);
Whoa, that鈥檚 pretty neat. Thanks for sharing!
Most helpful comment
Thanks all,
I managed to get around limitations using the
requestListener, but I had to essentially write a mock Response object that聽@slack/interactive-mesages would call on as it is coupled to anhttpresponse object in the sendResponse() methodHere's the mock adaptor, I just instantiate it with the callback i'd like called when
.end()is hit and the data being set by thesendResponse()is passed to that insteadand used something like this: