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

在AWS Lambda生成Twilio访问令牌时遇TypeError: callback is not a function的解决方法

修复AWS Lambda中生成Twilio访问令牌的"TypeError: callback is not a function"错误

这个错误本质上是因为你的generateToken函数期望接收一个回调函数作为参数,但实际调用它的时候要么没传,要么传的不是函数类型。结合AWS Lambda的场景,我帮你梳理两种常见的修复方案:

方案1:如果generateToken是自定义工具函数(非Lambda Handler)

很多开发者会把令牌生成逻辑抽成独立函数,再在Lambda的主处理函数里调用。这种情况下,你需要确保调用时正确传入回调,或者更推荐改成Promise/async-await的写法(适配Lambda的异步运行环境):

const AccessToken = require('twilio').jwt.AccessToken;
const VoiceGrant = AccessToken.VoiceGrant;

// 改成Promise版本的令牌生成函数,避免回调依赖
function generateToken(identity) {
  return new Promise((resolve, reject) => {
    // 注意:敏感信息建议用AWS环境变量/Secrets Manager存储,不要硬编码!
    const accountSid = process.env.TWILIO_ACCOUNT_SID;
    const apiKey = process.env.TWILIO_API_KEY;
    const apiSecret = process.env.TWILIO_API_SECRET;
    const pushCredSid = process.env.TWILIO_PUSH_CRED_SID;
    const outgoingApplicationSid = process.env.TWILIO_OUTGOING_APP_SID; // 补全你之前没写完的参数

    try {
      const voiceGrant = new VoiceGrant({
        pushCredentialSid: pushCredSid,
        outgoingApplicationSid: outgoingApplicationSid
      });

      const token = new AccessToken(
        accountSid,
        apiKey,
        apiSecret,
        { identity: identity }
      );
      token.addGrant(voiceGrant);

      resolve(token.toJwt());
    } catch (err) {
      reject(err);
    }
  });
}

// Lambda的主处理函数
exports.handler = async (event) => {
  try {
    // 从请求事件中获取用户身份标识(比如API Gateway传递的参数)
    const userIdentity = event.queryStringParameters?.identity || 'default-user';
    const token = await generateToken(userIdentity);
    
    return {
      statusCode: 200,
      body: JSON.stringify({ token })
    };
  } catch (error) {
    return {
      statusCode: 500,
      body: JSON.stringify({ error: error.message })
    };
  }
};

方案2:如果generateToken是Lambda的Handler函数

如果你的本意是让generateToken直接作为Lambda的入口函数,那你搞错了Lambda Handler的参数签名!Lambda的Handler函数默认接收event、context、callback三个参数(异步写法可以省略callback),修改后的代码如下:

const AccessToken = require('twilio').jwt.AccessToken;
const VoiceGrant = AccessToken.VoiceGrant;

// 正确的Lambda Handler签名
exports.handler = function(event, context, callback) {
  const userIdentity = event.identity; // 根据你的请求结构获取身份标识
  // 同样建议用环境变量存储敏感信息
  const accountSid = process.env.TWILIO_ACCOUNT_SID;
  const apiKey = process.env.TWILIO_API_KEY;
  const apiSecret = process.env.TWILIO_API_SECRET;
  const pushCredSid = process.env.TWILIO_PUSH_CRED_SID;
  const outgoingApplicationSid = process.env.TWILIO_OUTGOING_APP_SID;

  try {
    const voiceGrant = new VoiceGrant({
      pushCredentialSid: pushCredSid,
      outgoingApplicationSid: outgoingApplicationSid
    });

    const token = new AccessToken(
      accountSid,
      apiKey,
      apiSecret,
      { identity: userIdentity }
    );
    token.addGrant(voiceGrant);

    // 用Lambda的callback返回结果
    callback(null, {
      statusCode: 200,
      body: JSON.stringify({ token: token.toJwt() })
    });
  } catch (error) {
    // 返回错误信息
    callback(error);
  }
};

额外注意事项

  • 确保你已经把Twilio的SDK安装到Lambda的部署包或Lambda层中(npm install twilio)
  • 绝对不要把Twilio的账号SID、API密钥等敏感信息硬编码在代码里,使用AWS环境变量或者Secrets Manager来管理更安全
  • 你代码里的outgoingApplicationSi...没有写完,记得补全对应的应用SID,否则会导致令牌生成失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:22:07