responseMsg();// 这里区分下是测试还是商用 . }else{ $wechatObj->responseMsgsq();// 这里区分下是测试还是商用 . } }else{ $wechatObj->valid(); } class wechatCallbackapiTest { //验证签名 public function valid() { $echoStr = $_GET["echostr"]; $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $tmpArr = array(TOKEN, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if($tmpStr == $signature){ echo $echoStr; exit; } } //响应消息 审核 public function responseMsgsq() { $timestamp = $_GET['timestamp']; $nonce = $_GET["nonce"]; $msg_signature = $_GET['msg_signature']; $encrypt_type = (isset($_GET['encrypt_type']) && ($_GET['encrypt_type'] == 'aes')) ? "aes" : "raw"; $this->logger('APPID:'.$_GET['APPID']); $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)){ //解密 if ($encrypt_type == 'aes'){ $pc = new WXBizMsgCrypt(TOKEN, EncodingAESKey, AppID); $this->logger(" D \r\n".$postStr); $decryptMsg = ""; //解密后的明文 $errCode = $pc->DecryptMsg($msg_signature, $timestamp, $nonce, $postStr, $decryptMsg); $postStr = $decryptMsg; } $this->logger(" R \r\n".$postStr); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $RX_TYPE = trim($postObj->MsgType); $ComponentVerifyTicket = trim($postObj->ComponentVerifyTicket); $this->logger(" T: \r\n".$ComponentVerifyTicket); if($ComponentVerifyTicket<>''){//保存即可. $res=file_put_contents("json/VerifyTicket.json", $ComponentVerifyTicket); $data_string='{ "component_appid":"'.AppID.'" , "component_appsecret": "'.Appsecret.'", "component_verify_ticket": "'.$ComponentVerifyTicket.'" }'; // $bbb = http_post_data("https://api.weixin.qq.com/cgi-bin/component/api_component_token", $data_string); $this->logger(" B \r\n".$bbb); //echo "success"; // exit; //echo "sucsess"; } //消息类型分离 switch ($RX_TYPE) { case "location": $result = $this->receiveEvent($RX_TYPE,$postObj); break; case "event": $result = $this->receiveEvent($RX_TYPE,$postObj); break; case "text": $result = $this->receiveText($postObj); break; default: $result = $this->receiveEvent($RX_TYPE,$postObj); break; } $this->logger(" Re: \r\n".$RX_TYPE.$result); //加密 if ($encrypt_type == 'aes'){ $encryptMsg = ''; //加密后的密文 $errCode = $pc->encryptMsg($result, $timeStamp, $nonce, $encryptMsg); $result = $encryptMsg; $this->logger(" E \r\n".$result); } echo $result; }else { echo ""; exit; } } //正式响应消息 public function responseMsg() { $timestamp = $_GET['timestamp']; $nonce = $_GET["nonce"]; $msg_signature = $_GET['msg_signature']; $encrypt_type = (isset($_GET['encrypt_type']) && ($_GET['encrypt_type'] == 'aes')) ? "aes" : "raw"; $this->logger('APPID:'.$_GET['APPID']); $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)){ if ($encrypt_type == 'aes'){ //解密 $pc = new WXBizMsgCrypt(TOKEN, EncodingAESKey, AppID); $this->logger(" D \r\n".$postStr); //发来的加密文件 $decryptMsg = ""; $errCode = $pc->DecryptMsg($msg_signature, $timestamp, $nonce, $postStr, $decryptMsg); $postStr = $decryptMsg; } $this->logger(" R \r\n".$postStr); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $RX_TYPE = trim($postObj->MsgType); $ComponentVerifyTicket = file_get_contents('json/VerifyTicket.json');//yaoshi $Mtoken= $this-> getMToken(AppID,Appsecret,$ComponentVerifyTicket,'11111');//拿到自己的密钥 $this->logger(" M \r\n".$ComponentVerifyTicket); $this->logger(" M \r\n".$Mtoken); $ToUserName=$postObj->ToUserName; // 获取当前公众号的name $info = json_decode(file_get_contents("jsonX/info_".$ToUserName.".json"),true);//读取设置文件. $mini=$info['authorizer_info']['MiniProgramInfo']; if (is_array($mini)) { $xcx= true; }else{ $xcx= false; } $name=$info['authorizer_info']['nick_name'];//公众号名称 $signature=$info['authorizer_info']['signature'];//公众号名称 signature $Cappid=$info['authorization_info']['authorizer_appid']; $refresh_token=$info['authorization_info']['authorizer_refresh_token']; $Atoken=$this->getCToken(AppID,$Cappid,$refresh_token,$Mtoken); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$Atoken; // $aaa=sendmsg($FromUserName,$RX_TYPE,"测试:".$Content,$postObj,$url); //////////////////////////////////以上是获取token部分////////////////////////////////////////////////////// //$Content=trim($postObj->Content); $fromUsername = trim($postObj->FromUserName); //openid $toUsername = trim($postObj->ToUserName); $tousernamebak = $toUsername; $keyword = trim($postObj->Content); $sessionFrom = trim($postObj->SessionFrom); $MsgType = trim($postObj->MsgType);//消息类型 text event $Event = trim($postObj->Event); $json = file_get_contents('json/'.$toUsername.'.json'); $arr = json_decode($json,true); $uniacid = $arr['uniacid'];//bakuniacid $bakuniacid = bakuniacid;//bakuniacid $website = $arr['website']; $fromuserid = $fromUsername;// $myopenid = trim($arr['openids']);//管理员id if ($keyword=='openid'){ if ($xcx){ sendmsg($fromuserid,$MsgType,$fromuserid,'',$url);//给用户发消息. exit;} else{ $encrypt_type = 'aes11'; $keyword=$fromuserid; $result = $this->transmitText($postObj, $keyword.$aaa); $encryptMsg = ''; //加密后的密文 $errCode = $pc->encryptMsg($result, $timeStamp, $nonce, $encryptMsg); $result = $encryptMsg; echo $result; exit; } } $json = file_get_contents("json/".$uniacid."_kefu.json"); $kefuarr = json_decode($json,true); //客服列表 ////////////////////////////////////////////////////////动作提示////////////////////////////// if ($MsgType == "event") { $event = $postObj->Event; $this->logger(" R \r\n 进入动作处理:".$MsgType); if(array_key_exists($fromuserid,$kefuarr)){ //判断是不是客服. $paiduinumber=count(file('json/'.$uniacid.'_paidui.json')); $liuyannumber=count(file('json/'.$toUsername.'_lishi.json')); $kehuopenid= $kefuarr[$fromuserid]; //当前聊天的是? if (substr($kehuopenid,0,1)=='o'){ if(!is_numeric($uniacid)){$uniacid=$bakuniacid;}; $users=getuser($uniacid,$kehuopenid,$nickname,$website); $zhuangtai='当前聊天:['.$users['id'].']'.$users['nickname']; }else{ $zhuangtai='休息中'; if ($kehuopenid=='空闲') { $zhuangtai='当前空闲,有客户会立即进入聊天.';} if ($kehuopenid=='隐身') { $zhuangtai='当前隐身,客户可主动指定聊天.';} } $tongzhi='排队人数:'. $paiduinumber.'\n'.'留言条数:\n'. $liuyannumber.' \n'.$zhuangtai; $data1='{ "touser":"'.$fromuserid.'", "msgtype":"text", "text": { "content":"[客服上线工作提醒]\n '.$tongzhi.' " } }'; $aaa = http_post_data($url, $data1); //减少骚扰 不通知 exit; } //在线客服代码 $this->logger(" R \r\n 是客户:".$MsgType); //继续上一次的对话 $Kefuopenid=array_search($fromuserid,$kefuarr,true); if($Kefuopenid<>''){ sendmsg($fromuserid,'text','客服还在,直接回复继续上次的对话,或者回复再见 结束对话','',$url);//给用户发消息. exit; } if($xcx){ $this->logger(" R \r\n 是小程序:".$MsgType); $tablename=trim($arr['tablename']);//管理员id if ($tablename<>''){ $culname=$arr['culname']; $findname=$arr['findname']; $nickname= Finduser($uniacid,$tablename,$culname,$fromUsername,$findname,$website); if(!$nickname) { $nickname =''; } //logger('findname:'. $nickname); } $unid=$uniacid; if(!is_numeric($uniacid)){$unid=$bakuniacid;}; $userinfo = getuser($unid,$fromUsername,$nickname,$website); $this->logger(" R \r\n 客户信息:".json_encode($userinfo)); } else{ $user = getwxinfo($Atoken,$fromUsername);//微信公众号代码 $unid=$uniacid; if(!is_numeric($uniacid)){$unid=$bakuniacid;}; $userinfo = getuser($unid,$fromUsername,$user['nickname'],$website);//微信公众号代码 } if ($arr['Gappid']<>''){ //网页授权 // if((substr($userinfo['nickname'],0,6)=='会员')){ $sqstr1=$website."addons/qidong_app/intenet.php?zfopenid=".$fromUsername."&toUsername=".$toUsername."&appid=".$arr['Gappid']; $sqstr="\n点链接快速接通客服"; // } } if (trim(trim($arr['默认']))<>''){ $this->logger(" R \r\n 默认有:".$arr['默认']); zhishiku($fromuserid,trim($arr['默认']),$uniacid,$url,$zxkefu,$userinfo) ; }else{ $this->logger(" R \r\n 默认无:".$name.trim($arr['默认'])); sendmsg($fromuserid,'text','你好!欢迎访问'.$name.'.'.$signature,'',$url);//给用户发消息. } $zxkefu="\n在线客服:回复名字接通\n".zxkefu($uniacid,$kefuarr,$sqstr1); if($userinfo['lastliao']<>null){$zxkefu.="\n上次接待客服是:".$userinfo['lastliao'];} $zxkefu.=$sqstr; $caidan=trim($arr['Gjsonid']);//进入通知: if ($caidan<>''){//暂时屏蔽这里.3.15 // $Btoken=getToken($arr['Gappid'],$arr['GAPPSECRET'],$caidan);//修正token时间问题 // $url1 = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$Btoken; // $data1='{ "touser":"'.$arr['Gopenids'].'", "msgtype":"text", // "text": { "content":"[小程序'.$uniacid.'进入提醒]\n '.$userinfo['nickname'].' " } }'; // $aaa = http_post_data($url1, $data1); // //通知到公共号 } $this->logger(" R \r\n 完成.:" ); exit; } ////////////////////////////////////////////////结束动作/////////////////////////////// //print_r($kefuarr); //$arr= array_keys($arr1);//openid //处理客服消息模块开始 if(array_key_exists($fromuserid,$kefuarr)){//客服消息处理 if (substr($keyword,0,10)=='@所有人'){//@所有人 atsuoyouren($uniacid,$website,$keyword,$fromuserid,$url,$toUsername); exit; } //处理@----某人命令 if(substr($keyword,0,1)=='@'){//@某人 $kefulist = json_decode(file_get_contents("json/".$uniacid."_kefulist.json"),true); $kefuname = $kefulist[$fromuserid]; atmouren($keyword,$uniacid,$website,$fromuserid,$url,$kefuname); exit; } if($keyword=='p'){$keyword='下一个'; } if($keyword=='m'){$keyword='排队'; } if($keyword=='0'){$keyword='清零'; } //客服来的消息处理 $kehuopenid= $kefuarr[$fromuserid];// // echo '找到客户:'.$kehuopenid; //判断是不是有客户 if (substr($kehuopenid,0,1)=='o'){ //有客户 ,直接发消息过去: 判断消息是不是@ if (glymingling($uniacid,$fromuserid,$kehuopenid,$keyword,$arr['结束语'],$kefuarr,$url,$toUsername)){//是管理员命令 // echo '命令!'; }else{ //查找客服信息. $kefulist = json_decode(file_get_contents("json/".$uniacid."_kefulist.json"),true); $kefuname = $kefulist[$fromuserid]; // echo '给:'.$kefuarr[$fromuserid].'发内容'.$keyword; $bbb=sendmsg($kehuopenid,$MsgType,$kefuname.':'.$keyword,$postObj,$url);//给用户发消息. //增加判断.消息失败提示. if (json_decode($bbb, true)['errcode']<>0){ // $data2='{ "touser":"'.$fromUsername.'", "msgtype":"text", // "text": { "content":" 客服离开... 消息已存入信箱.'.json_decode($bbb, true)['errcode'].'" } }'; //当没有约定好的回复时,这么回复。 sendmsg($fromUsername,'text','客户可能已经离开了.','',$url);//给用户发消息. // savejson('json/'.$toUsername.'_lishi.json', '@'.$paidui['id'].'_'.$content.''.$keyword ); } //sendmsg($openid,$msgtype,$keyword,$postObj,$url) } }else{ //没客户接待时,可能发的命令:下一个. if (glymingling($uniacid,$fromuserid,$kehuopenid,$keyword,$arr['结束语'],$kefuarr,$url,$toUsername,$website)){ //echo '是命令!';zaij }else{ // echo '给:'.$kefuarr[$fromuserid].'发内容'.$keyword; // 空闲时 可以玩玩素材库 . if (!zhishiku($fromuserid,$keyword,$uniacid,$url,'',$userinfo)){ sendmsg($fromuserid,'text','暂无接待客户,可发送命令下一个接通.','',$url,$toUsername,$website);//给用户发消息. } } //客服状态. kong mang 判断是不是要上班?或者其他命令 比如 下一个 等. } }else{ // echo "not found kefu--";//不是客服 则看谁空闲? 规则 先找老客服 . //反查是否在队列 //先看客户是不是...选了指定的客服. 客服小李 正在咨询的时候 是不能调出的.除非. $Kefuopenid=array_search($fromuserid,$kefuarr,true); if($Kefuopenid<>'') { // echo "这是用户,正在咨询的客服是:"; // 用户发 再见 主动离线 . 更新客服列表 . 告诉客服 告诉客户 if (substr($keyword,0,6)=='再见'){ // sendmsg($fromuserid,'text',$arr['结束语'],'',$url);//说再见. jieshuyu($arr['结束语'],$uniacid,$fromuserid,$website,$url); $json = file_get_contents("json/".$uniacid."_kefulist.json");//客服详情页 $kefulist = json_decode($json,true); $kefuname = $kefulist[$Kefuopenid]; edituser($uniacid,$fromuserid,'',$website,$avartar,$zhuangtai,$kefuname); $json = file_get_contents("json/".$uniacid."_paidui.json"); $paiduinum = count(json_decode($json,true)); sendmsg($Kefuopenid,'text','当前客户已经离开,发下一个接通.当前有'.$paiduinum.'人排队.','',$url);//说再见. $kefuarr[$Kefuopenid]='空闲'; //建立对接 同时通知双方. 发两次消息. exec("rm -f ".'json/'.$uniacid.'_kefu.json'); $res=file_put_contents("json/".$uniacid."_kefu.json", json_encode($kefuarr)); }else{ if(!is_numeric($uniacid)){$uniacid=$bakuniacid;} $users=getuser($uniacid,$fromuserid,$nickname,$website); $bbb=sendmsg($Kefuopenid,$MsgType,'['.$users['id'].']'.$users['nickname'].':'.$keyword,$postObj,$url); if (json_decode($bbb, true)['errcode']<>0){ sendmsg($fromUsername,'text','客服忙..已经存入留言板...\n 回复 再见 结束会话.','',$url);//给用户发消息. // savejson('json/'.$toUsername.'_lishi.json', '@'.$users['id'].'_'.$users['nickname'].''.$keyword ); file_put_contents('json/'.$toUsername.'_lishi.json', '@'.$users['id'].'_'.$users['nickname'].''.$keyword .PHP_EOL, FILE_APPEND); } } }else{//没在咨询,检查是否有空闲客服 if ( strpos($arr['kefustr'],$keyword)>0){//客户发张三 $kongkefu=''; $zhiding=1; }else{ $kongkefu=array_search('空闲',$kefuarr,true); } if($kongkefu<>''){ //echo '当前有空的客服:'; //echo $kongkefu; $kefuarr[$kongkefu]=$fromuserid; //建立对接 同时通知双方. 发两次消息. exec("rm -f ".'json/'.$uniacid.'_kefu.json'); $res=file_put_contents("json/".$uniacid."_kefu.json", json_encode($kefuarr)); //增加获取用户信息功能. 没排队 直接进入 需要查客户信息. $unid=$uniacid; if(!is_numeric($uniacid)){$unid=$bakuniacid;}; $users=getuser($unid,$fromuserid,$nickname,$website); sendmsg($kongkefu,'text',$users['id'].$users['nickname'].':'.$keyword,'',$url);//通知客服 $kefulist = json_decode(file_get_contents("json/".$uniacid."_kefulist.json"),true); $kefuname = $kefulist[$kongkefu]; sendmsg($fromuserid,'text',$kefuname.':你好,有什么可以帮到你的?','',$url);//通知客服 $tongzhiadmin=$kefuname.' 接入了新客户.['.$users['id'].']'.$users['nickname']; }else { //echo '当前客服都忙:/或者客户指定了客服.'; //检查关键词回复 如果有则回复关键词 if($MsgType=='text'){ if (!zhishiku($fromuserid,$keyword,$uniacid,$url,'',$userinfo)){ //当客服发送 指定客服的指令时 .如发 客服1 if ($zhiding==1){//客户主动选择客服. $zd=zhaokefumingling($fromuserid,$uniacid,$keyword,$url,$kefuarr,$website); if($zd){ $tongzhiadmin=$keyword.' 被客户点名. ';} }else{ $paidui=paidui($uniacid,$fromuserid,$website);//排队语自己组织. sendmsg($fromuserid,'text',$paidui,'',$url);//下发排队情况给用户. if($paidui<>'排队中,请耐心等待.'){ $tongzhiadmin='有用户来:'.$keyword.'\n排队中:'.$paidui; } } } }else{//用户发送其他信息怎么办? 通知他排队. $paidui=paidui($uniacid,$fromuserid,$website);//排队语自己组织. sendmsg($fromuserid,'text',$paidui,'',$url);//下发排队情况给用户. sendmsg($myopenid,$MsgType,'其他类型文件',$postObj,$url);//其他文件 直接通知管理员.. } // 是否在排队? 用数组键值查询, 没有.插入排队表 .有 返回排队顺序? } } //下发给总管理员通知; if ($tongzhiadmin<>''){ $data1='{ "touser":"'.$myopenid.'", "msgtype":"text", "text": { "content":"[管理员提醒:]\n'.$tongzhiadmin.'" } }'; $aaa = http_post_data($url, $data1); //减少骚扰 不通知 } } //处理客服消息模块结束. ///////////////////////////////////////////////结束分配///////////////////////////////// //如果是公众号,可以自动回复: if ($encrypt_type == 'aes11'){ $result = $this->transmitText($postObj, $keyword.$aaa); $encryptMsg = ''; //加密后的密文 $errCode = $pc->encryptMsg($result, $timeStamp, $nonce, $encryptMsg); $result = $encryptMsg; $this->logger(" E \r\n".$result); } echo $result; }else { echo ""; exit; } } //接收事件消息 private function receiveEvent($RX_TYPE,$object) { $content = ""; // switch ($object->Event) // { // case "subscribe": // $content = "欢迎关注,系统正在升级. "; // break; // } $content= $RX_TYPE."from_callback"; $result = $this->transmitText($object, $content); return $result; } //接收文本消息 private function receiveText($object) { // $keyword = trim($object->Content); $needle ='QUERY_AUTH_CODE:'; $tmparray = explode($needle,$object['Content']); if(count($tmparray)>1){ // trace($response,"解密后: " ); //3、模拟粉丝发送文本消息给专用测试公众号,第三方平台方需在5秒内返回空串 //表明暂时不回复,然后再立即使用客服消息接口发送消息回复粉丝 $contentx = str_replace ($needle,'',$object['Content']);//将$query_auth_code$的值赋值给API所需的参数authorization_code $this->authorization_code = $contentx;//authorization_code // trace($contentx,'authorization_code'); //使用授权码换取公众号或小程序的接口调用凭据和授权信息 $postdata = array( "component_appid"=>$this->appid, "authorization_code"=>$this->authorization_code, ); $ComponentVerifyTicket = file_get_contents('json/VerifyTicket.json'); $token= getToken(AppID,Appsecret,$ComponentVerifyTicket,'11111'); $url="https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=$token"; $authorization=http_post_data($url,$data); $auth=json_decode($authorization,true); //authorizer_access_token $authorizer_access_token=$auth['authorization_info']['authorizer_access_token']; $content_re = $contentx."_from_api"; echo ''; $data = array( "touser"=>$object['FromUserName'], "msgtype"=>"text", "text" => array( "content" =>$content_re ) ); $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=".$authorizer_access_token; $ret = http_post_data($url, $data); }else{ $content="TESTCOMPONENT_MSG_TYPE_TEXT_callback"; $result = $this->transmitText($object, $content); return $result;} } //回复文本消息 private function transmitText($object, $content) { $xmlTpl = " %s "; $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), $content); return $result; } //回复图文消息 private function transmitNews($object, $newsArray) { if(!is_array($newsArray)){ return; } $itemTpl = " <![CDATA[%s]]> "; $item_str = ""; foreach ($newsArray as $item){ $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']); } $xmlTpl = " %s %s $item_str "; $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time(), count($newsArray)); return $result; } //回复音乐消息 private function transmitMusic($object, $musicArray) { $itemTpl = " <![CDATA[%s]]> "; $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']); $xmlTpl = " %s $item_str "; $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time()); return $result; } //日志记录 public 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 = 500000; $log_filename = "log_wx_open.xml"; if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);} file_put_contents($log_filename, date('Y-m-d H:i:s').$log_content."\r\n", FILE_APPEND); } } public function getNewCToken($Mappid,$Cappid,$refresh_token,$Mtoken){ $data_string='{ "component_appid":"'.$Mappid.'", "authorizer_appid":"'.$Cappid.'", "authorizer_refresh_token":"'.$refresh_token.'", }'; $access_token_Arr = http_post_data("https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=$Mtoken", $data_string); //$access_token_Arr=json_decode($access_token_Arr,true); return $access_token_Arr; } public function getCToken($Mappid,$Cappid,$refresh_token,$Mtoken){ $file = file_get_contents("jsonX/{$Cappid}_token.json",true); $result = json_decode($file,true); if (time() > $result['expires']){ // $data = array(); $jsonStr = $this->getNewCToken($Mappid,$Cappid,$refresh_token,$Mtoken); // $jsonStr = json_encode($data); $fp = fopen("jsonX/{$Cappid}_token.json", "w"); fwrite($fp, $jsonStr); fclose($fp); $data=json_decode($jsonStr,true); return $data['authorizer_access_token']; }else{ return $result['authorizer_access_token']; } } public function https_request ($url){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $out = curl_exec($ch); curl_close($ch); return json_decode($out,true); } public function traceHttp() { logger("\n\nREMOTE_ADDR:".$_SERVER["REMOTE_ADDR"].(strstr($_SERVER["REMOTE_ADDR"],'101.226')? " FROM WeiXin": "Unknown IP")); logger("QUERY_STRING:".$_SERVER["QUERY_STRING"]); } public function getMToken($appid,$appsecret,$ComponentVerifyTicket,$jsonid){ $file = file_get_contents("jsonX/{$appid}_token.json",true); $result = json_decode($file,true); if (time() > $result['expires']){ $data = array(); $data['component_access_token'] =$this->getNewToken($appid,$appsecret,$ComponentVerifyTicket); $data['expires']=time()+6200; $jsonStr = json_encode($data); $fp = fopen("jsonX/{$appid}_token.json", "w"); fwrite($fp, $jsonStr); fclose($fp); return $data['component_access_token']; }else{ return $result['component_access_token']; } } public function getNewToken($appid,$appsecret,$ComponentVerifyTicket){ $data_string='{ "component_appid":"'.$appid.'" , "component_appsecret": "'.$appsecret.'", "component_verify_ticket": "'.$ComponentVerifyTicket.'" }'; $access_token_Arr = http_post_data("https://api.weixin.qq.com/cgi-bin/component/api_component_token", $data_string); //echo "
---"; $access_token_Arr=json_decode($access_token_Arr,true); return $access_token_Arr['component_access_token']; } } function sendmsg($openid,$msgtype,$keyword,$postObj,$url){ //消息处理模块. switch ($msgtype) { case 'text': $data1='{ "touser":"'.$openid.'", "msgtype":"text", "text": { "content":" '.$keyword.' " } }'; break; case 'image': $MediaId = $postObj->MediaId; $data1=' { "touser":"'.$openid.'", "msgtype":"image", "image": { "media_id":"'.$MediaId.'" }}'; break; case 'voice': $MediaId = $postObj->MediaId; $Recognition = $postObj->Recognition; $data1=' { "touser":"'.$openid.'", "msgtype":"voice", "voice": { "media_id":"'.$MediaId.'" }}'; break; case 'miniprogrampage': $data1=''; break; default: $data1=''; } $aaa = http_post_data($url, $data1); //echo '发送消息:'.$data1.$aaa; // logger('@@@@@@@@'.$data1.$aaa); return $aaa; } function http_post_data($url, $data_string) { $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json; charset=utf-8', 'Content-Length: ' . strlen($data_string)) ); ob_start(); curl_exec($ch); $return_content = ob_get_contents(); //echo $return_content."
"; ob_end_clean(); $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); // return array($return_code, $return_content); return $return_content; } function getuser($ucid,$openid,$nickname,$website) { ///先判断缓存文件是否存在 $json = file_get_contents("json/".$ucid."_user.json"); $userinfos = json_decode($json,true); // $userid=$userinfos[$openid]['id']; // echo '找到缓存表:'.$userid; if (!array_key_exists($openid,$userinfos)){ $token_access_url = "{$website}/app/index.php?i=".$ucid."&c=entry&a=wxapp&do=getuser&m=qidong_app&openid=".$openid."&nickname=".$nickname; loggers($token_access_url) ; // echo $token_access_url; $res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容 $result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP $nickname= $result['data']['wxapp'][0]['nickname']; $beizhu= $result['data']['wxapp'][0]['zhuangtai']; $lastliao= $result['data']['wxapp'][0]['lastliao']; if (trim($nickname)==null) { $nickname='会员'.$result['data']['wxapp'][0]['id']; $isid=1; } $userid=$result['data']['wxapp'][0]['id']; $data = array( 'nickname' => $nickname, 'id' => $userid, 'beizhu' => $beizhu, 'lastliao'=> $lastliao ); return $data ; }else { // echo '找到缓存 直接返回;'; return $userinfos[$openid]; } } function zxkefu($uniacid,$kefuarr,$sqstr1){//读取在线客服列表//下次升级点击接通?? $json = file_get_contents("json/".$uniacid."_kefulist.json");//客服详情页 $kefulist = json_decode($json,true); $kefuopenid= array_keys($kefulist);//kfuopenid $kefuall=''; $i=0; foreach ($kefuopenid as $kefuopenid){ //群发-- //$kfopenid=$arr; if(substr($kefuarr[$kefuopenid],0,1)=="o"){ $zt='忙碌'; }else{ $zt=$kefuarr[$kefuopenid]; } if ($zt<>'隐身'){ $i++; //$sqstr=$website."addons/qidong_app/intenet.php?zfopenid=".$fromUsername."&toUsername=".$toUsername."&appid=".$arr['Gappid']."&kfname=".$kfname; //$sqstr="\n点此快速接通客服"; //$sqstr1=$website."addons/qidong_app/intenet.php?zfopenid=".$fromUsername."&toUsername=".$toUsername."&appid=".$arr['Gappid']."&kfname=".$kfname; if(($sqstr1=='') or ($zt=='忙碌')){ $kefuall=$kefuall." ".$kefulist[$kefuopenid]."[".$zt."]"; }else{ $sqstr="\n".$kefulist[$kefuopenid].""; $kefuall=$kefuall." ".$sqstr."[".$zt."]"; } if(($i % 2)==0){ $kefuall.="\n";} // $kefuall=$kefuall.' '.$kefulist[$kefuopenid].'['.$zt.']'; } } //logger($kefuall); return $kefuall; } function zhishiku($fromuserid,$keyword,$uniacid,$url,$addstr,$userinfo){ //知识库处理模块 //echo '
知识库模块
'.$keyword.$uniacid; $json = file_get_contents('json/'.$uniacid.'_keywords.json');//读取key列表 $keys = json_decode($json,true); $json = file_get_contents('json/'.$uniacid.'_keys.json');//读取数字key列表 $numkeys = json_decode($json,true); if(is_numeric($keyword)){ $send=$keys[$numkeys[$keyword]]; }else { $send=$keys[$keyword]; //$keys['关于我们']; } if ( $send<>'' ) { //判断是否是知识库设置字段 if ($send['link']['title']!=''){ $send['link']['title']=str_replace('id',$userinfo['id'],$send['link']['title']); $send['link']['title']=str_replace('[name]', trim($userinfo['nickname']),$send['link']['title']); } if ($send['miniprogrampage']['title']!=''){ $send['miniprogrampage']['title']=str_replace('id',$userinfo['id'],$send['miniprogrampage']['title']); $send['miniprogrampage']['title']=str_replace('[name]', trim($userinfo['nickname']),$send['miniprogrampage']['title']); } if ($send['text']['content']!=''){ $send['text']['content']=str_replace('[id]',$userinfo['id'],$send['text']['content']); $send['text']['content']=str_replace('[name]',trim($userinfo['nickname']),$send['text']['content']); $send['text']['content']=changeurl($send['text']['content']); $send['text']['content'].=$addstr; } $send['touser']=$fromuserid; $data=json_encode($send,JSON_UNESCAPED_UNICODE); $aaa = http_post_data($url, $data); $zt=json_decode($aaa, true)['errcode']; if ($zt!=0){//下发未成功 $data='{ "touser":"'.$fromuserid.'", "msgtype":"text", "text": { "content":" 系统忙 错误代码: ' . $zt . ' " } }'; $aaa = http_post_data($url, $data); } return true; }else{ return false;//不是知识. } } function zhaokefumingling($fromuserid,$uniacid,$keyword,$url,$kefuarr,$website){ $kefulist = json_decode(file_get_contents("json/".$uniacid."_kefulist.json"),true); //$kefuname=substr($keyword,7); $Kefuopenid=array_search($keyword,$kefulist,true);//找到客服id if (substr($kefuarr[$Kefuopenid],0,1)=='o')//看客服状态 客服状态over { sendmsg($fromuserid,'text','客服忙,请稍后.','',$url);//下发排队情况给用户. return false; }else{//客服接入// if($Kefuopenid==''){ sendmsg($fromuserid,'text','客服休息了.请稍后再试.','',$url);//下发排队情况给用户. return false; }else{//客服在,对接开始. 如果是排队发的 则删除排队.如果是没排队发的.则不排队. $kefuarr[$Kefuopenid]=$fromuserid; //建立对接 同时通知双方. 发两次消息. exec("rm -f ".'json/'.$uniacid.'_kefu.json'); $res=file_put_contents("json/".$uniacid."_kefu.json", json_encode($kefuarr)); //增加获取用户信息功能. 没排队 直接进入 需要查客户信息. $json = file_get_contents("json/".$uniacid."_paidui.json"); $paiduiarr = json_decode($json,true); if(array_key_exists($fromuserid,$paiduiarr)){//如果在排队则.. $uid=$paiduiarr[$fromuserid]['id']; $nickname=$paiduiarr[$fromuserid]['nickname']; unset($paiduiarr[$fromuserid]);//删除它 $res=file_put_contents("json/".$uniacid."_paidui.json", json_encode($paiduiarr)); }else{//没排队 .就是上来就发的. 新用户就注册 老用户就获取. $users=getuser($uniacid,$fromuserid,$nickname,$website); $uid=$users['id']; $nickname=$users['nickname']; } sendmsg($Kefuopenid,'text','['.$uid.']'.$nickname.':'.$keyword.' 你好','',$url);//通知客服 // $kefuname = $kefulist[$Kefuopenid]; sendmsg($fromuserid,'text',$keyword.':你好,有什么可以帮到你的?','',$url);//通知客服 return true; } } } function atsuoyouren($uniacid,$website,$keyword,$myopenid,$url,$toUsername){ //@所有人 $huncun= json_decode(alluser($uniacid,$website),true); $gjz=substr($keyword,10,strlen(trim($keyword))-10); if (substr ($keyword, -1)=='#'){ $gjz=str_replace('#','|',$gjz); } $baogao=' { "title": "代发列表已经准备好!点此群发", "description": "本次准备发送: '.$huncun['count'].' 请1分钟内点击,过期失效.", "url": "'.$website.'addons/qidong_app/qunfa.php?uniacid='.$uniacid.'&keyword='.$gjz.'&tousername='.$toUsername.'&t='.time().'", "thumb_url": "'.$website.'/addons/qidong_app/icon.jpg" }'; $data1='{ "touser":"'.$myopenid.'", "msgtype":"link", "link": '.$baogao.' }'; $aaa = http_post_data($url, $data1); // } function atmouren($keyword,$uniacid,$website,$fromuserid,$url,$kefuname){ $stri=0; $stri= stripos($keyword,':'); if ($stri==0){$stri= stripos($keyword,' ') ;} if ($stri==0){$stri= stripos($keyword,':') ;} $nid=substr($keyword,1,$stri-1); //@12:=>12 $say=trim(substr($keyword,$stri+1));//发送的内容: if($say==''){$say=$kefuname.'@你 ,客服上线了,邀请你进入会话.';} //判断say最后字符是# 则是关键词消息 991# $liuuser= hiuser($uniacid,$nid,$website); $result = substr ($say, -1); //当是# 关键字图文时 . if ($result=='#'){ $json = file_get_contents('json/'.$uniacid.'_keywords.json');//读取key列表 $keys = json_decode($json,true); $json = file_get_contents('json/'.$uniacid.'_keys.json');//读取数字key列表 $numkeys = json_decode($json,true); $gjz=substr($say,0,strlen($say)-1); if(is_numeric($gjz)){ $send=$keys[$numkeys[$gjz]]; } else { $send=$keys[$gjz]; //$keys['关于我们']; } $send['touser']=$liuuser['openid']; $nickname=$liuuser['nickname']; if($nickname==''){$nickname='会员'.$liuuser['id'];} $send['link']['title']=str_replace('[id]',$liuuser['id'],$send['link']['title']); $send['link']['title']=str_replace('[name]', trim($nickname),$send['link']['title']); $data=json_encode($send,JSON_UNESCAPED_UNICODE); $bbb = http_post_data($url, $data); // logger('单发:'.$gjz.'-'.$data); }else{ sendmsg($liuuser['openid'],'text','['.$kefuname.'@你]:'.$say,'',$url); } if (json_decode($bbb, true)['errcode']==0) { $zt='送达'; //对方正在输入...哈哈 $data8='{ "touser":"'.trim($liuuser['openid']).'", "command":"Typing"}'; $url8='https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token='.$Atoken; $bbb = http_post_data($url8, $data8); //logger($bbb); //结束输入判断. }else{ $zt='失败,可能已经离线'.json_decode($bbb, true)['errcode']; }; sendmsg($fromuserid,'text','[@'.$nid.'报告]:'.$zt,'',$url); //发送消息 } function glymingling($uniacid,$openid,$kehuopenid,$keyword,$jsy,$kefuarr,$url,$toUsername,$website){ //处理管理员命令 @某人命令? //echo '检查命令!';$ if (strpos(',清零,下一个,隐身,看留言,上班,排队,@所有人,',$keyword)>0){ //此处增加管理员命令列表处理. if($keyword=='看留言'){ $json = file_get_contents('json/'.$toUsername.'_lishi.json'); sendmsg($openid,'text','本次获取的内容,已清空留言板:\n'.$json,'',$url); exec("rm -f ".'json/'.$toUsername.'_lishi.json'); break; } if($keyword=='排队'){ $json = file_get_contents("json/".$uniacid."_paidui.json"); $karr = json_decode($json,true); $pdrs=count($karr); sendmsg($openid,'text','排队人数:'.$pdrs,'',$url);//发排队人数.后面再做详情.?? } if($keyword=='隐身'){ $kefuarr[$openid]='隐身'; $res=file_put_contents("json/".$uniacid."_kefu.json", json_encode($kefuarr)); sendmsg($openid,'text','设置隐身成功. 可被点名进入聊天.不能自动进入聊天.','',$url); } if($keyword=='清零'){ exec("rm -f ".'json/'.$toUsername.'_paidui.json'); exec("rm -f ".'json/'.$toUsername.'_token.json'); exec("rm -f ".'log.xml'); if (!file_exists('json/'.$toUsername.'_token.json')){ $t="清零成功!"; }else{ $t="清零失败,请检查目录权限是否设置为777!"; } sendmsg($openid,'text',$t,'',$url); } if($keyword=='上班'){ $kefuarr[$openid]='空闲'; $res=file_put_contents("json/".$uniacid."_kefu.json", json_encode($kefuarr)); sendmsg($openid,'text','设置上班成功. 可自动接入来访客户.','',$url); } if($keyword=='下一个'){ //跟现在的说再见 ?再见语? $json = file_get_contents("json/".$uniacid."_kefulist.json");//客服详情页 $kefulist = json_decode($json,true); $kefuname = $kefulist[$openid]; if (substr($kehuopenid,0,1)=='o'){ //回复图文消息. jieshuyu($jsy,$uniacid,$kehuopenid,$website,$url); // sendmsg($kehuopenid,'text',$jsy,'',$url);//说再见. // $a=edituser($uniacid,$delid['openid'],'',$website); //$lastliao='';//最后聊天客服. edituser($uniacid,$kehuopenid,'',$website,$avartar,$zhuangtai,$kefuname); } //找到下一个客户? $json = file_get_contents("json/".$uniacid."_paidui.json"); $paiduiarr = json_decode($json,true); $nextkh=array_shift($paiduiarr);//取出并从排队中删除第一个. if (substr($nextkh['openid'],0,1)=='o'){ //print_r($nextkh); //echo '
'; //print_r('nextkhoid:'.$nextkh['openid']); sendmsg($nextkh['openid'],'text',$kefuname.':你好,久等了.','',$url);//新用户你好. $userjson=json_encode($paiduiarr); $res=file_put_contents("json/".$uniacid."_paidui.json",$userjson);//更新排队数据. $kefuarr[$openid]=$nextkh['openid'];//保存新的用户进来.; sendmsg($openid,'text','['.$nextkh['id'].']'.$nextkh['nickname'].'已经进入聊天.','',$url);// $res=file_put_contents("json/".$uniacid."_kefu.json",json_encode($kefuarr));//更新客服数据. $kefulist = json_decode(file_get_contents("json/".$uniacid."_kefulist.json"),true); $kefuname = $kefulist[$fromuserid]; //sendmsg($nextkh['openid'],'text',$kefuname.':你好久等了.','',$url);// }else{//已无排队用户.修正客服表 保存.告诉客服. $kefuarr[$openid]='空闲'; $res=file_put_contents("json/".$uniacid."_kefu.json",json_encode($kefuarr));//更新客服数据. sendmsg($openid,'text','已无排队用户.你的状态目前是空闲.\n常用命令: 上班 隐身 排队.','',$url);//新用户你好. } } return true; }else { return false; } } function paidui($uniacid,$openid,$website){ $json = file_get_contents("json/".$uniacid."_paidui.json"); $kefuarr = json_decode($json,true); if(array_key_exists($openid,$kefuarr)){ return '排队中,请耐心等待.';//排队中... }else{ $user=getuser($uniacid,$openid,$nickname,$website);//获取用户信息 $userinfo=array('id'=>$user['id'], 'nickname'=>$user['nickname'], 'beizhu'=>$user['beizhu'], 'openid'=>$openid); $kefuarr[$openid]=$userinfo; $userjson=json_encode($kefuarr); $res=file_put_contents("json/".$uniacid."_paidui.json",$userjson); $qianmian=count($kefuarr)-1; return '已接入客服中心,前面有'.$qianmian.'人';//排队数量 } } function changeurl($a){ $bi= strpos($a,'[['); if ($bi==0){ return $a; }else{ $ei= strpos($a,']]'); $qb=substr($a,0,$bi); $eb=substr($a,$ei+2); $b=substr($a,$bi+2,$ei-$bi-2); $ci=strpos($b,'|'); $add=substr($b,0,$ci); $herf=substr($b,$ci+1,strlen($b)-$ci); } return $qb."".$add."".$eb; } function getwxinfo($token,$openid){ $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$token}&openid={$openid}&lang=zh_CN"; // logger($url); $access_token_Arr = https_request($url); return $access_token_Arr; } function hiuser($ucid,$id,$website){ $token_access_url = "{$website}/app/index.php?i=".$ucid."&c=entry&a=wxapp&do=getopenid&m=qidong_app&id=".$id; $res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容 $result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP $data=$result['data'][0] ; return $data ; } function alluser($ucid,$website){ $token_access_url = "{$website}/app/index.php?i=".$ucid."&c=entry&a=wxapp&do=Getallopenid&m=qidong_app"; $res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容 $result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP $data=$result['data'] ; return json_encode($data) ; } function edituser($ucid,$openid,$nickname,$website,$avartar,$zhuangtai,$lastliao) //改名取号 { $token_access_url = "{$website}/app/index.php?i=".$ucid."&c=entry&a=wxapp&do=edituser&m=qidong_app&openid=".$openid."&nickname=".$nickname."&avartar=".$avartar."&lastliao=".$lastliao; //zhuangtai // echo $token_access_url; // exit; $res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容 $result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP $data=$result['data']; if ($data==1){$data='改名成功!';} else{$data='改名失败!';} return $data ; } function jieshuyu($bye,$uniacid,$openid,$website,$url){ if(is_numeric($bye)){ $json = file_get_contents('json/'.$uniacid.'_keywords.json');//读取key列表 $keys = json_decode($json,true); $json = file_get_contents('json/'.$uniacid.'_keys.json');//读取数字key列表 $numkeys = json_decode($json,true); $delid=getuser($uniacid,$openid,'',$website); $send=$keys[$numkeys[$bye]]; if ($send['link']['title']!=''){ $send['link']['title']=str_replace('id',$delid['id'],$send['link']['title']); $send['link']['title']=str_replace('[name]', trim($delid['nickname']),$send['link']['title']); } if ($send['miniprogrampage']['title']!=''){ $send['miniprogrampage']['title']=str_replace('id',$delid['id'],$send['miniprogrampage']['title']); $send['miniprogrampage']['title']=str_replace('[name]', trim($delid['nickname']),$send['miniprogrampage']['title']); } if ($send['text']['content']!=''){ $send['text']['content']=str_replace('[id]',$delid['id'],$send['text']['content']); $send['text']['content']=str_replace('[name]',trim($delid['nickname']),$send['text']['content']); // logger('要替换的文本:'.$send['text']['content']); $send['text']['content']=changeurl($send['text']['content']); } $send['touser']=trim($openid); $data0=json_encode($send,JSON_UNESCAPED_UNICODE); } else { $sends=$bye; //$keys['关于我们']; $jieshuyu= str_replace('[name]',$delid['nickname'],$sends); $jieshuyu=str_replace("{br}","\n",$jieshuyu); $jieshuyu=changeurl($jieshuyu); $data0='{ "touser":"'.trim($openid).'", "msgtype":"text", "text": { "content":" '.$jieshuyu.' " } }'; } $aaa = http_post_data($url, $data0); // logger($data0); } function Finduser($ucid,$tablename,$culname,$openid,$findname,$website){ //&tablename=dc_user&culname=openid&findname=name&openid=ogMce0dAqzqm3LSCIBzoHb4XYgFU $token_access_url = "{$website}/app/index.php?i=".$ucid."&c=entry&a=wxapp&do=finduser&m=qidong_app&tablename={$tablename}&culname={$culname}&findname={$findname}&openid={$openid}"; // logger( $token_access_url); $res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容 //logger('--------------'.$res); $result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP $data=$result['data']['nickname'] ; return $data ; } function loggers($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 = 500000; $log_filename = "log_wx_open.xml"; if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);} file_put_contents($log_filename, date('Y-m-d H:i:s').$log_content."\r\n", FILE_APPEND); } } ?>