Twilio外呼通话中按数字指令操作的PHP/JavaScript实现方案咨询
在通话过程中触发Twilio DTMF按键的PHP+JavaScript实现方案
你说得没错——仅靠PHP确实没法直接实现通话过程中的实时DTMF按键触发,因为PHP是后端服务端语言,无法直接操控已经建立的实时通话流。我们需要结合Twilio Client JavaScript SDK来处理前端的通话交互,PHP则负责后端的身份验证和Token生成工作。
下面是完整的实现步骤和代码示例:
一、后端PHP:生成Twilio Client身份令牌
首先,你需要用PHP生成Twilio Client的访问令牌,前端JS需要这个令牌来初始化通话连接。确保你已经安装了Twilio的PHP SDK(可以通过Composer安装:composer require twilio/sdk)。
<?php require_once 'vendor/autoload.php'; use Twilio\Jwt\ClientToken; // 替换成你的Twilio账号信息 $accountSid = 'YOUR_TWILIO_ACCOUNT_SID'; $authToken = 'YOUR_TWILIO_AUTH_TOKEN'; $appSid = 'YOUR_TWILIO_TWIML_APP_SID'; // 生成客户端令牌 $token = new ClientToken($accountSid, $authToken, $appSid); echo $token->generateToken(); ?>
二、前端JavaScript:处理通话并发送DTMF
前端部分我们使用Twilio Client SDK来建立通话,并在需要时发送DTMF数字。这里我们做一个简单的示例:包含拨号按钮、通话状态显示,以及发送DTMF的数字按钮。
<!DOCTYPE html> <html> <head> <title>Twilio DTMF Demo</title> <script src="https://sdk.twilio.com/js/client/v1.12/twilio.min.js"></script> </head> <body> <h3>客服中心通话</h3> <button id="callBtn">拨打客服</button> <button id="hangupBtn" disabled>挂断</button> <div id="status"></div> <!-- DTMF按键区域 --> <div id="dtmfKeypad" style="display:none; margin-top:20px;"> <button class="digitBtn">1</button> <button class="digitBtn">2</button> <button class="digitBtn">3</button><br> <button class="digitBtn">4</button> <button class="digitBtn">5</button> <button class="digitBtn">6</button><br> <button class="digitBtn">7</button> <button class="digitBtn">8</button> <button class="digitBtn">9</button><br> <button class="digitBtn">*</button> <button class="digitBtn">0</button> <button class="digitBtn">#</button> </div> <script> // 从后端获取Twilio令牌 fetch('generate-token.php') .then(response => response.text()) .then(token => { // 初始化Twilio Client Twilio.Device.setup(token); let activeConnection = null; // 监听设备就绪事件 Twilio.Device.ready(function(device) { document.getElementById('status').innerText = '设备已就绪,可以拨打通话'; }); // 监听通话连接事件 Twilio.Device.connect(function(connection) { activeConnection = connection; document.getElementById('status').innerText = '通话已连接'; document.getElementById('callBtn').disabled = true; document.getElementById('hangupBtn').disabled = false; document.getElementById('dtmfKeypad').style.display = 'block'; }); // 监听通话断开事件 Twilio.Device.disconnect(function() { activeConnection = null; document.getElementById('status').innerText = '通话已断开'; document.getElementById('callBtn').disabled = false; document.getElementById('hangupBtn').disabled = true; document.getElementById('dtmfKeypad').style.display = 'none'; }); // 拨号按钮点击事件 document.getElementById('callBtn').addEventListener('click', function() { // 替换成你的客服中心号码 Twilio.Device.connect({ number: 'YOUR_SUPPORT_PHONE_NUMBER' }); }); // 挂断按钮点击事件 document.getElementById('hangupBtn').addEventListener('click', function() { if (activeConnection) { activeConnection.disconnect(); } }); // DTMF按键点击事件 document.querySelectorAll('.digitBtn').forEach(btn => { btn.addEventListener('click', function() { if (activeConnection) { // 发送对应的DTMF数字 activeConnection.sendDigits(this.innerText); document.getElementById('status').innerText = `已发送按键: ${this.innerText}`; } }); }); // 监听错误事件 Twilio.Device.error(function(error) { document.getElementById('status').innerText = `错误: ${error.message}`; }); }); </script> </body> </html>
关键说明
- 核心方法:
activeConnection.sendDigits(digits)是实现通话中发送DTMF的关键,这个方法可以接受单个或多个数字(比如sendDigits('123#')可以一次性发送多个按键)。 - 通话状态判断:必须确保在通话处于
connected状态时才能发送DTMF,所以我们通过Twilio.Device.connect事件来获取活跃连接,并控制按键区域的显示。 - 后端Token作用:Twilio Client需要令牌来验证客户端身份,确保通话请求是合法的,这个令牌必须由你的PHP后端生成,不能在前端硬编码敏感信息。
额外注意事项
- 确保你的Twilio TwiML应用配置正确,指向的TwiML端点能正确处理通话请求(比如返回
<Dial>动词连接到客服中心)。 - 测试时需要使用支持WebRTC的浏览器,并且确保你的服务器配置了HTTPS(Twilio Client要求在生产环境使用HTTPS,本地开发可以用ngrok做隧道)。
内容的提问来源于stack exchange,提问作者Osama.octopuspro
相关产品推荐
相关产品推荐

