企业微信外部联系人回调事件

说明:

1) 下列"外部联系人" 和 "客户联系" 其实都是一个意思,都是指顾客,但是由于企业微信开发文档中叫"外部联系人",管理后台叫"客户联系", 为方便操作,故本文名称跟企业微信保持一致
2) 下列两段代码实例,默认使用者已经有PHP-SDK, 原生代码案例可以自行前往git下载PHP-SDK(地址见官方文档),ThinkPHP5.*版本案例,可以参考本人下载资源中的PHP-SDK,或者根据官方提供的sdk自行修改命名空间; 由于时间问题,原生代码部分由TP5版本代码修改而成,仅供参考代码,暂未实测; ThinkPHP5.*版本代码亲测有效,有异议欢迎提出讨论

1.作用

     企业成员 添加/删除外部联系人 时,可在企业后台接收添加/删除的外部人数据,及时更新企业后台数据

2.运行原理

 1) 开发者验证回调事件url有效性,验证通过后,可在企业微信管理员后台,配置回调所需的3个参数: 回调事件url, Token , EncodingAESKey2) 企业微信管理后台给相关企业成员配置"客户联系"权限3) 当企业成员(需要配置客户联系操作权限) 添加/删除外部联系人时,企业微信服务器会向外部联系人回调事件url 推送一段加密字符串(xml格式) ,具体事件格式可参照开发文档, 而且务必保证正确处理数据,

3.开发者操作步骤

 1) 管理后台配置外部联系人回调事件url地址,并验证该url有效性A) 先调用调试工具,验证回调事件url有效性,具体参见:![验证回调事件url的详情图片](https://img-blog.csdnimg.cn/20190221220329870.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2R1cmluZ25vbmU=,size_16,color_FFFFFF,t_70)B) 除了A)操作,还需要在该url中,返回解密后的加密消息内容,首先两点;a) 调用PHP-SDK中的XMLparse类中的VerifyUrl方法(Verify方法可验证回调事件url); PHP-SDK可下载本人下载资源中的SDK(此SDK根据ThinkPHP5.0进行了命名空间的封装),或者参考企业微信开发文档自行编写b) **坑一**: 在回调事件中必须 return 企业微信调试工具发送的Get请求结果(ps:企业微信文档中说的是正确响应,经和其技术沟通,并亲测为使用return关键字即可,示例代码如下:$params = $_GET;$obj = new XMLparse();$callbackRes = $obj->VerifyUrl($params);  //调用SDK中的VerifyUrl方法,返回值为解密后的消息,即步骤A)图中的 "测试消息123"return $callbackRes;    // 相当于直接返回明文消息: return  "测试消息123";)c) **坑二**: 验证回调事件url有效性时,即调用verifyUrl方法时,必须先urldecode('echoStr参数'),否则会抛出异常; 若使用原生代码示例,务必自行添加urldecode,若使用框架可自行输出参数查看;(本人使用ThinkPHP5.*框架,ThinkPHp5.*框架中做了urldecode的处理,可以不必开发者手动urldecode;)2) url通过验证后,添加/删除外部联系人时,会想该url推送指定格式的xml数据(加密字符)A)  **坑三**: 接收xml数据时,确保接收的数据事原生的,最好使用 $params = file_get_contents('php://input');    (ps: 本人就是因为在框架配置了htmlspecialchars(html标签过滤函数)这个函数将<>转义了,导致SDK中的DOMDocument类的loadXML方法, 无法读取正确的xml数据,抛出异常,记得将数据恢复成xml格式数据,若使用了htmlspecialchars,记得htmlspecialchars_decode一次)B)  **坑四**: 因为涉及的字符串长度过长(400~750个字节),使用var_dump,echo,print_r均无法正常输出字符内容,建议使用将字符写入文件中(使用函数fopen(),fwrite(),或者file_put_content())C)  具体代码过程参见下列两个版本,以ThinkPHP5.*版本为准,如有异议,欢迎提出讨论3) 详情参见企业微信api开发文档,A)文档地址:https://work.weixin.qq.com/api/doc#90000/90135/90664B) 接口调试工具地址: https://work.weixin.qq.com/api/devtools/devtool.php

3.注意:

 1) 上述有提及四个坑点,请各位开发者多留意 (可结合下列示例代码理解)2) 必须先登录企业管理后台(管理员身份),配置回调事件的url相关的参数,并给相关企业成员配置"客户联系"权限

4.PHP原生代码示例 (使用前提,需要先获取SDK)

<?phpclass External {protected $_weworkConfig = ['corpId' => '', //企业ID];    protected $_externalCallbackEvent = [  //回调事件参数'url' => 'http://www.test.com/External/callbackEvent','token' => '','encodingAESKey' => ''];    protected $_callbackObj;    // 回调事件对象(外部联系人添加/删除)protected $_callbackErrorMsgArr = [   //企业微信(添加/删除外部联系人)回调事件错误码+错误信息'0'=> 'success','-40001'=> '签名验证错误','-40002'=> 'xml解析失败','-40003'=> 'sha加密生成签名失败','-40004'=> 'encodingAesKey 非法','-40005'=> 'corpid 校验错误','-40006'=> 'aes 加密失败','-40007'=> 'aes 解密失败','-40008'=> '解密后得到的buffer非法','-40009'=> 'base64加密失败','-40010'=> 'base64解密失败','-40011'=> '生成xml失败',];public function __construct() {# 回调事件对象$this->_callbackObj = new \weworkapi\callback\WXBizMsgCrypt($this->_externalCallbackEvent['token'], $this->_externalCallbackEvent['encodingAESKey'], $this->_weworkConfig['corpId']); //企业应用回调, 消息加密/解密类WXBizMsgCrypt}/*** 验证(添加/删除外部联系人)回调事件url有效性*/public function verifyUrl($data) {$params = $_GET;$params2 = $_POST;$params = array_merge($params,$params2);    // get数据+post数据try {if (empty($params['msg_signature'])) {throw new \Exception('msg_signature不得为空');}if (empty($params['timestamp'])) {throw new \Exception('timestamp不得为空');}if (empty($params['nonce'])) {throw new \Exception('nonce不得为空');}if (empty($params['echostr'])) {throw new \Exception('echostr不得为空');}$sReplyEchoStr = "";$verifyRes = $this->_callbackObj->VerifyURL($data['msg_signature'], $data['timestamp'], $data['nonce'], urldecode($data['echostr']),$sReplyEchoStr);   // 此处需要urldecode($data['echoStr'])0 !== $verifyRes && exception('errCode: '.$verifyRes .', errMsg: '.$this->_callbackErrorMsgArr[$verifyRes]);return $sReplyEchoStr;} catch (\Exception $ex) {return ['errCode'=>'0084','errMsg'=>$ex->getMessage()];}return ['errCode'=>'0','errMsg'=>'success','data'=>$verifyRes];}/*** 测试企业微信的外部联系人事件回调*/public function callbackEvent() {$params = $_GET; //get参数$params['xmlContent'] = file_get_contents('php://input');  //post的xml数据# 记录入参$params['date'] = date('Y-m-d H:i:s');$paramsStr = json_encode($params);$fp = fopen('./externalCallbackEvent_params.log', 'w');fwrite($fp, $paramsStr);try {//若回调url验证通过,处理回调的xml消息if (!empty($params['xmlContent']) && empty($params['echostr'])) {   $dealRes = $this->dealCallbackEvent($params);if ('success' !== $dealRes['desc']) {throw new \Exception($dealRes['desc']);}# 记录调用结果$callbakcRes = json_encode(['date'=>date('Y-m-d H:i:s'),'result'=>$dealRes['data']]);$fp2 = fopen('./externalCallbackEvent_result.log', 'w');fwrite($fp2, $callbakcRes);return $dealRes['data'];} else {     //验证url有效性$verifyRes = $this->verifyUrl($params);if ('success' !== $verifyRes['desc']) {throw new \Exception($verifyRes['desc']);}return $verifyRes['data'];  // 解密后的消息内容(务必原文输出),否则报错}} catch (\Exception $ex) {return ['errCode'=>'0083','errMsg'=>$ex->getMessage()];}}/*** 验证(添加/删除外部联系人)回调事件消息加密*/public function dealCallbackEvent($data) {try {# 解密$decryptMsg = $this->decryptMsg($data);$decryptMsgArr = $this->XMLString2Array($decryptMsg);switch ($decryptMsgArr['ChangeType']) {case 'add_external_contact':    // 添加外部联系人回调事件$dealRes = $this->addExternalCallbackEvent($decryptMsgArr);break;case 'del_external_contact':    // 删除外部联系人回调事件$dealRes = $this->delExternalCallbackEvent($decryptMsgArr);break;default:throw new \Exception($type . '回调事件类型不合法');break;}return $dealRes;}catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 消息加密*/public function encryptMsg($data) {try {//        $sReqTimeStamp = "1409659813";//        $sReqNonce = "1372623149";//        $sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";$sReqTimeStamp = $data['timestamp'];    //时间戳$sReqNonce = $data['nonce'];    //随机字符串$content = $data['content'];    //被加密的消息内容// 需要发送的明文$sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[".Config::get('wework.CORP_ID')."]]></FromUserName><CreateTime>".$sReqNonce."</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[".$content."]]></Content><MsgId>1234567890123456</MsgId><AgentID>".Config::get('WEWORK_AGENT_ID')."</AgentID></xml>";$sEncryptMsg = ""; //xml格式的密文$errCode = $this->_callbackObj->EncryptMsg($sRespData, $sReqTimeStamp, $sReqNonce, $sEncryptMsg);if (0 !== $errCode) {throw new \Exceptionexception('errCode: '.$errCode .', errMsg: '.$this->_callbackErrorMsgArr[$errCode]);}return $sEncryptMsg;} catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 消息解密*/public function decryptMsg($data) {try {//        $sReqMsgSig = "477715d11cdb4164915debcba66cb864d751f3e6";//        $sReqTimeStamp = "1409659813";//        $sReqNonce = "1372623149";//        $sReqData = "<xml><ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt><AgentID><![CDATA[218]]></AgentID></xml>";$sReqMsgSig = $data['msg_signature'];$sReqTimeStamp = $data['timestamp'];$sReqNonce = $data['nonce'];$sReqData = $data['xmlContent'];    // post请求的密文数据$decryptMsg = "";  // 解析之后的明文$errCode = $this->_callbackObj->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData, $decryptMsg);if (0 !== $errCode) {throw new \Exception('errCode: '.$errCode .', errMsg: '.$_callbackErrorMsgArr[$errCode]);}return $decryptMsg;} catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 提取xml数据中的指定参数* (转换原理:xml字符串->xml对象->json对象->数组)* @param string xml格式数据* @return array array格式数据*/public function XMLString2Array($xmlStr) {try {//xml字符转换为xml对象$xmlObj = simplexml_load_string($xmlStr,'SimpleXMLElement', LIBXML_NOCDATA);$jsonObj = json_encode($xmlObj);return json_decode($jsonObj,true);} catch (\Exception $ex) {throw new Exception($ex->getMessage());}}/*** 添加外部联系人回调处理* 原理:*  1) 获取外部联系人userid(异步处理时,userid从队列中获取)*  2) 获取外部联系人详情*  3) 将外部联系人插入数据库* @param array */public function addExternalCallbackEvent($data) {}/*** 删除外部联系人回调处理* 原理:*   1) 获取外部联系人userid(异步处理时,userid从队列中获取)*   2) 删除本地数据库中外部联系人记录*/public function delExternalCallbackEvent($data) {}}

5. ThinkPHP5.*实例(先获取PHP-SDK)

<?php
use \think\Validate;    //ThinkPHP5.*的验证类
class External {protected $_weworkConfig = ['corpId' => '',    //企业ID];    protected $_externalCallbackEvent = [  //回调事件参数'url' => 'http://www.test.com/External/callbackEvent','token' => '','encodingAESKey' => ''];    protected $_callbackObj;    // 回调事件对象(外部联系人添加/删除)protected $_callbackErrorMsgArr = [   //企业微信(添加/删除外部联系人)回调事件错误码+错误信息'0'=> 'success','-40001'=> '签名验证错误','-40002'=> 'xml解析失败','-40003'=> 'sha加密生成签名失败','-40004'=> 'encodingAesKey 非法','-40005'=> 'corpid 校验错误','-40006'=> 'aes 加密失败','-40007'=> 'aes 解密失败','-40008'=> '解密后得到的buffer非法','-40009'=> 'base64加密失败','-40010'=> 'base64解密失败','-40011'=> '生成xml失败',];public function __construct() {# 回调事件对象$this->_callbackObj = new \weworkapi\callback\WXBizMsgCrypt($this->_externalCallbackEvent['token'], $this->_externalCallbackEvent['encodingAESKey'], $this->_weworkConfig['corpId']); //企业应用回调,消息加密/解密类WXBizMsgCrypt}/*** 测试企业微信的外部联系人事件回调*/public function callbackEvent() {$params = Request::instance()->param(); //get参数$params['xmlContent'] = file_get_contents('php://input');  //post的xml数据# 记录入参$params['date'] = date('Y-m-d H:i:s');$paramsStr = json_encode($params);$fp = fopen('./externalCallbackEvent_params.log', 'w');fwrite($fp, $paramsStr);try {//若回调url验证通过,处理回调的xml消息if (!empty($params['xmlContent']) && empty($params['echostr'])) {   $dealRes = $this->dealCallbackEvent($params);'success' !== $dealRes['desc'] && exception($dealRes['desc']);# 记录调用结果$callbakcRes = json_encode(['date'=>date('Y-m-d H:i:s'),'result'=>$dealRes['data']]);$fp2 = fopen('./externalCallbackEvent_result.log', 'w');fwrite($fp2, $callbakcRes);return $dealRes['data'];} else {     //验证url有效性$verifyRes = $this->verifyUrl($params);'success' !== $verifyRes['desc'] && exception($verifyRes['desc']);return $verifyRes['data'];  // 解密后的消息内容(务必原文输出),否则报错}} catch (\Exception $ex) {$this->result([],'0083',$ex->getMessage(),'json');}}/*** 验证(添加/删除外部联系人)回调事件消息加密*/public function dealCallbackEvent($data) {try {$rules = ['msg_signature' => 'require','timestamp' => 'require','nonce' => 'require','xmlContent' => 'require',  //接企业微信服务器发送的回调的xml消息内容];$validate = new Validate($rules);!$validate->check($params) && exception($validate->getError());
//            $params['xmlContent'] = htmlspecialchars_decode($params['xmlContent']); //若配置中使用了htmlspecialchars函数,转义了<,>等符号# 解密$decryptMsg = $this->decryptMsg($data);$decryptMsgArr = $this->XMLString2Array($decryptMsg);switch ($decryptMsgArr['ChangeType']) {case 'add_external_contact':    // 添加外部联系人回调事件$dealRes = $this->addExternalCallbackEvent($decryptMsgArr);break;case 'del_external_contact':    // 删除外部联系人回调事件$dealRes = $this->delExternalCallbackEvent($decryptMsgArr);break;default:throw new \Exception($type . '回调事件类型不合法');break;}return $dealRes;}catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 验证URL有效性* @param array 参数* @return int 错误码,0-正常,否则出错*/public function verifyUrl($data) {try {$rules = ['msg_signature' => 'require','timestamp' => 'require','nonce' => 'require','echostr' => 'require',];$validate = new Validate($rules);!$validate->check($params) && exception($validate->getError());$sReplyEchoStr = "";$verifyRes = $this->_callbackObj->VerifyURL($data['msg_signature'], $data['timestamp'], $data['nonce'], $data['echostr'],$sReplyEchoStr);   // 此处不需要urldecode($data['echoStr']),初步猜测是TP5的Request类已经做过了urldecode处理0 !== $verifyRes && exception('errCode: '.$verifyRes .', errMsg: '.$this->_callbackErrorMsgArr[$verifyRes]);return $sReplyEchoStr;} catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 消息加密*/public function encryptMsg($data) {try {
//        $sReqTimeStamp = "1409659813";
//        $sReqNonce = "1372623149";
//        $sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[wx5823bf96d3bd56c7]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId><AgentID>128</AgentID></xml>";$sReqTimeStamp = $data['timestamp'];    //时间戳$sReqNonce = $data['nonce'];    //随机字符串$content = $data['content'];    //被加密的消息内容// 需要发送的明文$sRespData = "<xml><ToUserName><![CDATA[mycreate]]></ToUserName><FromUserName><![CDATA[".Config::get('wework.CORP_ID')."]]></FromUserName><CreateTime>".$sReqNonce."</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[".$content."]]></Content><MsgId>1234567890123456</MsgId><AgentID>".Config::get('WEWORK_AGENT_ID')."</AgentID></xml>";$sEncryptMsg = ""; //xml格式的密文$errCode = $this->_callbackObj->EncryptMsg($sRespData, $sReqTimeStamp, $sReqNonce, $sEncryptMsg);0 !== $errCode && exception('errCode: '.$errCode .', errMsg: '.$this->_callbackErrorMsgArr[$errCode]);return $sEncryptMsg;} catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 消息解密*/public function decryptMsg($data) {try {//        $sReqMsgSig = "477715d11cdb4164915debcba66cb864d751f3e6";//        $sReqTimeStamp = "1409659813";//        $sReqNonce = "1372623149";//        $sReqData = "<xml><ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt><AgentID><![CDATA[218]]></AgentID></xml>";$sReqMsgSig = $data['msg_signature'];$sReqTimeStamp = $data['timestamp'];$sReqNonce = $data['nonce'];$sReqData = $data['xmlContent'];    // post请求的密文数据$decryptMsg = "";  // 解析之后的明文$errCode = $this->_callbackObj->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData, $decryptMsg);0 !== $errCode && exception('errCode: '.$errCode .', errMsg: '.$this->_callbackErrorMsgArr[$errCode]);return $decryptMsg;} catch (\Exception $ex) {throw new \Exception($ex->getMessage());}}/*** 提取xml数据中的指定参数* (转换原理:xml字符串->xml对象->json对象->数组)* @param string xml格式数据* @return array array格式数据*/public function XMLString2Array($xmlStr) {try {//xml字符转换为xml对象$xmlObj = simplexml_load_string($xmlStr,'SimpleXMLElement', LIBXML_NOCDATA);$jsonObj = json_encode($xmlObj);return json_decode($jsonObj,true);} catch (\Exception $ex) {throw new Exception($ex->getMessage());}}/*** 添加外部联系人回调处理* 原理:*  1) 获取外部联系人userid(异步处理时,userid从队列中获取)*  2) 获取外部联系人详情*  3) 将外部联系人插入数据库* @param array */public function addExternalCallbackEvent($data) {}/*** 删除外部联系人回调处理* 原理:*   1) 获取外部联系人userid(异步处理时,userid从队列中获取)*   2) 删除本地数据库中外部联系人记录*/public function delExternalCallbackEvent($data) {}
}

企业微信外部联系人回调事件相关推荐

  1. php 企业微信指令回调借款_企业微信外部联系人回调事件

    企业微信外部联系人回调事件 说明: 1) 下列"外部联系人" 和 "客户联系" 其实都是一个意思,都是指顾客,但是由于企业微信开发文档中叫"外部联系人 ...

  2. 企业微信外部联系人怎么更高效的添加?

    搜索添加好友 一.企业微信侧添加外部好友入口 1.[手机端->消息页面右上角"+"->加微信/添加客户],可选择面对面添加.通过手机号添加(不支持微信号).从微信好友中 ...

  3. 企业微信的外部联系人回调处理技巧

    一.关于设置接收事件服务器的信息 在企业微信管理后台的"客户联系-客户"页面,点开"API"小按钮,再点击"接收事件服务器"配置,进入配置页 ...

  4. 【分享】如何自动同步企业微信外部客户信息到CRM系统?

    许多企业的销售人员利用企业微信添加外部客户,与客户沟通,但是销售添加外部客户后并不加外部客户录入到企业CRM中.另外,即便是录入了客户到企业CRM系统中,也经常不去更新外部联系人的信息变化到企业CRM ...

  5. 企业微信外部群和内部群有什么区别?如何创建外部群

    一.企业微信外部群和内部群的区别 1.成员来源渠道不同 企业微信内部群的群成员必须是同一公司的企业微信用户,而外部群是可以同时含有不同企业的企业微信用户与个人微信用户的. PS:需要注意的是,因为微信 ...

  6. 企业微信外部群机器人api接口sdk登陆

    用代码实现hook拦截获取到微信二维码,用到的工具有 ce od. 先看下图片在内存里面的表现形式,微信登陆的二维码是一个png的格式,看下png在内存的表现形式,看下图,就是png在内存里面的格式, ...

  7. 企业微信如何自动同步外部客户信息到CRM系统

    许多企业的销售人员利用企业微信添加外部客户,与客户沟通,但是销售添加外部客户后并不加外部客户录入到企业CRM中.另外,即便是录入了客户到企业CRM系统中,也经常不去更新外部联系人的信息变化到企业CRM ...

  8. 请签收裂变指南—公众号联动企业微信双向获客

    大家好,我是Linkflow增长黑客.最近很多客户都问,如何利用裂变海报功能进行公众号和企业微信双重裂变,既能带来公众号粉丝,又能沉淀企业微信好友.今天我就给大家拆解整套裂变玩法,如何通过Linkfl ...

  9. Java实现企业微信回调配置

    在使用前阅读官方文档:回调配置文档 一.配置回调服务 一.在企业微信管理后台配置三个配置 分别是:URL, Token, EncodingAESKey.打开企业微信后台-->管理工具--> ...

  10. 【企业微信急速救心丸】(一)第三方应用开发 - Java整合企业微信回调

    一.首先要了解开发场景,第三方应用开发.企业内部开发.智慧硬件开发的区别. 企业微信对应有三个开发文档,要注意三个开发文档虽然说部分接口是通用的,但是其接口获取的内容.调用的本质却大有不同,我建议先把 ...

最新文章

  1. 我又发现了7个让人心动的宝藏软件,很少有人知道
  2. 用指针查找数组中温度值为32的天数
  3. Linux使用百度云
  4. 2018.12.5 区块链论文翻译
  5. 网站如何获得优质链接
  6. 《Java大学教程》—第5章 数组
  7. socket 套接字的基本概念
  8. HDU-2688 Rotate
  9. Linux---cacti安装后不出图
  10. 一个典型的加了 SAP 注解的 OData 服务明细分析
  11. 怎么查看eclipse的版本号
  12. Charbonnier Loss
  13. 讲讲你理解的服务治理
  14. 非合作关系设定下的多智能体强化学习
  15. 号外:中国雅虎相册即将关闭原图下载 请网友及时备份
  16. vue 里面的slot属性
  17. 分布式计算模式:流水线
  18. HTML初识:网页结构、标签、特殊符号、列表
  19. html调用一言api,一言-纯净API
  20. 微信小程序开发一个小型商城(八、个人页面)

热门文章

  1. C语言 - 学习实践
  2. 知识笔记 - 平头哥ratel安卓Hook框架的安装与简单使用
  3. 基于bind搭建智能dns
  4. 如何把应用程序变成.exe执行文件
  5. PostgreSQL备份和恢复
  6. 前端上半年工作总结、下半年工作计划
  7. html各类表格制作,HTML:复杂表格制作
  8. android tv 下载地址,Android TV获取所有的应用apk
  9. 大龄程序员找工作,为什么这么难?能力与年龄不匹配
  10. xml保存图片和读取图片(一)