2020-07-31 03:22:19 晓掌柜 版权声明:本文为站长原创文章,转载请写明出处
在之前的业务中,我们的消息推送是使用的微信公众号的模板消息。
但是有几个痛点:
① 模板要申请,不能应急处理一些场景。
② 模板能支持的自定义操作有限。
③ 消息内容及形式相对单一
所以,在最近的版本中,我们准备把内部消息推送统一集中到企业微信上(在企业微信建立专门的应用用以收发消息)
① 首先这个发送消息的程序定义成一个单独的服务节点,统一接收外部请求
② 可配置:满足不同的消息格式及使用场景(卡片消息、文字消息、事件A的消息、事件B的消息)
MSG_TYPE_00(0, "文本消息"),
MSG_TYPE_01(1, "图片消息"),
MSG_TYPE_02(2, "语音消息"),
MSG_TYPE_03(3, "视频消息"),
MSG_TYPE_04(4, "文件消息"),
MSG_TYPE_05(5, "图文消息"),
MSG_TYPE_06(6, "卡片消息");
EVENT_00(0, "货物XX"),
EVENT_01(1, "增值XX"),
EVENT_02(2, "XX件"),
EVENT_03(3, "退XX"),
EVENT_04(4, "待XXX"),
EVENT_05(5, "已XX"),
EVENT_06(6, "退XX过"),
EVENT_07(7, "未XX"),
EVENT_08(8, "货XXX"),
EVENT_09(9, "增XXX成"),
EVENT_10(10, "问XX成"),
EVENT_11(11, "已XXX"),
EVENT_12(12, "程序预警");
作为总的入口进行业务的分发处理。
根据在企业微信注册的信息获取token,作为后续的操作凭证。
因为token会自动过期及腾讯方业务需要过期,所以要加入重试机制。
根据消息类型枚举类中的配置及对应业务场景来动态创建消息内容。
调用企业微信api进行消息发送
监听返回结果值,并作出对应处理。
/**
* 功能描述: 获取应用的操作token
* Param: [isOutTime] 是否过期或不合法...
* Return: java.lang.String
*/
public String getToken(boolean isOutTime){
/* 从redis获取token */
Object tokenObj = redisUtil.get("wechatToken");
if(tokenObj == null || isOutTime){
String url = String.format("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s", groupId, groupSecret);
String rltStr = HttpClientUtil.doGet(url, null);
/* 失败重试3次 */
for(int i=0;i<3;i++){
JSONObject jsonRlt = JSON.parseObject(rltStr);
if(0 != jsonRlt.getIntValue("errcode")){
rltStr = HttpClientUtil.doGet(url, null);
}else{
String tokenStr = jsonRlt.getString("access_token");
/* 保存到redis缓存(token有效期为7200) */
redisUtil.set("wechatToken", tokenStr, 60 * 60 * 2);
return tokenStr;
}
}
}
assert tokenObj != null;
return tokenObj.toString();
}
/**
* 功能描述:消息发送实现类
* Param: [msgType, msgHandlerVO]
* Return: com.bh.enterprisewechat.commons.utils.R
*/
@Override
public R sendMsgByType(int msgType, MsgHandlerVO msgHandlerVO) {
String token = tokenUtil.getToken(false);
if(token == null){
return R.error("获取token失败!");
}
/* 消息发送失败后重试(3次)*/
String rltStr = formatPost(msgType, token, msgHandlerVO);
for(int i=0;i<3;i++){
JSONObject rltJson = JSON.parseObject(rltStr);
int errCode = rltJson.getIntValue("errcode");
if(0 != errCode){
/* 中间判断是否为token过期,或者不合法 */
if(42001 == errCode || 40014 == errCode){
token = tokenUtil.getToken(true);
}
rltStr = formatPost(msgType, token, msgHandlerVO);
}else{
return R.ok();
}
}
return R.error().put("data", rltStr);
}
/**
* 功能描述: 消息分发 (XXX)
* Param: [type, token, msgVO]
* Return: java.lang.String
*/
private String formatPost(int type,String token, MsgHandlerVO msgHandlerVO){
TextMsgVO textMsgVO;
TextCardMsgVO textCardMsgVO;
String rltStr = null;
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + token;
Integer eventKey = msgHandlerVO.getEventType().getKey();
switch (type){
case 0:
/* 此处省略部分业务处理... */
/* 程序预警 */
if(eventKey == 12){
// 此处省略格式化消息内容处理...
textCardMsgVO = buildTextCardMsg("warning", msgHandlerVO);
rltStr = HttpClientUtil.sendJsonStr(url, JSONObject.toJSONString(textCardMsgVO));
}
break;
default:
break;
}
return rltStr;
}