在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
相关产品推荐
相关产品推荐

