You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SAM部署@slack/bolt至AWS Lambda时遇类型错误求助

问题解决方案

错误原因分析

  1. Cannot convert undefined or null to object:
    该错误来自AwsLambdaReceiver.getHeaderValue方法,说明传入的事件对象event.headers为null或undefined。同时你的Lambda处理程序在每次请求时都调用awsLambdaReceiver.start(),这会导致接收器重复初始化,引发内部状态异常。

  2. Wrong arguments:
    你的lambdaHandler是异步函数,但同时使用了callback参数,这与Node.js 18.x Lambda运行时的异步处理逻辑冲突,导致运行时无法正确处理返回值。

修复步骤

1. 修正Lambda处理程序代码(app.mjs)

将接收器初始化和启动移到函数外部,避免重复初始化;移除callback参数,改用异步函数的返回值:

import pkg from '@slack/bolt';
const { App, AwsLambdaReceiver } = pkg;

// 初始化接收器(仅执行一次)
const awsLambdaReceiver = new AwsLambdaReceiver({
    signingSecret: process.env.SLACK_SIGNING_SECRET, // 使用环境变量,不要硬编码
});

const app = new App({
  token: process.env.SLACK_BOT_TOKEN, // 使用环境变量
  receiver: awsLambdaReceiver,
});

// 消息监听逻辑不变
app.message('hello', async ({ message, say }) => {
  await say({
    blocks: [
      {
        "type": "section",
        "text": {
          "type": "mrkdwn",
          "text": `Hey there <@${message.user}>!`
        },
        "accessory": {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "Click Me"
          },
          "action_id": "button_click"
        }
      }
    ],
    text: `Hey there <@${message.user}>!`
  });
});

app.action('button_click', async ({ body, ack, say }) => {
  await ack();
  await say(`<@${body.user.id}> clicked the button`);
});

// 启动接收器(仅冷启动时执行一次)
const handler = await awsLambdaReceiver.start();

// 修正后的Lambda处理程序
export const lambdaHandler = async (event, context) => {
    // 禁用Lambda回调上下文,确保异步处理正确
    context.callbackWaitsForEmptyEventLoop = false;
    return handler(event, context);
};

2. 修复SAM模板(template.yaml)

  • 修正HelloWorldFunctionIamRole的输出值(缺少n)
  • 建议添加环境变量配置,避免硬编码敏感信息
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  slack-bot-lambda

  Sample SAM Template for slack-bot-lambda
  
Globals:
  Function:
    Timeout: 10 # 延长超时时间,确保Slack API调用完成
    Environment:
      Variables:
        SLACK_SIGNING_SECRET: "" # 部署时填入或使用Secrets Manager
        SLACK_BOT_TOKEN: ""

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs18.x
      Architectures:
        - x86_64
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello/slack/events
            Method: post

Outputs:
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/slack/events/" # 修正路径为实际事件路径
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn # 修正拼写错误

3. 额外注意事项

  • 环境变量配置:不要在代码中硬编码MY_SIGNING_SECRET和MY_TOKEN,通过Lambda控制台或SAM部署时注入环境变量,敏感信息建议使用AWS Secrets Manager存储。
  • API Gateway路径:确保Slack事件订阅的URL与模板中定义的/hello/slack/events一致,Outputs中的URL也需要同步修正。
  • Lambda超时:默认3秒可能不足以完成Slack API调用,建议延长到10秒。

内容的提问来源于stack exchange,提问作者Tails

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:13:15