企業(yè)微信外部聯(lián)系人之回調(diào)

需求:實(shí)時(shí)更新外部聯(lián)系人信息
環(huán)境:php+mysql

一、引言:

1.思路

  • 建立存儲外部聯(lián)系人相關(guān)字段的數(shù)據(jù)表杯巨,兩個(gè)字段需要注意,一個(gè)是userid努酸,一個(gè)是external_userid服爷。前者是所添加的外部聯(lián)系人上級,后者是該外部聯(lián)系人的id获诈,想要根據(jù)這個(gè)id來查找其詳細(xì)信息仍源。簡單來說就是:如果我是客服,我要去添加客戶舔涎,那么我使用的賬號的這個(gè)id就是userid笼踩,我所添加的客戶(們)的id就是external_userid。
  • 配置回調(diào)地址
  • 根據(jù)回調(diào)地址觸發(fā)事件來及時(shí)更新數(shù)據(jù)表(增刪改)

2.參考文檔

3.所遇到的棘手問題(所謂的坑)

所謂的坑亡嫌,還是老樣子嚎于,思路不清楚,所以覺得很坑(騰訊官方文檔)挟冠。
1.驗(yàn)證回調(diào)地址不通過于购。從以下幾點(diǎn)找一下問題所在:首先在瀏覽器另起一個(gè)窗口訪問一下填的地址,看看能不能訪問的通先知染。然后檢查一下驗(yàn)證的接口結(jié)束的地方有沒有一個(gè)返回值肋僧,需要將入?yún)⒅械?code>$sEchoStr返回。還是不行的話可以試一下更換一下tokenEncodingAESKey控淡。
具體錯(cuò)誤碼對應(yīng)的原因如下:

  '0'=> 'success',
  '-40001'=> '簽名驗(yàn)證錯(cuò)誤',
  '-40002'=> 'xml解析失敗',
  '-40003'=> 'sha加密生成簽名失敗',
  '-40004'=> 'encodingAesKey 非法',
  '-40005'=> 'corpid 校驗(yàn)錯(cuò)誤',
  '-40006'=> 'aes 加密失敗',
  '-40007'=> 'aes 解密失敗',
  '-40008'=> '解密后得到的buffer非法',
  '-40009'=> 'base64加密失敗',
  '-40010'=> 'base64解密失敗',
  '-40011'=> '生成xml失敗',
image.png

2.驗(yàn)證完了回調(diào)地址后嫌吠,回調(diào)事情里獲取不到相關(guān)的xml數(shù)據(jù),只返回了msg_signature掺炭、 timestamp 居兆、nonce。如果文檔讀的不仔細(xì)的話很容易出現(xiàn)這個(gè)問題(讀這個(gè)文檔就像破案一樣竹伸,一個(gè)一個(gè)去找相關(guān)的線索,....此處省略粗口一萬字)簇宽。
所謂的消息體不是從地址欄中傳來的勋篓,是從body里傳來的。這里完是使用的php腳本語言魏割,采用的獲取方法為:file_get_contents("php://input");
3.如何打印這個(gè)回調(diào)里的數(shù)據(jù)譬嚣?最好的辦法是在回調(diào)的接口方法里,把需要的數(shù)據(jù)寫入到文件中:file_put_contents钞它。使用如var_dump,print這種不行拜银,因?yàn)榇蛴〉膬?nèi)容長度過長殊鞭。
4.回調(diào)事件不觸發(fā)。這里需要檢查一下入?yún)⒅械钠髽I(yè)應(yīng)用corpId是否正確尼桶。然后再檢查一下外部聯(lián)系人的一些權(quán)限問題操灿,根據(jù)文檔給的一個(gè)一個(gè)去點(diǎn)開檢查一下就行了。

image.png

5.根據(jù)打印寫入的文件中的數(shù)據(jù)進(jìn)行測試解密泵督,返回 -40002 錯(cuò)誤碼趾盐。我遇到這個(gè)的原因是在打印中復(fù)制過來的xml格式有問題,經(jīng)過了json_encode后小腊,斜杠前面會多一個(gè)反斜杠救鲤,把其中的反斜杠刪掉就行了。
打印的數(shù)據(jù)

二秩冈、代碼

驗(yàn)證回調(diào)地址

public function text1(){
        $sVerifyMsgSig = $_GET['msg_signature'];
        $sVerifyTimeStamp = $_GET['timestamp'];
        $sVerifyNonce = $_GET['nonce'];
        $sVerifyEchoStr = $_GET['echostr'];

        // 需要返回的明文
        $sEchoStr = "321";

        $wxcpt = new \WXBizMsgCrypt('eHtnCm7SVxxx', 'igM5h5jsCZbcTTI5ixomyPNDt33Pn9N2xxxxxx', 'ww15abe89fedxxxxx');
        $errCode = $wxcpt->VerifyURL($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr, $sEchoStr);
       
        if ($errCode == 0) {
            // 驗(yàn)證URL成功本缠,將sEchoStr返回
            return $sEchoStr;
        } else {
            print("ERR: " . $errCode . "\n\n");
        }
    }

處理回調(diào)數(shù)據(jù)

//接收回調(diào)
    public function text(){
        date_default_timezone_set('PRC');
        $sReqMsgSig = isset($_GET['msg_signature'])?$_GET['msg_signature']:'';
        $sReqTimeStamp = isset($_GET['timestamp'])?$_GET['timestamp']:'';
        $sReqNonce = isset($_GET['nonce'])?$_GET['nonce']:'';
        $sReqData = file_get_contents("php://input");

        $params = $_GET; //get參數(shù)
        $params['xmlContent'] = $sReqData;  //post的xml數(shù)據(jù)
        $sMsg = '';
        $wxcpt = new \WXBizMsgCrypt('eHtnCm7Sxxx', 'igM5h5jsCZbcTTI5ixomyPNDt33Pn9N2JcXwxxxx', 'ww15abe89fed8xxxx');
        $errCode = $wxcpt->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData, $sMsg);
        if ($errCode == 0) {
            //存緩存記錄
            $params['errorCode'] = $errCode;
            $params['errorMsg'] = $this->_callbackErrorMsgArr[$errCode];
            $params['sMsg'] = json_decode(json_encode(simplexml_load_string($sMsg,"SimpleXMLElement", LIBXML_NOCDATA),JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT),true);
            $this->putMark($params);

            $msg_arr = json_decode(json_encode(simplexml_load_string($sMsg,"SimpleXMLElement", LIBXML_NOCDATA)),true);
            //外部聯(lián)系人的userid
            $external_userid = isset($msg_arr['ExternalUserID'])?$msg_arr['ExternalUserID']:'';
            //客服userid
            $userid = isset($msg_arr['UserID'])?$msg_arr['UserID']:'';
            //應(yīng)用id
            $to_user_name = isset($msg_arr['ToUserName'])?$msg_arr['ToUserName']:'';
            //改變類型
            $type = isset($msg_arr['ChangeType'])?$msg_arr['ChangeType']:'';

            if(!empty($external_userid) && !empty($userid)){
                //數(shù)據(jù)庫操作
                if($type == 'add_external_contact'){ //增加
                    $is_ex = $this->db_text->table('qy_wx_back')->where('userid',$userid)->where('external_userid',$external_userid)->find();
                    if($is_ex){ //已存在
                        $update = [
                            'is_del' => 0,
                            'update_time' => date('Y-m-d H:i:s',time())
                        ];
                        $this->db_text->table('qy_wx_back')
                            ->where('userid',$userid)
                            ->where('external_userid',$external_userid)
                            ->update($update);
                        //外部聯(lián)系人詳情處理
                        $rr = $this->updateCustomerInfo(1,$userid,$external_userid);
                    }else{
                        $insert = [
                            'error_code' => $errCode,
                            'error_msg' => $params['errorMsg'],
                            'to_user_name' => $to_user_name,
                            'add_time' => date('Y-m-d H:i:s',time()),
                            'update_time' => date('Y-m-d H:i:s',time()),
                            'type' => $type,
                            'userid' => $userid,
                            'external_userid' => $external_userid,
                            'is_del' => 0
                        ];
                        $this->db_text->table('qy_wx_back')->insert($insert);
                        //外部聯(lián)系人詳情處理
                        $rr = $this->updateCustomerInfo(2,$userid,$external_userid);
                    }
                }elseif($type == 'del_external_contact'){ //刪除
                    $is_ex1 = $this->db_text->table('qy_wx_back')->where('userid',$userid)->where('external_userid',$external_userid)->find();
                    if($is_ex1){
                        $update = [
                            'is_del' => 1,
                            'update_time' => date('Y-m-d H:i:s',time())
                        ];
                        $this->db_text->table('qy_wx_back')
                            ->where('userid',$userid)
                            ->where('external_userid',$external_userid)
                            ->update($update);
                    }else{
                        $insert = [
                            'error_code' => $errCode,
                            'error_msg' => $params['errorMsg'],
                            'to_user_name' => $to_user_name,
                            'add_time' => date('Y-m-d H:i:s',time()),
                            'update_time' => date('Y-m-d H:i:s',time()),
                            'type' => $type,
                            'userid' => $userid,
                            'external_userid' => $external_userid,
                            'is_del' => 1
                        ];
                        $this->db_text->table('qy_wx_back')->insert($insert);
                    }
                    //外部聯(lián)系人詳情處理
                    $rr = $this->updateCustomerInfo(1,$userid,$external_userid);
                }elseif($type == 'edit_external_contact'){
                    $is_ex1 = $this->db_text->table('qy_wx_back')->where('userid',$userid)->where('external_userid',$external_userid)->find();
                    if($is_ex1){
                        $update = [
                            'is_del' => 2,
                            'update_time' => date('Y-m-d H:i:s',time())
                        ];
                        $this->db_text->table('qy_wx_back')
                            ->where('userid',$userid)
                            ->where('external_userid',$external_userid)
                            ->update($update);
                    }else{
                        $insert = [
                            'error_code' => $errCode,
                            'error_msg' => $params['errorMsg'],
                            'to_user_name' => $to_user_name,
                            'add_time' => date('Y-m-d H:i:s',time()),
                            'update_time' => date('Y-m-d H:i:s',time()),
                            'type' => $type,
                            'userid' => $userid,
                            'external_userid' => $external_userid,
                            'is_del' => 1
                        ];
                        $this->db_text->table('qy_wx_back')->insert($insert);
                    }
                    //外部聯(lián)系人詳情處理
                    $rr = $this->updateCustomerInfo(3,$userid,$external_userid);
                }
                //標(biāo)簽處理

                var_dump($msg_arr);die;
            }
        } else {
            $params['errorCode'] = $errCode;
            $params['errorMsg'] = $this->_callbackErrorMsgArr[$errCode];
            $this->putMark($params);
            $insert = [
                'error_code' => $errCode,
                'error_msg' => $params['errorMsg'],
                'to_user_name' => '',
                'add_time' => date('Y-m-d H:i:s',time()),
                'update_time' => date('Y-m-d H:i:s',time()),
                'type' => 'error',
                'userid' => '',
                'external_userid' => '',
                'is_del' => 0
            ];
            $this->db_text->table('qy_wx_back')->insert($insert);
            print("ERR: " . $errCode . "\n\n");
            //exit(-1);
        }
    }

public function putMark($params){
        # 記錄入?yún)?        $time = date('Y-m-d h:i:s',time());
        $params['date'] = date('Y-m-d H:i:s');
        $paramsStr = json_encode($params,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
        $data = $time.$paramsStr;
        $address = Extend_PATH.'externalCallbackEvent_params.log';
        file_put_contents($address,$data."\r\n",FILE_APPEND);
    }

后續(xù)還要進(jìn)行標(biāo)簽更新的處理,到時(shí)候看看需不需要更新上來吧入问,估計(jì)坑少就不寫了丹锹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市队他,隨后出現(xiàn)的幾起案子卷仑,更是在濱河造成了極大的恐慌,老刑警劉巖麸折,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锡凝,死亡現(xiàn)場離奇詭異,居然都是意外死亡垢啼,警方通過查閱死者的電腦和手機(jī)窜锯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芭析,“玉大人锚扎,你說我怎么就攤上這事∧倨簦” “怎么了驾孔?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長惯疙。 經(jīng)常有香客問我翠勉,道長,這世上最難降的妖魔是什么霉颠? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任对碌,我火速辦了婚禮,結(jié)果婚禮上蒿偎,老公的妹妹穿的比我還像新娘朽们。我一直安慰自己怀读,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布骑脱。 她就那樣靜靜地躺著菜枷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪惜姐。 梳的紋絲不亂的頭發(fā)上犁跪,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機(jī)與錄音歹袁,去河邊找鬼坷衍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛条舔,可吹牛的內(nèi)容都是我干的枫耳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼孟抗,長吁一口氣:“原來是場噩夢啊……” “哼迁杨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凄硼,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤铅协,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后摊沉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狐史,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年说墨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骏全。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡尼斧,死狀恐怖姜贡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情棺棵,我是刑警寧澤楼咳,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站烛恤,受9級特大地震影響母怜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜棒动,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宾添。 院中可真熱鬧船惨,春花似錦柜裸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挚赊。三九已至秸妥,卻和暖如春敦迄,著一層夾襖步出監(jiān)牢的瞬間腰池,已是汗流浹背亿鲜。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工篷牌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留假褪,地道東北人光戈。 一個(gè)月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓跨琳,卻偏偏與公主長得像自点,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子脉让,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容