需求:實(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.參考文檔
- https://developer.work.weixin.qq.com/document/path/92129
- https://developer.work.weixin.qq.com/document/path/92114
- https://blog.csdn.net/weixin_39658900/article/details/113475089
3.所遇到的棘手問題(所謂的坑)
所謂的坑亡嫌,還是老樣子嚎于,思路不清楚,所以覺得很坑(騰訊官方文檔)挟冠。
1.驗(yàn)證回調(diào)地址不通過于购。從以下幾點(diǎn)找一下問題所在:首先在瀏覽器另起一個(gè)窗口訪問一下填的地址,看看能不能訪問的通先知染。然后檢查一下驗(yàn)證的接口結(jié)束的地方有沒有一個(gè)返回值肋僧,需要將入?yún)⒅械?code>$sEchoStr返回。還是不行的話可以試一下更換一下token
和EncodingAESKey
控淡。
具體錯(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失敗',
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)開檢查一下就行了。
5.根據(jù)打印寫入的文件中的數(shù)據(jù)進(jìn)行測試解密泵督,返回 -40002 錯(cuò)誤碼趾盐。我遇到這個(gè)的原因是在打印中復(fù)制過來的xml格式有問題,經(jīng)過了
json_encode
后小腊,斜杠前面會多一個(gè)反斜杠救鲤,把其中的反斜杠刪掉就行了。二秩冈、代碼
驗(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ì)坑少就不寫了丹锹。