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

如何在Twilio Serverless Functions中完整录制呼入电话?

在Twilio Serverless Functions中实现完整呼入通话录制的最佳方案

针对你遇到的函数重定向导致录制中断的问题,核心原因是Twilio Serverless Functions的生命周期限制:函数执行完成(包括重定向)后,所有后台异步进程会被终止,因此通过函数内异步调用录制API的方式不可靠。以下是几种可靠的实现机制:

1. 优先使用TwiML直接启用通话级录制

这是最稳定的方案,直接通过返回的TwiML指令让Twilio接管录制流程,完全不受函数生命周期影响,录制会持续到通话结束。

场景1:转接通话时录制

如果你的流程包含转接,在返回的TwiML中给<Dial>标签添加record属性,指定录制模式:

<Response>
  <!-- 录制通话双方音频,从振铃阶段开始 -->
  <Dial record="record-from-ringing-dual" recordingStatusCallback="/handle-recording-status">
    <Number>+1234567890</Number>
  </Dial>
</Response>

record属性可选值:

  • record-from-answer:从接听开始录制
  • record-from-ringing-dual:录制双方音频,从振铃开始
  • true:仅录制主叫方音频

场景2:IVR语音交互录制

如果是纯IVR流程(无转接),可以在<Response>中直接使用<Record>标签,或者启用全局通话录制。若需要多步骤IVR,建议通过Twilio API在通话初始阶段启动全局录制:

exports.handler = async function(context, event, callback) {
  const client = context.getTwilioClient();
  // 启动全局通话录制
  await client.calls(event.CallSid)
    .update({ record: 'record-from-answer' });
  
  const response = new Twilio.twiml.VoiceResponse();
  response.say('欢迎致电,请按1咨询业务,按2转人工');
  response.gather({ numDigits: 1, action: '/ivr-next-step' });
  callback(null, response);
};

2. 条件触发录制时,确保API调用同步完成

如果必须通过复杂条件判断来启动录制,不要在函数后台异步调用录制API,而是用await同步等待API请求完成后,再返回重定向或TwiML:

exports.handler = async function(context, event, callback) {
  const client = context.getTwilioClient();
  const shouldRecord = event.RecordCall === 'true'; // 自定义条件

  if (shouldRecord) {
    // 同步等待录制启动完成
    await client.calls(event.CallSid)
      .recordings
      .create({
        recordFromAnswer: true,
        recordingStatusCallback: '/recording-complete'
      });
  }

  // 录制启动后再重定向到下一个函数
  const response = new Twilio.twiml.VoiceResponse();
  response.redirect('/next-function');
  callback(null, response);
};

这种方式确保录制已经被Twilio的通话服务接管,后续函数重定向不会影响录制进程。

3. 用Recording Status Callback处理录制后续

无论采用哪种方式,都建议设置recordingStatusCallback指向你的Serverless Function,用于接收录制完成、失败等状态通知,方便后续处理录制文件(如存储、转码、通知):

exports.handler = function(context, event, callback) {
  const recordingSid = event.RecordingSid;
  const recordingStatus = event.RecordingStatus;

  if (recordingStatus === 'completed') {
    // 处理完成的录制,比如存储到云存储
    console.log(`录制完成:${recordingSid}`);
  }

  callback(null, new Twilio.twiml.VoiceResponse());
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:46:33