slackapi/bolt-js

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.