如何使用微信公众平台开发模式实现多客服


Posted in PHP onJanuary 06, 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网页木马一枚 附PHP木马的防范方法
Oct 09 PHP
让PHP支持断点续传的源码
May 16 PHP
hessian 在PHP中的使用介绍
Dec 13 PHP
php产生随机数的两种方法实例代码 输出随机IP
Apr 08 PHP
PHP转换IP地址到真实地址的方法详解
Jun 09 PHP
php设计模式之单例、多例设计模式的应用分析
Jun 30 PHP
php版小黄鸡simsimi聊天机器人接口分享
Jan 26 PHP
destoon公司主页模板风格的添加方法
Jun 20 PHP
php的mkdir()函数创建文件夹比较安全的权限设置方法
Jul 28 PHP
php静态文件生成类实例分析
Jan 03 PHP
Cygwin中安装PHP方法步骤
Jul 04 PHP
php之可变函数的实例详解
Sep 13 PHP
基于PHP技术开发客服工单系统
Jan 06 #PHP
分享php邮件管理器源码
Jan 06 #PHP
CI(Codeigniter)的Setting增强配置类实例
Jan 06 #PHP
WordPress开发中短代码的实现及相关函数使用技巧
Jan 05 #PHP
WordPress开发中用于获取近期文章的PHP函数使用解析
Jan 05 #PHP
Yii中表单用法实例详解
Jan 05 #PHP
php实现购物车功能(下)
Jan 05 #PHP
You might like
PHP 生成的XML以FLASH获取为乱码终极解决
2009/08/07 PHP
一步一步学习PHP(2)――PHP类型
2010/02/15 PHP
深入理解PHP几个算法:PHP冒泡、PHP二分法、PHP求素数、PHP乘法表
2013/06/06 PHP
php获取数组长度的方法(有实例)
2013/10/27 PHP
php对文件夹进行相关操作(遍历、计算大小)
2015/11/04 PHP
php 输入输出流详解及示例代码
2016/08/25 PHP
PHP遍历目录文件的常用方法小结
2017/02/03 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
php 删除指定文件夹的实例讲解
2017/07/25 PHP
PHP排序算法之基数排序(Radix Sort)实例详解
2018/04/21 PHP
一份老外写的XMLHttpRequest代码多浏览器支持兼容性
2007/01/11 Javascript
JQERY limittext 插件0.2版(长内容限制显示)
2010/08/27 Javascript
kmock javascript 单元测试代码
2011/02/06 Javascript
NodeJS使用jQuery选择器操作DOM
2015/02/13 NodeJs
node.js [superAgent] 请求使用示例
2015/03/13 Javascript
vue从使用到源码实现教程详解
2016/09/19 Javascript
nodejs个人博客开发第六步 数据分页
2017/04/12 NodeJs
jQuery手风琴的简单制作
2017/05/12 jQuery
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
vue-cli 3.0 版本与3.0以下版本在搭建项目时的区别详解
2018/12/11 Javascript
jquery实现下载图片功能
2019/07/18 jQuery
JavaScript实现简单随机点名器
2019/11/21 Javascript
详解Python中的序列化与反序列化的使用
2015/06/30 Python
从CentOS安装完成到生成词云python的实例
2017/12/01 Python
python 正则表达式参数替换实例详解
2020/01/17 Python
如何基于python3和Vue实现AES数据加密
2020/03/27 Python
详解Python中string模块除去Str还剩下什么
2020/11/30 Python
HTML5离线缓存Manifest是什么
2016/03/09 HTML / CSS
白宫黑市官网:White House Black Market
2016/11/17 全球购物
定制别致的瑜伽垫:Sugarmat
2019/06/21 全球购物
会计系毕业个人自荐信格式
2013/09/23 职场文书
法律进学校实施方案
2014/03/15 职场文书
个人年底工作总结
2015/03/10 职场文书
2015年助残日活动总结
2015/03/27 职场文书
干部培训简讯
2015/07/20 职场文书
python中的plt.cm.Paired用法说明
2021/05/31 Python