前言
企业微信的对接,比较复杂,因为企业微信的开发文档中,包含了企业内部开发和第三方应用开发,稍不注意就容易理解偏差,我们使用的是第三方应用的API,开发前期对于文档的梳理非常必要,一定要耐心去整理思路。文档梳理
一、必看板块
1.快速入门重点是“服务商注册应用”,说明了各种回调接口的含义、开发配置信息、创建应用或小程序的步骤。(小编在这里踩过坑)
2.服务端API
小编使用到的接口集中在:
应用授权 身份验证推广二维码消息推送
二、辅助文档
1.运营规范确定使用推广二维码的方式,安装小程序
2.工具与资源
加解密的资源、查询错误码含义、API调用验证
3.开放社区
小编在开放社区自问自答了一个问题:
跳转授权登录,如何解决从http协议跳转就可以成功;从https协议跳转,就报“校验请求来源错误”?
开发亮点
服务商后台安装小程序开发流程一、主要步骤
1.企业微信授权登录:通过此步骤实现服务商租户与企业微信租户实现tenantId信息绑定;2.安装小程序:通过推广二维码扫描安装,安装成功后,服务商后台接收到企业微信回调API发送的消息,进行通讯录信息同步。
二、部分逻辑代码
1.获取企业微信授权登录的地址,拼接state值,实现安全认证 public String getWeChatAuthCode(String entCode) {
StringBuilder url = new StringBuilder();
StringBuilder params = new StringBuilder();
String redirectUrl = TENANT_PATH + LOGIN_REDIRECT_URL;
String state;
if (redisDao.existKey(LOGIN_STATE_KEY + entCode)) {
state = redisDao.getString(LOGIN_STATE_KEY + entCode);
} else {
state = KeyGenerator.randomStr(16);
state = entCode + ":" + state;
redisDao.setStringEx(LOGIN_STATE_KEY + entCode, 300, state);
}
try {
redirectUrl = URLEncoder.encode(redirectUrl, CodeEnum.ENCODE_TYPE.getErrorCode());
} catch (UnsupportedEncodingException e) {
log.error("getWeChatLoginUrl error{}", e.getMessage());
return null;
}
params.append("?appid=")
.append(WeChatConstants.CORP_ID)
.append("&redirect_uri=")
.append(redirectUrl)
.append("&state=")
.append(state)
.append("&usertype=")
.append(USER_TYPE);
url.append(LOGIN_WE_CHAT_URL).append(params);
log.info("getWeChatLoginUrl:{}", url);
return url.toString();
}
2.两种回调API,获取post/get两种请求,并加解密消息体
@RequestMapping(value = "/pushMessage", method = {RequestMethod.GET, RequestMethod.POST})
public void pushMessage(@RequestParam("msg_signature") String sVerifyMsgSig,
@RequestParam("timestamp") String sVerifyTimeStamp,
@RequestParam("nonce") String sVerifyNonce,
@RequestParam(value = "echostr", required = false) String sEchoStr,
HttpServletRequest request, HttpServletResponse response) {
String sDesStr;
try {
WXBizMsgCrypt wxBizMsgCrypt;
if (StringUtils.isNotBlank(sEchoStr)) {
log.info("============回调验证=============");
// get请求 验证URL:消息推送 指令回调、数据回调、系统事件-注册完成回调事件、安装成功回调
wxBizMsgCrypt = new WXBizMsgCrypt(WeChatConstants.TOKEN, WeChatConstants.ENCODING_AES_KEY, WeChatConstants.CORP_ID);
sDesStr = wxBizMsgCrypt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, sEchoStr);
log.info("pushMessage sDesStr:{}", sDesStr);
qyWeChatService.pushMessage(sDesStr);
WeChatUtils.writeToWeb(response, sDesStr);
} else {
log.info("============回调业务数据=============");
// post请求:推送事件:回调事件:推送ticket、授权变更、通讯录变更
String xmlData = WeChatUtils.getBody(request);
Document document = DocumentHelper.parseText(xmlData);
String receiveId = getElementValue(document, "ToUserName");
log.info("xmlData==>" + xmlData);
log.info("receiveId==>" + receiveId);
wxBizMsgCrypt = new WXBizMsgCrypt(WeChatConstants.TOKEN, WeChatConstants.ENCODING_AES_KEY, receiveId);
sDesStr = wxBizMsgCrypt.DecryptMsg(sVerifyMsgSig, sVerifyTimeStamp, sVerifyNonce, xmlData);
log.info("pushEvent sDesStr:{}", sDesStr);
qyWeChatService.pushEvent(sDesStr);
WeChatUtils.writeToWeb(response, WeChatConstants.SUCCESS);
}
} catch (AesException e) {
log.error("AES error:{}", e.getMessage());
} catch (DocumentException e) {
log.error("Parse xml error:{}", e.getMessage());
}
}
跳坑经验
一、企业推送消息
消息参数,title、description字数不少于4个字,否则会发送失败{
"touser": "HaoYue",
"msgtype": "miniprogram_notice",
"agentid": 1000023,
"enable_duplicate_check": 1,
"duplicate_check_interval": 1800,
"miniprogram_notice": {
"appid": "wxe7f3caa522a5de4f",
"title": "phi哈 ",
"description": "浩月抄",
"page": "core/WelcomePage",
"content_item": [
{
"key": "2",
"value": "1"
}
]
}
}
//执行结果:失败
{
"errcode": 40058,
"errmsg": "miniprogram_notice.description exceed min chinese words 4. Invalid input invalid Request Parameter, hint: [1597027824_79_b1488cdcae682c711919a5761f4df67f], from ip: , more info at https://open.work.weixin.qq.com/devtool/query?e=40058"
}
二、上线后,回调地址为测试API
1.原因:在服务商后台更改回调地址后,地址更新未生效2.解决方法:在服务商后台“应用和模板上线板块”,重新上线发布小程序
小结
开发过程中,不断整理思路,不断完善业务逻辑,校验安全,同时对于文档的了解也需要深入,多角度去思考问题出现的原因,同时打印日志,排查问题很重要,小编遇到一个Redis缓存过期,导致安装小程序失败的坑。同样的代码,不同的企业微信租户安装会遇到不同的问题,这与企业微信租户特殊环境有关,打印日志后,确认是缓存过期的问题。