php 微信公众平台开发模式实现多客服的实例代码


Posted in PHP onNovember 07, 2016

其实微信公众平台的多客服功能已经出来好久了,并且一出来的时候我就已经为自己的公众号实现了,原本以为大家都已经会了,但是今天还是有人问起这个多客服功能怎么使用,我找了下网上也没什么好的教程,今天我就给大家发一篇比较简单易懂的教程吧

在这篇微信公众平台开发教程中,我们将介绍如何使用开发模式实现多客服系统。

一、回复多客服消息

在新的微信协议中,开发模式也可以接入客服系统。 开发者如果需要让用户使用客服系统,需要在接收到用户发送的消息时,返回一个MsgType为transfer_customer_service的消息,微信服务器在收到这条消息时,会把用户这次发送的和以后一段时间内发送的消息转发客服系统。

返回的消息举例如下

<xml>
 <ToUserName><![CDATA[touser]]></ToUserName>
 <FromUserName><![CDATA[fromuser]]></FromUserName>
 <CreateTime>1399197672</CreateTime>
 <MsgType><![CDATA[transfer_customer_service]]></MsgType>
</xml>

该消息的实现如下(以方倍工作室的微信公众平台PHP SDK为基础)

//回复多客服消息
 private function transmitService($object)
 {
  $xmlTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[transfer_customer_service]]></MsgType>
</xml>";
  $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
  return $result;
 }

 二、触发多客服会话

一般情况下,用户想要咨询问题是,经常会问“你好”,“在吗”,这样的问题。

我们以这些词为触发关键词,当用户发送的文本消息内容中包含这些词的时候,就返回多客服消息给用户(用户在微信端感觉不到任何内容,但微信公众账号会将用户本次及以后一段时间的消息都转发到客服)。

实现代码如下:

//接收文本消息
 private function receiveText($object)
 {
  $keyword = trim($object->Content);
  if (strstr($keyword, "投诉") || strstr($keyword, "你好") || strstr($keyword, "在吗")){
   $result = $this->transmitService($object);
  }
  return $result;
 }

 三、完整代码

<?php
/*
 方倍工作室
 CopyRight 2014 All Rights Reserved
*/
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
 $wechatObj->responseMsg();
}else{
 $wechatObj->valid();
}
class wechatCallbackapiTest
{
 //验证消息
 public function valid()
 {
  $echoStr = $_GET["echostr"];
  if($this->checkSignature()){
   echo $echoStr;
   exit;
  }
 }
 //检查签名
 private function checkSignature()
 {
  $signature = $_GET["signature"];
  $timestamp = $_GET["timestamp"];
  $nonce = $_GET["nonce"];
  $token = TOKEN;
  $tmpArr = array($token, $timestamp, $nonce);
  sort($tmpArr, SORT_STRING);
  $tmpStr = implode($tmpArr);
  $tmpStr = sha1($tmpStr);
  if($tmpStr == $signature){
   return true;
  }else{
   return false;
  }
 }
 //响应消息
 public function responseMsg()
 {
  $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
  if (!empty($postStr)){
   $this->logger("R ".$postStr);
   $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
   $RX_TYPE = trim($postObj->MsgType);
   switch ($RX_TYPE)
   {
    case "event":
     $result = $this->receiveEvent($postObj);
     break;
    case "text":
     $result = $this->receiveText($postObj);
     break;
   }
   $this->logger("T ".$result);
   echo $result;
  }else {
   echo "";
   exit;
  }
 }
 //接收事件消息
 private function receiveEvent($object)
 {
  switch ($object->Event)
  {
   case "subscribe":
    $content[] = array("Title" =>"欢迎关注方倍工作室", "Description" =>"使用方法:\n1.发送快递单号,例如6367532560,可查询快递详情", "PicUrl" =>"http://www.3856.cc/weixin/weixin/logo.jpg", "Url" =>"");
    break;
   default:
    $content = "receive a new event: ".$object->Event;
    break;
  }
  if(is_array($content)){
   if (isset($content[0])){
    $result = $this->transmitNews($object, $content);
   }else if (isset($content['MusicUrl'])){
    $result = $this->transmitMusic($object, $content);
   }
  }else{
   $result = $this->transmitText($object, $content);
  }
  return $result;
 }
 //接收文本消息
 private function receiveText($object)
 {
  $keyword = trim($object->Content);
  if($keyword == "时间" || $keyword == "测试"){
   $content = date("Y-m-d H:i:s",time());
   $result = $this->transmitText($object, $content);
  }
  //触发多客服模式
  else if (strstr($keyword, "您好") || strstr($keyword, "你好") || strstr($keyword, "在吗") || strstr($keyword, "有人吗")){
   $result = $this->transmitService($object);
   return $result;
  }
  return $result;
 }
 private function transmitText($object, $content)
 {
  $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
  $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
  return $result;
 }
 private function transmitNews($object, $newsArray)
 {
  if(!is_array($newsArray)){
   return;
  }
  $itemTpl = " <item>
  <Title><![CDATA[%s]]></Title>
  <Description><![CDATA[%s]]></Description>
  <PicUrl><![CDATA[%s]]></PicUrl>
  <Url><![CDATA[%s]]></Url>
 </item>
";
  $item_str = "";
  foreach ($newsArray as $item){
   $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
  }
  $newsTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>%s</ArticleCount>
<Articles>
$item_str</Articles>
</xml>";
  $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($newsArray));
  return $result;
 }
 private function transmitMusic($object, $musicArray)
 {
  $itemTpl = "<Music>
 <Title><![CDATA[%s]]></Title>
 <Description><![CDATA[%s]]></Description>
 <MusicUrl><![CDATA[%s]]></MusicUrl>
 <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
</Music>";
  $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);
  $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
$item_str
</xml>";
  $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
  return $result;
 }
 //回复多客服消息
 private function transmitService($object)
 {
  $xmlTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[transfer_customer_service]]></MsgType>
</xml>";
  $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time());
  return $result;
 }
 private function logger($log_content)
 {
  if(isset($_SERVER['HTTP_APPNAME'])){ //SAE
   sae_set_display_errors(false);
   sae_debug($log_content);
   sae_set_display_errors(true);
  }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL
   $max_size = 10000;
   $log_filename = "log.xml";
   if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
   file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);
  }
 }
}
?>

本段代码经过测试,在自定义菜单中返回多客服消息,无法让用户进入多客服状态,使用多客服消息后,后续所有消息在一段时间内都将作为客服消息转发,原来的开发模式下的自动回复都将失效。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
也谈php网站在线人数统计
Apr 09 PHP
使用zend studio for eclipse不能激活代码提示功能的解决办法
Oct 11 PHP
php截取字符串之截取utf8或gbk编码的中英文字符串示例
Mar 12 PHP
PHP入门经历和学习过程分享
Apr 11 PHP
ThinkPHP发送邮件示例代码
Oct 08 PHP
php socket通信简单实现
Nov 18 PHP
PHP迭代器和迭代的实现与使用方法分析
Apr 19 PHP
让Laravel API永远返回JSON格式响应的方法示例
Sep 05 PHP
php数组遍历类与用法示例
May 24 PHP
thinkphp5修改view到根目录实例方法
Jul 02 PHP
php提高脚本性能的4个技巧
Aug 18 PHP
关于PHP求解三数之和问题详析
Nov 09 PHP
深入了解PHP中的Array数组和foreach
Nov 06 #PHP
PHP运行模式汇总
Nov 06 #PHP
PHP数组的定义、初始化和数组元素的显示实现代码
Nov 05 #PHP
PHP中获取文件创建日期、修改日期、访问时间的方法
Nov 05 #PHP
PHP利用超级全局变量$_GET来接收表单数据的实例
Nov 05 #PHP
PHP利用超级全局变量$_POST来接收表单数据的实例
Nov 05 #PHP
PHP中用mysqli面向对象打开连接关闭mysql数据库的方法
Nov 05 #PHP
You might like
php cookie使用方法学习笔记分享
2013/11/07 PHP
PHP常用的小程序代码段
2015/11/14 PHP
从性能方面考虑PHP下载远程文件的3种方法
2015/12/29 PHP
PHP静态延迟绑定和普通静态效率的对比
2017/10/20 PHP
laravel5.0在linux下解决.htaccess无效和去除index.php的问题
2019/10/16 PHP
javascript StringBuilder类实现
2008/12/22 Javascript
XHTML下,JS浮动代码失效的问题
2009/11/12 Javascript
jQuery语法高亮插件支持各种程序源代码语法着色加亮
2013/04/27 Javascript
JS实现动态移动层及拖动浮层关闭的方法
2015/04/30 Javascript
JavaScript对象学习小结
2015/09/02 Javascript
js点击按钮实现带遮罩层的弹出视频效果
2015/12/19 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
2016/05/31 Javascript
js以分隔符分隔数组中的元素并转换为字符串的方法
2016/11/16 Javascript
纯javaScript、jQuery实现个性化图片轮播【推荐】
2017/01/08 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
ES6教程之for循环和Map,Set用法分析
2017/04/10 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
easyui-datagrid开发实践(总结)
2017/08/02 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
2018/05/02 Javascript
微信小程序实现通过js操作wxml的wxss属性示例
2018/12/06 Javascript
基于JavaScript 实现拖放功能
2019/09/12 Javascript
Python面向对象编程中的类和对象学习教程
2015/03/30 Python
13个最常用的Python深度学习库介绍
2017/10/28 Python
用Python登录好友QQ空间点赞的示例代码
2017/11/04 Python
Python3实现发送QQ邮件功能(html)
2017/12/15 Python
Python 类的特殊成员解析
2018/06/20 Python
python实现多层感知器MLP(基于双月数据集)
2019/01/18 Python
关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题
2020/11/24 Python
详解Html5中video标签那些属性和方法
2019/07/01 HTML / CSS
丝绸和人造花卉、植物和树木:Nearly Natural
2018/11/28 全球购物
英国家具、照明、家居用品网上商店:Wayfair.co.uk
2020/02/13 全球购物
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
2019让人心动的商业计划书
2019/06/27 职场文书
nginx配置proxy_pass中url末尾带/与不带/的区别详解
2021/03/31 Servers
Windows server 2003卸载和安装IIS的图文教程
2022/07/15 Servers