zoukankan      html  css  js  c++  java
  • 微信公众平台开发(92) 多客服(转)

    关键字:微信公众平台开发 多客服
    作者:方倍工作室
    原文:http://www.cnblogs.com/txw1958/p/weixin-transfer-customer-service.html

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

    本文分为以下三个部分:

    1. 回复多客服消息
    2. 触发多客服会话
    3. 其他说明

     

    一、回复多客服消息

    在新的微信协议中,开发模式也可以接入客服系统。 开发者如果需要让用户使用客服系统,需要在接收到用户发送的消息时,返回一个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;
        }
    复制代码

    http://www.cnblogs.com/txw1958/p/weixin-transfer-customer-service.html

    二、触发多客服会话

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

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

    实现代码如下:

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

     http://www.cnblogs.com/txw1958/p/weixin-transfer-customer-service.html

    三、完整代码

    复制代码
    <?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" =>"使用方法:
    1.发送快递单号,例如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."
    ", FILE_APPEND);
            }
        }
    }
    ?>
    复制代码

    四、其他注意事项

    1. 经测试,在自定义菜单中返回多客服消息,无法让用户进入多客服状态。 

    2. 使用多客服消息后,后续所有消息在一段时间内都将作为客服消息转发,原来的开发模式下的自动回复都将失效!!!

    3. 除了上述程序开发之外,多客服系统还需要进行系统配置。配置的相关内容可参考:

    多客服新手指导 http://www.cnblogs.com/txw1958/p/weixin-multi-customer-service.html

    多客服FAQ   http://wkd.qq.com/php/static/mp/html/faq-1_1.html

    ====================================================================

    方倍工作室微信公众平台账号关注方法:
    1. 微信通讯录-添加朋友-查找公众号-搜索“方倍工作室”
    2. 微信通讯录-添加朋友-搜号码-输入“pondbaystudio”
    3. 使用微信扫描下面的二维码

  • 相关阅读:
    Eclipse / android studio 添加第三方jar包 步骤
    Android checkbox 自定义点击效果
    Android 程序打包和安装过程
    Android 基础
    (转)Genymotion安装virtual device的“unable to create virtual device, Server returned Http status code 0”的解决方法
    (转)eclipse 导入Android 项目 步骤
    微信开放平台注册 步骤
    Android Studio 初级安装
    数组
    作用域问题代码
  • 原文地址:https://www.cnblogs.com/sandea/p/4143450.html
Copyright © 2011-2022 走看看