本文目录导读:

在 PHP 中实现客服消息回复,主要取决于你使用的是微信公众号、微信小程序还是网页端客服(或第三方平台)。
由于场景不同,代码实现方式差异很大,以下是针对最常见场景(微信小程序/公众号)的完整实现方案,以及针对自建网页客服的方案。
微信小程序 / 微信公众号(最常用)
微信的客服消息机制是“被动回复”+“主动推送”的组合,核心流程是:用户发消息 -> 微信服务器推送到你的服务器 -> 你的服务器处理后返回XML或调用API。
被动回复(5秒内响应)
当用户发消息时,微信会带着用户的 openid 和消息内容 POST 到你的服务器,你需要在5秒内直接输出回复的 XML。
核心代码(reply.php):
<?php
// 1. 验证签名(首次配置时使用,正式运行时也要校验)
function checkSignature() {
$signature = $_GET["signature"] ?? '';
$timestamp = $_GET["timestamp"] ?? '';
$nonce = $_GET["nonce"] ?? '';
$token = "YOUR_TOKEN"; // 你在微信后台填写的自定义Token
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
return $tmpStr === $signature;
}
// 2. 只有首次配置URL时启用GET验证
if ($_SERVER['REQUEST_METHOD'] == 'GET') {
if (checkSignature()) {
echo $_GET["echostr"];
exit;
}
}
// 3. 处理POST请求(用户发来的消息)
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$postStr = file_get_contents("php://input");
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
// 用户OpenID
$fromUsername = $postObj->FromUserName;
// 开发者微信号(你自己的)
$toUsername = $postObj->ToUserName;
// 消息类型(text, image, event等)
$msgType = $postObj->MsgType;
// 用户发送的内容
$content = trim($postObj->Content);
// -------- 自定义智能回复逻辑 --------
$replyContent = "抱歉,小助手暂时不在线。";
if ($msgType == 'text') {
if (mb_strpos($content, '你好') !== false) {
$replyContent = "你好呀!请问有什么可以帮您?";
} elseif (mb_strpos($content, '价格') !== false) {
$replyContent = "我们的报价单已发送至邮箱,请查收。";
} else {
// 这里可以接大模型API(如ChatGPT)或关键词匹配
$replyContent = "您说的是:".$content." 吗?";
}
} elseif ($msgType == 'event') {
// 处理关注/菜单点击事件
$replyContent = "欢迎关注我们的公众号!回复【帮助】获取菜单。";
}
// -------- 结束 --------
// 4. 拼接回复XML
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
// 注意:ToUserName和FromUserName要互换
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $replyContent);
echo $resultStr;
}
?>
⚠️ 注意:
From和To需要互换,因为这是在回复用户。
主动推送(客服接口,48小时内/或特定场景)
如果你需要客服在后台点击某个按钮,主动发送消息给用户(非用户触发),需要使用客服接口。
核心代码(send_customer_service.php):
<?php
// 获取access_token
function getAccessToken() {
$appid = 'YOUR_APPID';
$secret = 'YOUR_APPSECRET';
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
$res = file_get_contents($url);
$data = json_decode($res, true);
return $data['access_token'];
}
// 发送文本客服消息
function sendKfMessage($openid, $text) {
$token = getAccessToken();
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$token}";
$data = [
'touser' => $openid,
'msgtype' => 'text',
'text' => ['content' => $text]
];
$options = [
'http' => [
'header' => "Content-Type: application/json\r\n",
'method' => 'POST',
'content' => json_encode($data, JSON_UNESCAPED_UNICODE)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
return $result;
}
// 示例:给某个用户发消息
$user_openid = '用户openid变量';
sendKfMessage($user_openid, "您好,我是客服小张,您的问题已处理完毕。");
?>
自建网页/App 客服系统(使用 WebSocket 或长轮询)
如果你是想在自己的网页里做类似“聊天窗口”的客服功能,PHP 通常配合 WebSocket 或 SSE,由于 PHP 默认是短生命周期,推荐使用 Workerman 或 Swoole。
这里以 Workerman 为例(最流行的PHP长连接方案),实现客服/用户实时聊天。
核心思路:
- 用户和客服都连接同一个 WebSocket 服务器。
- 服务器转发消息。
核心代码(chat_server.php,基于 Workerman):
<?php
use Workerman\Worker;
use Workerman\Lib\Timer;
require_once __DIR__ . '/vendor/autoload.php'; // 安装: composer require workerman/workerman
$ws_worker = new Worker("websocket://0.0.0.0:2346");
$ws_worker->count = 1;
// 存储用户ID对应的连接
$UidConnections = [];
$ws_worker->onConnect = function($connection) {
echo "新连接建立\n";
};
$ws_worker->onMessage = function($connection, $data) use (&$UidConnections) {
global $ws_worker;
$message = json_decode($data, true);
// 根据消息类型处理
switch ($message['type']) {
case 'login':
// 用户登录,绑定UID
$UidConnections[$message['uid']] = $connection;
$connection->uid = $message['uid'];
break;
case 'chat':
// 客服发给用户,或用户发给客服
$target_uid = $message['to_uid'];
if (isset($UidConnections[$target_uid])) {
$target_connection = $UidConnections[$target_uid];
$target_connection->send(json_encode([
'type' => 'chat',
'from' => $message['from_uid'],
'content' => $message['content']
]));
}
break;
}
};
$ws_worker->onClose = function($connection) use (&$UidConnections) {
// 连接断开时清理
if (isset($connection->uid)) {
unset($UidConnections[$connection->uid]);
}
};
Worker::runAll();
注意:这种方案需要前端 JS 使用 WebSocket 协议连接
ws://你的域名:2346。
对接第三方客服平台(如美洽、网易七鱼)
如果你想快速接入,直接使用第三方客服SDK,PHP只需调用其服务端API获取会话历史和发送消息。
示例(伪代码):
// 调用美洽客服API发送消息
$url = 'https://api.meiqia.com/v1/agent/messages';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'conversation_id' => $conv_id,
'content' => '您好,有什么可以帮您?'
]));
// ... 设置headers和令牌
$response = curl_exec($ch);
总结与建议
- 如果你是新手:优先考虑微信客服接口(场景一),代码量少,容易调试。
- 如果是复杂业务系统:选择 Workerman/Swoole(场景二),能保持长连接,支持多客服并发。
- 如果预算允许:直接接入第三方客服(场景三),省心省力,且自带数据分析。
调试注意:
- 微信服务器要求你在后台配置服务器URL,且必须是HTTPS(生产环境)。
- 服务器必须能正常接收GET验证请求,否则配置失败。
- 日志调试:建议将接收到的
$postStr写入日志文件,便于排查问题。