AWS Lambda - Slack bolt error on starting AWSLabmdaReceiver
Closed this issue · 3 comments
Reproducible in:
AWS Lambda
runTime nodejs18.x
The Slack SDK version
├── @slack/bolt@3.17.1
├── aws-sdk@2.1577.0
├── jest@26.6.3
└── serverless-http@2.7.0
slack/bolt": "^3.17.1"
Node.js runtime version
nodejs18.x
OS info
AWS Lambda??
(Paste the output of sw_vers && uname -v
on macOS/Linux or ver
on Windows OS)
Steps to reproduce:
(Share the commands to run, source code, and project settings)
Sam template.yaml
handleCommandFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/handle-command.handleCommandHandler
Runtime: nodejs18.x
Architectures:
- x86_64
MemorySize: 128
Timeout: 100
Description: A simple function that receives an event and sends a response to slack
Role: !GetAtt SieGPTLambdaRole.Arn
Environment:
Variables:
# Make table name accessible as environment variable from function code during execution
SLACK_SIGNING_SECRET:
SLACK_BOT_TOKEN:
SLACK_APP_TOKEN:
Events:
Api:
Type: Api
Properties:
Path: /events
Method: POST
handle-command.mjs
// Create clients and set shared const values outside of the handler.
import pkg from '@slack/bolt';
const { App, AwsLambdaReceiver } = pkg;
const awsLambdaReceiver = new AwsLambdaReceiver({
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
// Initializes your app with your bot token and the AWS Lambda ready receiver
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
receiver: awsLambdaReceiver,
appToken: process.env.SLACK_APP_TOKEN,
});
// require('./lib/bot')(app);
// Listens to incoming messages that contain "hello"
app.message('hello', async ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
await say({
blocks: [
...
],
text: `Hey there <@${message.user}>!`
});
});
// Listens to incoming messages that contain "goodbye"
app.message('goodbye', async ({ message, say }) => {
// say() sends a message to the channel where the event was triggered
await say(`See ya later, <@${message.user}> :wave:`);
});
// Handle the Lambda function event
export const handleCommandHandler = async (event, context, callback) => {
const handler = await awsLambdaReceiver.start();
console.log("Handler result");
console.log(handler);
return handler(event, context, callback);
}
Run lambda deployed as part of specified SAM template and observe error
{
"errorType": "TypeError",
"errorMessage": "Cannot convert undefined or null to object",
"trace": [
"TypeError: Cannot convert undefined or null to object",
" at Function.keys (<anonymous>)",
" at AwsLambdaReceiver.getHeaderValue (/var/task/node_modules/@slack/bolt/dist/receivers/AwsLambdaReceiver.js:186:43)",
" at /var/task/node_modules/@slack/bolt/dist/receivers/AwsLambdaReceiver.js:54:62",
" at Runtime.handleCommandHandler [as handler] (file:///var/task/src/handlers/handle-command.mjs:65:10)"
]
}
Expected result:
No error
Actual result:
Error
Hi @Partynator81, thanks for sharing this. It seems that the request sent to the AwsLambdaReceiver in this scenario does not have any request headers. This means that you sent a test request to the endpoint without any headers, right? If that's the case, indeed, there is a chance to improve this logic not to throw an exception in the scenario. Instead, the handler should reject the request with 400 bad request response.
If the request is a kind of healthcheck request, we recommend dispatching it to a different logic that validates necessary resource availability rather than just passing it to AwsLambdaReceiver.
So yes, this is the case. The issue is visible when testing from the AWS interface using the default event. When testing directly from slack integration, the event has the whole schema and it's decorated with all the headers and the error is not longer present. Sorry for the false alarm, thanks for checking on this.