背景:客户首次添加企微相关运营客服之后,需要自动发送对应活动信息,优惠券内容,以及相关短链跳转信息等
企微添加好友调用链路过程
企微回调接口(用于和第三方交互):
企业微信提供的接口:
新客户欢迎语调用:developer.work.weixin.qq.com/document/pa…
打标签接口调用:developer.work.weixin.qq.com/document/pa…
联系我生成企微二维码: developer.work.weixin.qq.com/document/pa…
相关配置:
飞书,企微,微信配置大同小异,创建相关应用,配置对应的回调api,在配置对应的白名单路由等
1:创建相关应用:
2:配置对应的回调路由
2:配置对应的白名单ip:
相关内容:
//回调逻辑处理
@PostMapping(value = "/callback")
public String callBack() {
String token = enterpriseWechatConfig.getEpWechatToken();
String encodingAesKey = enterpriseWechatConfig.getEpWechatEncodingAesKey();
String cropId = enterpriseWechatConfig.getEpWechatReceiveid();
String sMsg = null;
ServletRequestAttributes servletRequestAttributes = null;
try {
if (RequestContextHolder.getRequestAttributes() != null) {
servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
HttpServletRequest request = servletRequestAttributes.getRequest();
String sMsgSignature = request.getParameter("msg_signature").trim();
// 时间戳
String sTimestamp = request.getParameter("timestamp").trim();
// 随机数
String sNonce = request.getParameter("nonce").trim();
InputStream inputStream = request.getInputStream();
String sPostData = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
//解密:
WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(token, encodingAesKey, cropId);
sMsg = wxBizMsgCrypt.DecryptMsg(sMsgSignature, sTimestamp, sNonce, sPostData);
log.info("消息体sMsg:\n{}", sMsg);
JAXBContext jaxbContext = JAXBContext.newInstance(EpQywxCallback.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(sMsg);
EpQywxCallback callback = (EpQywxCallback) unmarshaller.unmarshal(reader);
String userID = callback.getUserID();
String externalUserId = callback.getExternalUserID();
String welcomeCode = callback.getWelcomeCode();
String state = callback.getState();
//当是单向好友才会返回add_half_external_contact事件,即不通过联系我二维码添加,app-隐私里面关闭添加时需要验证,个人二维码添加好友,就是add_half_external_contact事件
if ("add_external_contact".equals(callback.getChangeType())) {
EpUnionActivityType activityType = EpUnionActivityType.getByDesc(state);
if (activityType!=null) {
//异步下发消息:
enterpriseService.sendMsg(welcomeCode, activityType);
//异步打标签:
enterpriseService.fillTag(userID, externalUserId, activityType);
//记录对应企微用户添加的人数
enterpriseService.addUserNum(userID);
}
}
}
}
}catch (Exception e){
log.error("回调异常",e);
}
return sMsg;
}
//引入加解密实体类 https://developer.work.weixin.qq.com/devtool/introduce?id=10128
@Component
@RefreshScope
public class EnterpriseWechatConfig {
@Value("${ep.wechat.token:XXXX}")
public String ep_wechat_token;
@Value("${ep.wechat.encodingAesKey:XXXX}")
public String ep_wechat_encodingAesKey;
@Value("${ep.wechat.receiveid:XXX}")
public String ep_wechat_receiveid;
}
异常问题分析:
1:路由校验不通过
调试工具调用确定是否能返回结果:
网关鉴权放行,以及使用公网的ip路由
2:加解密信息异常:
i:get接口的路由校验通过,但是post接口回调获取的数据为空:
wechat回调信息是xml类型的,如果有配置xss过滤器的话,Xss会拦截这个xml加密报文的内容,注意这个post请求有没有拦截,路由放行
回调的是xml报文,所以需要xml解析工具类来解密对应的报文内容
2:单向好友关系无法发送欢迎语:
双向好友回调事件类型不对: add_external_contact
单向好友回调事件:add_half_external_contact
出现单向好友关系事件的场景:
1:如果成员设置了【加我为联系人时-无需验证-不添加对方到通讯录】
2:企微账号对应的成员已经离职,没有绑定手机号啥的。
异常场景处理:
一:添加客户频繁限制:
1:单人被添加限制:非固定值,如下,需要测试测下边界
单个企微账号客户总数会有5000人上限,可以扩容至2万人
综上存在单账号被添加好友频繁以及总数上线风险:
更新
1:记录对应用户的企微id,直接配置naocs之中,直接读取
2:redis维护一个可分配的企微id池
1:redis记录当天企微被动添加好友的人数,达到阈值之后,暂时剔除该用户,总好友边界接近5000的时候,该企微用户二维码需剔除
二:接口调用频率限制:
developer.work.weixin.qq.com/document/pa…
根据业务量去考虑频率限制
相关参考文档:
缺少回调:developer.work.weixin.qq.com/community/q…