微信企业号客服功能开发PHP

思路

1.点击应用的菜单-在线客服-触发事件

$result1 = $this->receiveEvent($postObj);

2.分配客服 - 使用缓存memcache进行存储分配客服的信息(项目部署在sae,所以在sae上面开启memcache即可)

$mmc = memcache_init();   //初始化缓存
memcache_set($mmc, "service", '{"from":"'.$from.'","to":"'.$to.'"}');  //分配的信息

3.发送信息接入客服和用户

$this->send_custom_msg($from, "text",  "正在为您接入客服,请稍候..");

4.断开连接,结束在线客服模式

memcache_delete($mmc, "service");

回调模式

对企业号进行开发的必要条件,就是开启回调模式。

开启回调

index.php

/*
------------验证回调URL---------------
*企业开启回调模式时,企业号会向验证url发送一个get请求 
假设点击验证时,企业收到类似请求:
* GET /cgi-bin/wxpush?msg_signature=5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3&timestamp=1409659589&nonce=263014780&echostr=P9nAzCzyDtyTWESHep1vC5X9xho%2FqYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp%2B4RPcs8TgAE7OaBO%2BFZXvnaqQ%3D%3D 
* HTTP/1.1 Host: qy.weixin.qq.com
接收到该请求时,企业应
1.解析出Get请求的参数,包括消息体签名(msg_signature),时间戳(timestamp),随机数字串(nonce)以及公众平台推送过来的随机加密字符串(echostr),
这一步注意作URL解码。
2.验证消息体签名的正确性 
3. 解密出echostr原文,将原文当作Get请求的response,返回给公众平台
第2,3步可以用公众平台提供的库函数VerifyURL来实现。
*/
<?php
include_once "inc/WXBizMsgCrypt.php";    //企业微信接口可下载此文件  ①
include_once "information.php";			//此为在线客服功能方法类文件
include_once "constant.php";			//静态参数类

//如下参数静态定义在constant.php,其值与企业微信相应值对应
$encodingAesKey= Constant::$EncodingAesKey;   
$token = Constant::$Token;
$corpId = Constant::$CorpId;

$sVMsgSig = $_GET['msg_signature'];    //消息体签名
$sVTimeStamp = $_GET['timestamp'];     //时间戳
$sVNonce = $_GET['nonce'];				//随机字符串
$sVEchoStr = $_GET['echostr']; 			//随机加密字符串

$wxcpt = new WXBizMsgCrypt($token, $encodingAesKey, $corpId); 
if($sVEchoStr){
$sEchoStr = "";
$errCode = $wxcpt->VerifyURL($sVMsgSig, $sVTimeStamp, $sVNonce, $sVEchoStr, $sEchoStr);
if ($errCode == 0) {
echo $sEchoStr;
} else {
print($errCode . "\n\n");
}
exit;
}else{
	$wechatObj = new information();    //在线客服类
    $wechatObj->responseMsg();
}

①代码地址:WXBizMsgCrypt.php

菜单

$menu = '{
     "button":[{
     		"name":"点我其他",
            "sub_button":[
            {
            	"type":"clik",
                "name":"其他",
                "key":"qt"
            },
            {
            	"type":"click", 
                "name":"在线客服",
                "key":"qt_kf"
            }]
          
      }]
 }';
$corpsecret = Constant::$Corpsecret;
$corpId = Constant::$CorpId;
//获取token的url
$url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$corpId&corpsecret=$corpsecret";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$jsoninfo = json_decode($output, true);
$access_token = $jsoninfo["access_token"];

$agentid = Constant::$Agentid;  
//创建菜单的url
$url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=$access_token&agentid=$agentid";
$result = https_request($url, $jsonmenu);  

function https_request($url,$data = null){
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    if (!empty($data)){
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
}

在线客服

information.php

<?php
include_once "inc/WXBizMsgCrypt.php";
include_once "constant.php";
/**
------------在线客服---------------
1、用户点击菜单在线客服,判断memcache状态
2、若存在,则发送等待信息至用户
3、若不存在,则初始化memcache,并发送相应连接客服信息至用户以及客服
4、客服发信息,则至用户;用户发信息,则至客服
5、直至客服点击菜单在线客服,则结束连接
注:此memcache需在sae上开启的memcache,否则无效
*/
class information
        {
        	public function responseMsg()
            {
                $encodingAesKey = Constant::$EncodingAesKey; 
                $token = Constant::$Token;
                $corpId = Constant::$CorpId;  
                $agentId = Constant::$Agentid;  
                
            	$wxcpt = new WXBizMsgCrypt($token, $encodingAesKey, $corpId);
            	
                $sReqMsgSig = $_GET["msg_signature"];
                $sReqTimeStamp = $_GET["timestamp"];
                $sReqNonce =$_GET["nonce"];
                $sReqData =  file_get_contents('php://input');  
                $sMsg = ""; // 解析之后的明文
                
                $errCode = $wxcpt->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData, $sMsg);
                if ($errCode == 0) {
                    $postStr=$sMsg;
                    $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                    $result1= "";
                    $RX_TYPE = trim($postObj->MsgType);
                    switch($RX_TYPE)
                    {
                        case "text":  //文本消息
                        	$result1 = $this->receiveText($postObj);
                        	break;
                        case "image":  //图文消息
                        	$result1 = $this->receiveImage($postObj);
                    	   	break;
                        case "event":  //事件   触发在线客服连接,以及断开在线客服连接
                            $result1 = $this->receiveEvent($postObj);
                            break;
                        default:
                        	$result1 = "unknow msg type:".$RX_TYPE;
                        	break;
                    }
                     //加密输出
                    $sEncryptMsg = "";
                    //xml格式的密文
                    $errCode = $wxcpt->EncryptMsg($result1, $sReqTimeStamp, $sReqNonce, $sEncryptMsg);
                    if ($errCode == 0) {
                        echo $sEncryptMsg;
                    } else {
                        print("ERR: " . $errCode . "\n\n");	
                    }
                } else {
                        print("ERR: " . $errCode . "\n\n");	
                    } 
            }
         }   
            

客服用户对话连接

 private function receiveEvent($object)  
            {
            	$content = "";
                switch($object->Event){
                    case "click":
                        switch($object->EventKey)
                        {
                            case "qt_kf":
                                $mmc = memcache_init();
                                //客服单击,结束对话
                                if($object->FromUserName== Constant::$Staff1 ){
                                    $service = memcache_get($mmc,"service");
                                    $relation = json_decode($service, true);
                                    $from = $relation['to'];
                                    $to = $relation['from'];
                                    $this->send_custom_msg($from, "text", "你已结束本次对话!");
                                    $this->send_custom_msg($to, "text", "感谢您的咨询。期待下次再会!");
                                    memcache_delete($mmc, "service");  //删除memcache
                                }
                                else{	//用户单机,开始对话
                                    $service = memcache_get($mmc,"service");
                                    $relation = json_decode($service, true);
                                    if($relation['from'] == null)
                                    {
                                        $from =strval($object->FromUserName);
                                        $to = Constant::$Staff1;
                                        memcache_set($mmc, "service", '{"from":"'.$from.'","to":"'.$to.'"}');
                                        $this->send_custom_msg($from, "text",  "正在为您接入客服,请稍候..");
                                        $this->send_custom_msg($to, "text", "有用户请求接入,请响应!");
                                    }else {     //如有memcache,则提示占线
                                    	$from =strval($object->FromUserName);
                                        if($from != $relation['from']){
                                        	$this->send_custom_msg($from, "text",  "在线客服占线,请稍后再试。");
                                        }
                                    }
                                }
                                
                                return;
                            default:
                                $content = "菜单默认回复";
                                break;
                        }
                        break;
                }
                if(is_array($content)){
                	$result = $this->transmitNews($object,$content);
                }else{
                	$result = $this->transmitText($object,$content);
                }
                
                return $result;
            }

接收文本信息

/**
用户和客服之间的文本交互,若是在线客服功能已连接,则通过此方法,进行信息传递
*/
private function receiveText($object)   //文本消息
            {
                $keyword = trim($object->Content);
                $mmc = memcache_init();   //初始化memcache
                $service = memcache_get($mmc, "service");
                if($service){  //当前有人工客服对话
                	$relation = json_decode($service, true);
                    //用户处在人工客服交互中
                    if(in_array($object->FromUserName, $relation))
                    {
                    	$to = ($relation['from'] == strval($object->FromUserName))?$relation['to']:$relation['from'];
                        
                        $this->send_custom_msg($to, "text", $keyword);
                        return;
                    }
                    $content = "";
                    if(is_array($content)){
                    	$result = $this->transmitNews($object, $content);
                        
                    }else{
                    	$result = $this->transmitText($object, $content);
                    }
                } 
                return $result;
                }

发送文本信息

public function send_custom_msg($from, $type, $content) 
            {
                $access_token = $this->getAccessToken();    //获取access_token
                //发送信息的url
                $sendmsg_url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=$access_token";
				//信息格式
				$data ='{ "touser": "'.$from.'",   
                "toparty": "", 
                "totag": "", 
                "msgtype": "text", 
                "agentid": 0, 
                "text": { "content": "'.$content.'" }, 
                "safe": "0" }'; 
                return $this->mn_post($sendmsg_url,$data);
            }

		//获取access_token
            private function getAccessToken(){
            	$corpid = Constant::$CorpId; 
                $corpsecret = Constant::$Corpsecret;
                
                $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$corpid&corpsecret=$corpsecret";

                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                $output = curl_exec($ch);
                curl_close($ch);
                $jsoninfo = json_decode($output, true);
                $access_token = $jsoninfo["access_token"];
                return $access_token;
            }
             function mn_post($url,$data){ // 模拟提交数据函数 
                $curl = curl_init();   // 启动一个CURL会话 
                curl_setopt($curl, CURLOPT_URL, $url);  // 要访问的地址 
                curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测 
                curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1); // 从证书中检查SSL加密算法是否存在 
                curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览 
                curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:')); //解决数据包大不能提交 
                curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转 
                curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer 
                curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求 
                curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包 
                curl_setopt($curl, CURLOPT_COOKIEFILE, $GLOBALS['cookie_file']); // 读取上面所储存的Cookie信息 
                curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循 
                curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容 
                curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回   
                $tmpInfo = curl_exec($curl); // 执行操作 
                if (curl_errno($curl)) { 
                    echo 'Errno'.curl_error($curl); 
                } 
                curl_close($curl); // 关键CURL会话 
                return $tmpInfo; // 返回数据 
			} 

多客服

如需开发多客服功能,则参考微信企业号多客服功能开发

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值