基于Twilio统计WhatsApp消息会话数的PHP实现及API疑问
针对你提到的Twilio WhatsApp会话计费与PHP实现问题,以下是详细解答:
一、Twilio API能否获取最近会话起始时间?
答案是肯定的,你可以通过两种方式获取会话起始时间:
- 利用Twilio Conversations API(推荐):
发送或接收WhatsApp消息时,每条消息的响应都会包含conversation_id(会话SID)。用这个ID调用Conversations API的会话详情接口,就能拿到会话的date_created字段——这就是会话的起始时间,也就是商家首次发起消息或回复客户消息的瞬间。 - 查询历史消息记录(备用):
如果不想用Conversations API,也可以通过Twilio的Messages API查询同一商家号码(from)与客户号码(to)的所有消息,手动筛选最近的会话起始点:遍历历史消息,找到距离当前时间最近的、与上一条消息间隔超过24小时的那条消息,它的date_created就是新会话的起始时间。这种方式需要遍历历史数据,效率稍低。
二、PHP代码实现方案
核心逻辑
- 发送消息前,查询当前中心与目标客户的最近会话起始时间
- 判断当前时间与会话起始时间的间隔是否超过24小时
- 若超出,更新MySQL数据库中该中心的
remaining_whatsapp_messaging_sessions字段(减1) - 调用Twilio API发送消息,可选记录会话信息以便后续快速查询
代码示例
<?php require_once 'vendor/autoload.php'; use Twilio\Rest\Client; // Twilio配置 $twilioSid = '你的Twilio Account SID'; $twilioToken = '你的Twilio Auth Token'; $twilioWhatsAppNumber = 'whatsapp:+14155238886'; // 替换为你的Twilio WhatsApp号码 // MySQL数据库配置 $dbHost = 'localhost'; $dbUser = '你的数据库用户名'; $dbPass = '你的数据库密码'; $dbName = '你的数据库名'; // 业务参数 $centerId = 1; // 当前操作的社区中心ID $customerPhone = 'whatsapp:+8613xxxxxxxxx'; // 客户的WhatsApp号码(需带whatsapp:前缀) $messageContent = '您好,这里是XX社区中心,您预约的活动将于明天上午9点开始,请准时参加。'; // 初始化Twilio客户端 $twilio = new Client($twilioSid, $twilioToken); /** * 获取中心与客户的最近会话起始时间 * @param string $customerPhone 客户WhatsApp号码 * @param Client $twilio Twilio客户端实例 * @param string $twilioWhatsAppNumber 商家Twilio WhatsApp号码 * @return DateTime|null 会话起始时间,无历史会话则返回null */ function getLatestSessionStartTime($customerPhone, $twilio, $twilioWhatsAppNumber) { // 优先用Conversations API查询 try { // 获取最近一条与该客户的消息 $latestMessages = $twilio->messages->read([ 'from' => $twilioWhatsAppNumber, 'to' => $customerPhone, 'limit' => 1 ]); if (!empty($latestMessages)) { $conversationSid = $latestMessages[0]->conversationSid; // 获取会话详情 $conversation = $twilio->conversations->v1->conversations($conversationSid)->fetch(); return new DateTime($conversation->dateCreated); } } catch (\Exception $e) { // 无历史会话或API调用失败,进入备用方案 } // 备用方案:查询历史消息手动判断会话起始 try { $allMessages = $twilio->messages->read([ 'from' => $twilioWhatsAppNumber, 'to' => $customerPhone ]); if (empty($allMessages)) return null; $sessionStartTime = null; $prevMsgTime = null; foreach ($allMessages as $message) { $currentMsgTime = new DateTime($message->dateCreated); if (!$prevMsgTime) { $prevMsgTime = $currentMsgTime; $sessionStartTime = $currentMsgTime; } else { $interval = $prevMsgTime->diff($currentMsgTime); // 两条消息间隔超过24小时,当前消息为新会话起始 if ($interval->days > 0 || $interval->h >= 24) { $sessionStartTime = $currentMsgTime; } $prevMsgTime = $currentMsgTime; } } return $sessionStartTime; } catch (\Exception $e) { return null; } } // 连接MySQL数据库 $dbConn = new mysqli($dbHost, $dbUser, $dbPass, $dbName); if ($dbConn->connect_error) { die("数据库连接失败: " . $dbConn->connect_error); } // 判断是否需要扣减会话配额 $latestSessionTime = getLatestSessionStartTime($customerPhone, $twilio, $twilioWhatsAppNumber); $currentTime = new DateTime(); $needDeductQuota = false; if (!$latestSessionTime) { // 无历史会话,发送消息将创建新会话,需扣减配额 $needDeductQuota = true; } else { $timeDiff = $currentTime->getTimestamp() - $latestSessionTime->getTimestamp(); // 计算间隔是否超过24小时(86400秒) if ($timeDiff >= 86400) { $needDeductQuota = true; } } if ($needDeductQuota) { // 扣减数据库中的会话配额 $updateStmt = $dbConn->prepare("UPDATE centers SET remaining_whatsapp_messaging_sessions = remaining_whatsapp_messaging_sessions - 1 WHERE id = ?"); $updateStmt->bind_param("i", $centerId); $updateStmt->execute(); $updateStmt->close(); } // 发送WhatsApp消息 try { $sentMessage = $twilio->messages->create( $customerPhone, [ 'from' => $twilioWhatsAppNumber, 'body' => $messageContent ] ); echo "消息发送成功,SID: " . $sentMessage->sid; } catch (\Exception $e) { echo "消息发送失败: " . $e->getMessage(); } // 关闭数据库连接 $dbConn->close(); ?>
关键说明
- 优先使用Conversations API获取会话时间,Twilio会自动维护会话的生命周期,无需手动判断会话间隔,准确性和效率更高。
- 数据库操作使用了预编译语句,避免SQL注入风险。
- 可以在代码中添加配额校验逻辑:如果
remaining_whatsapp_messaging_sessions为0,直接阻止发送消息。
内容的提问来源于stack exchange,提问作者Hagaymosko
相关产品推荐
相关产品推荐

