微信小程序客服消息回复开发
概述
微信小程序为了提高小程序的服务质量,提供了客服消息能力,目的是为了让用户快捷地与小程序服务提供方进行沟通。小程序的客服消息回复有两种方式:一种是接入用户消息到微信公众平台网页版客服工具和客服小助手小程序进行客服消息回复,接入后客服可以看到用户留言,根据用户问题进行专门解答。一种是开启消息推送,当客服无法及时回复的时候能够指导用户联系客服人员或者解决问题。
如果需要接入微信公众平台网页版客服工具和客服小助手,只需要在小程序后台->客服里头添加客服人员就可以,客服人员就可以实时接收到用户消息并且与用户沟通。
如果需要开启消息推送可以参考下文的接入过程。
消息推送开发准备条件
在小程序中设置button组件并且把open-type属性设置为contact
前往小程序后台开发->开发设置->消息推送配置相关信息,可在此指定消息加密方式和数据格式。注意当开启了消息推送,普通微信用户向小程序客服发消息时,微信服务器会先将消息 POST 到开发者填写的 URL 上。在此处的填写我选择的是明文模式和JSON数据格式。
开发过程
处理初次验证
填写完消息推送的配置并且提交后,微信服务器将发送GET请求到填写的URL地址进行校验。因此首先要进行的就是针对微信服务器的初次校验做处理。微信官方在消息推送章节已经提出了校验代码此处便不再重复。
[代码]//微信服务器验证处理
if (isset($_GET['echostr'])) {
//调用微信提供的校验代码
if ($this->checkSignature() == false) {
exit();
}
$echoStr = $_GET['echostr'];
echo $echoStr;
exit;
}
[代码]
处理消息
校验成功后,微信服务器会将用户在客服会话中的消息转发到开发者的服务器上,针对微信服务器传入的消息的类型,开发者们可以编写不同的业务逻辑处理。以用户在客服会话中写入文本为例:根据选择的数据格式JSON或者XML,微信服务器会传入相应格式的数据包。根据"MsgType"可以分辨微信服务器转发的是何种类型消息,并编写不同的业务逻辑。
[代码]//1接受微信推送消息
$message = $GLOBALS["HTTP_RAW_POST_DATA"];
$message = json_decode($message, true);
//2判定用户发送消息的类型
if (!empty($message['MsgType']) && $message['MsgType'] == 'text') {
//do something
}
[代码]
在处理完微信转发的消息之后,开发者可以根需要调用服务端的客服消息发送接口发送消息给用户。
[代码]$fromUsername = $message['FromUserName']; //发送者openid
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=$access_token";//根据需要获取access_token
$data = array(
"touser" => $fromUsername,
"msgtype" => "text",
"text" => array(
"content" => "客服消息推送测试"
)
);
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
$result = httpRequest($url, "post", $data);
$result = json_decode($result, true);
if ($result['errcode'] == 0) { //当处理成功之后返回空字符串或者success都可以防止微信服务器重新发起请求
echo "";
exit;
}
[代码]
转发客服消息
小程序设置了推送消息之后,还可以接入到网页版客服工具中,只需要设置返回数据的MsgType为transfer_customer_service返回给微信服务器。
[代码]//设置转发数据
$transferData = array(
"ToUserName" => $message['FromUserName'],//用户的OpenID
"FromUserName" => $message['ToUserName'],//小程序原始id
"CreateTime" => $message['CreateTime'],//创建时间
"MsgType" => "transfer_customer_service",//指定为transfer_customer_service 消息将会转发到客服工具中
);
$transferData = json_encode($transferData, JSON_UNESCAPED_UNICODE);
[代码]
完整代码演示
[代码]//接受微信服务器转发的请求。
public function getMessage()
{
// 判断是否为微信验证消息
if (isset($_GET['echostr'])) {
if ($this->checkSignature() == false) {
exit();
}
$echoStr = $_GET['echostr'];
echo $echoStr;
exit;
}
//接受微信推送消息
$message = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($message)) {
$access_token = $this->getAccess();//根据需要获取小程序对应的 access_token
//设置转发客服消息
$fromUsername = $message['FromUserName'];//消息发起用户的open_id
$transferData = array(
"ToUserName" => $fromUsername,//接收方帐号(用户的OpenID)
"FromUserName" => $message['ToUserName'],//小程序原始id
"CreateTime" => $message['CreateTime'],//创建时间
"MsgType" => "transfer_customer_service",//指定为transfer_customer_service 消息将会转发到客服工具中
);
$transferData = json_encode($transferData, JSON_UNESCAPED_UNICODE);
$message = json_decode($message, true);
//判定消息类型并处理
if (!empty($message['MsgType']) && $message['MsgType'] == 'text') {
//调用send接口发送相对应的消息
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=$access_token";
$data = array(
"touser" => $fromUsername,
"msgtype" => "text",
"text" => array(
"content" => "客服消息推送测试"
)
);
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
$result = httpRequest($url, "post", $data);
$result = json_decode($result, true);
//回复消息之后 不转发消息到客服系统 返回success 或者空字符串 避免微信提示严重错误
if ($result['errcode'] == 0) {
echo "";
exit;
}
//回复消息之后 转发客服消息到客服系统 将$transferData['MsgType']设置为transfer_customer_service
//if ($result['errcode'] == 0) {
//echo $transferData;
//exit;
//}
}
}
}
/**
* 处理微信验证函数
*/
public function checkSignature()
{
$signature = $_GET['signature'];
$timestamp = $_GET['timestamp'];
$nonce = $_GET['nonce'];
$token = "customer12"; //填写在后台配置的Token(令牌)
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr); //加密
if ($tmpStr == $signature) {
return true;
} else {
return false;
}
}
/**
* CURL请求
* @param $url 请求url地址
* @param $method 请求方法 get post
* @param null $postfields post数据数组
* @param array $headers 请求header信息
* @param bool|false $debug 调试开启 默认false
* @return mixed
*/
function httpRequest($url, $method, $postfields = null, $headers = array(), $debug = false)
{
$method = strtoupper($method);
$ci = curl_init();
curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */
curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
switch ($method) {
case "POST":
curl_setopt($ci, CURLOPT_POST, true);
if (!empty($postfields)) {
$tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
}
break;
default:
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
break;
}
$ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
curl_setopt($ci, CURLOPT_URL, $url);
if ($ssl) {
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
}
curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ci, CURLINFO_HEADER_OUT, true);
$response = curl_exec($ci);
$requestinfo = curl_getinfo($ci);
$http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
if ($debug) {
echo "=====post data======\r\n";
var_dump($postfields);
echo "=====info===== \r\n";
print_r($requestinfo);
echo "=====response=====\r\n";
print_r($response);
}
curl_close($ci);
return $response;
}
[代码]