微信通知

简介: 基于企业微信与小程序集成,通过API获取access_token,查询通讯录并匹配医生信息,异步发送小程序通知消息。需配置企业微信appId、secret及小程序信息,实现订单提醒等场景的精准推送。

1.前置条件
● 企业微信appId
● 企业微信secret
● 企业微信绑定小程序
● 小程序的appId
2.发送示例
2.1 获取access_token(HTTPS-GET)

请求URL:
https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=corpid&corpsecret=corpsecret

示例入参:
corpid=wx161we55e1fe5e4fr
corpsecret=Rspav9pmjem3zve8fkjqe6yTtCs78Rwdabn6tNdU1g

public class AccessToken {
// 获取到的凭证
private String token;
// 凭证有效时间,单位:秒
private int expiresIn;

public String getToken() {
    return token;
}

public void setToken(String token) {
    this.token = token;
}

public int getExpiresIn() {
    return expiresIn;
}

public void setExpiresIn(int expiresIn) {
    this.expiresIn = expiresIn;
}

}
// url就是上述的,完整如下:
// https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=wx161we55e1fe5e4fr&corpsecret=Rspav9pmjem3zve8fkjqe6yTtCs78Rwdabn6tNdU1g
public static AccessToken getAccessToken(String url) {
logger.info("[WeixinUtil.getAccessToken]:start getAccessToken,url:" + url);
AccessToken accessToken = null;
JSONObject jsonObject = httpRequest(url, "GET", null);
if (jsonObject != null) {
try {
accessToken = new AccessToken();
accessToken.setToken(jsonObject.getString("access_token"));
accessToken.setExpiresIn(jsonObject.getInteger("expires_in"));
} catch (JSONException e) {
accessToken = null;
logger.error("[WeixinUtil.getAccessToken]:getAccessToken occured an JSONException,errcode:"

                     + jsonObject.getInteger("errcode") + ",errmsg:" + jsonObject.getString("errmsg") + ",JSONException:" + e);
    }
}
logger.info("[WeixinUtil.getAccessToken]:end getAccessToken.");
return accessToken;

}

2.2 发送
logger.info("发送企业号获取Token结束:" + accessTokenUrl + ",accessToken:" + JSONObject.toJSONString(accessToken));
// 查询通讯录分组,分组ID:在线咨询医生
String getDeptUserUrl = null;
if(10000 == hospitalId) {
getDeptUserUrl = WechatUtil.QY_GET_DEPT_USER_URL_XMHA.replace("ACCESS_TOKEN", accessToken.getToken())
.replace("DEPARTMENT_ID", "123").replace("FETCH_CHILD", "1");
} else if(10001 == hospitalId) {
getDeptUserUrl = WechatUtil.QY_GET_DEPT_USER_URL_XMHA.replace("ACCESS_TOKEN", accessToken.getToken())
.replace("DEPARTMENT_ID", "124").replace("FETCH_CHILD", "1");
}

JSONObject hResponse = WechatUtil.httpRequest(getDeptUserUrl, "GET", null);
if (null == hResponse) {
logger.info("未能成功获取到通讯录");
return;
}
String docNo = getDoctorNo(doctorNo);
WXQYUser toWXQYUser = null;
List wXQYUserList = getWXQYUserList(hResponse);
for (WXQYUser wxQYUser : wXQYUserList) {
if (docNo.equals(wxQYUser.getHisid())) {
// 发消息
toWXQYUser = wxQYUser;
break;
}
}

if (null != toWXQYUser) {
String toUserId = toWXQYUser.getUserid();
String time = DateUtil.formatDate("MM-dd HH:mm", new Date());
String descTime = time.split(" ")[0].substring(0, 2) + "月" +
time.split(" ")[0].substring(3) + "日 " +
time.split(" ")[1];

String appIdForMiniProgram = imSystemConfigService.getImSystemConfig(hospitalId, HUUtil.APP_ID_FOR_MINI_PROGRAM);

String jsonParam = "{\"touser\": \"" + toUserId + "\",\"toparty\":\"\",\"totag\":\"\",\"msgtype\":\"miniprogram_notice\",\"miniprogram_notice\":" +
    "{\"appid\":\"" +appIdForMiniProgram +  "\",\"page\":\"pages/index/chat/trade-start/trade-start?orderNo=" + orderNo +"\"," +
    "\"title\":\"新订单接诊提醒\",\"description\": \"" + descTime + "\",\"emphasis_first_item\":true," +
    "\"content_item\":[{\"key\":\"接诊通知\",\"value\":\"来新咨询订单了\"},{\"key\":\"咨询人\",\"value\":\""+subTitle+"\"},{\"key\":\"病情描述\",\"value\":\""+content+"\"}]},\"enable_id_trans\":0," +
    "\"enable_duplicate_check\":0,\"duplicate_check_interval\":1800}";

logger.info("开始发送微信企业号消息,入参:" + jsonParam);

String imsServiceDomainConfigStr = imSystemConfigService.getImSystemConfig(hospitalId,
                                                                           HUUtil.IMS_SERVICE_WECHAT_QYH_TEMPLATE_DOMAIN_CONFIG_KEY);
if (null == imsServiceDomainConfigStr || "".equals(imsServiceDomainConfigStr)) {
    logger.info("IMS发送微信企业号消息服务地址配置信息不存在:" + hospitalId);
    return;
}

imsServiceDomainConfigStr = imsServiceDomainConfigStr + "?access_token=" + accessToken.getToken();
String result = HUHttpUtil.sendJsonPostRequest(imsServiceDomainConfigStr, jsonParam, 0);
logger.info("开始发送微信企业号消息,结果:" + result);

} else {
logger.info("该医生" + doctorNo + "在企业号通讯录中不存在,终止发送企业号消息");
}
完整代码示例(建议异步)
private static final ThreadLocal synExecuteService = ThreadLocal.withInitial(() -> Executors.newFixedThreadPool(200));

private final static String QY_ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=CORPID&corpsecret=SECRET";

private final static String QY_GET_DEPT_USER_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token=ACCESS_TOKEN&department_id=DEPARTMENT_ID&fetch_child=FETCH_CHILD";

public void sendOpenWxMsg(final String doctorNo, final String title, final String subTitle, final String content, final String toUrl,
final String orderNo, final long hospitalId) {
synExecuteService.submit(() -> {
String appIdAppSecretConfigStr = imSystemConfigService.getImSystemConfig(hospitalId, HUUtil.WEIXIN_QY_APPID_SECRET_CONFIG_FOR_MINI_PROGRAM);
if (null == appIdAppSecretConfigStr || "".equals(appIdAppSecretConfigStr)) {
logger.info("未查询到APPID信息:" + hospitalId + ",KEY:" + HUUtil.WEIXIN_QY_APPID_SECRET_CONFIG);
return;
}
String accessTokenUrl = WechatUtil.QY_ACCESS_TOKEN_URL_XMHA.replace("CORPID", appIdAppSecretConfigStr.split("=")[0])
.replace("SECRET", appIdAppSecretConfigStr.split("=")[1]);
AccessToken accessToken = WechatUtil.getAccessToken(accessTokenUrl);
if (null == accessToken) {
logger.info("未能成功获取到AccessToken");
return;
}

    logger.info("发送企业号获取Token结束:" + accessTokenUrl + ",accessToken:" + JSONObject.toJSONString(accessToken));
    // 查询通讯录分组,分组ID:在线咨询医生
    String getDeptUserUrl = null;
    // 不同医院部门编号不一样,对应部门编号在企业微信查看
    if(10000 == hospitalId) {
        getDeptUserUrl = WechatUtil.QY_GET_DEPT_USER_URL_XMHA.replace("ACCESS_TOKEN", accessToken.getToken())
            .replace("DEPARTMENT_ID", "123").replace("FETCH_CHILD", "1");
    } else if(10001 == hospitalId) {
        getDeptUserUrl = WechatUtil.QY_GET_DEPT_USER_URL_XMHA.replace("ACCESS_TOKEN", accessToken.getToken())
            .replace("DEPARTMENT_ID", "124").replace("FETCH_CHILD", "1");
    }

    JSONObject hResponse = WechatUtil.httpRequest(getDeptUserUrl, "GET", null);
    if (null == hResponse) {
        logger.info("未能成功获取到通讯录");
        return;
    }
    String docNo = getDoctorNo(doctorNo);
    WXQYUser toWXQYUser = null;
    List<WXQYUser> wXQYUserList = getWXQYUserList(hResponse);
    for (WXQYUser wxQYUser : wXQYUserList) {
        if (docNo.equals(wxQYUser.getHisid())) {
            // 发消息
            toWXQYUser = wxQYUser;
            break;
        }
    }

    if (null != toWXQYUser) {
        String toUserId = toWXQYUser.getUserid();
        String time = DateUtil.formatDate("MM-dd HH:mm", new Date());
        String descTime = time.split(" ")[0].substring(0, 2) + "月" +
            time.split(" ")[0].substring(3) + "日  " +
            time.split(" ")[1];

        String appIdForMiniProgram = imSystemConfigService.getImSystemConfig(hospitalId, HUUtil.APP_ID_FOR_MINI_PROGRAM);

        String jsonParam = "{\"touser\": \"" + toUserId + "\",\"toparty\":\"\",\"totag\":\"\",\"msgtype\":\"miniprogram_notice\",\"miniprogram_notice\":" +
            "{\"appid\":\"" +appIdForMiniProgram +  "\",\"page\":\"pages/index/chat/trade-start/trade-start?orderNo=" + orderNo +"\"," +
            "\"title\":\"新订单接诊提醒\",\"description\": \"" + descTime + "\",\"emphasis_first_item\":true," +
            "\"content_item\":[{\"key\":\"接诊通知\",\"value\":\"来新咨询订单了\"},{\"key\":\"咨询人\",\"value\":\""+subTitle+"\"},{\"key\":\"病情描述\",\"value\":\""+content+"\"}]},\"enable_id_trans\":0," +
            "\"enable_duplicate_check\":0,\"duplicate_check_interval\":1800}";

        logger.info("开始发送微信企业号消息,入参:" + jsonParam);
        // 微信企业号消息发送服务地址 http://ip:port/mp-api/wechat/enterprise/message/send
        String imsServiceDomainConfigStr = imSystemConfigService.getImSystemConfig(hospitalId, HUUtil.IMS_SERVICE_WECHAT_QYH_TEMPLATE_DOMAIN_CONFIG_KEY);
        if (null == imsServiceDomainConfigStr || "".equals(imsServiceDomainConfigStr)) {
            logger.info("IMS发送微信企业号消息服务地址配置信息不存在:" + hospitalId);
            return;
        }

        imsServiceDomainConfigStr = imsServiceDomainConfigStr + "?access_token=" + accessToken.getToken();
        String result = HUHttpUtil.sendJsonPostRequest(imsServiceDomainConfigStr, jsonParam, 0);
        logger.info("开始发送微信企业号消息,结果:" + result);
    } else {
        logger.info("该医生" + doctorNo + "在企业号通讯录中不存在,终止发送企业号消息");
    }
});

}

/**

 * 发送GET请求
 *
 * @param requestUrl
 * @param requestMethod
 * @param outputStr
 * @return
 */

public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
logger.info("[WeixinUtil.httpRequest]:请求入参:" + requestUrl);
String respStr = HUHttpUtil.sendGet(requestUrl, null);
logger.info("[WeixinUtil.httpRequest]:请求响应:" + respStr);
try {
return JSON.parseObject(respStr);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

private List getWXQYUserList(JSONObject hResponse) {
List wXQYUserList = (List) hResponse.get("userlist");
List nmList = null;
WXQYUser wxQYUser = null;
JSONObject mm = null;
List wxQYUserList = new ArrayList();
for (JSONObject jsObject : wXQYUserList) {
if (jsObject.containsKey("userid")) {
if (jsObject.containsKey("extattr")) {
mm = jsObject.getJSONObject("extattr");
if (null != mm.get("attrs")) {
nmList = (List) mm.get("attrs");
for (JSONObject nmObject : nmList) {
if (nmObject.containsKey("name") && "hisid".equals(nmObject.getString("name"))
&& null != nmObject.getString("value") && !"".equals(nmObject.getString("value"))) {
wxQYUser = new WXQYUser();
wxQYUser.setUserid(jsObject.getString("userid"));
wxQYUser.setName(jsObject.getString("name"));
wxQYUser.setMobile(jsObject.getString("mobile"));
wxQYUser.setHisid(nmObject.getString("value"));
wxQYUserList.add(wxQYUser);
}
}
}
}
}
}
return wxQYUserList;
}

// 企业微信存储12345,数据库存储:医院ID+12345,随意这里做截取再去匹配
private String getDoctorNo(String doctorNo) {
if (doctorNo.startsWith("10000")) {
return doctorNo.substring(5, doctorNo.length());
}
if (doctorNo.startsWith("10001")) {
return doctorNo.substring(5, doctorNo.length());
}

return doctorNo;

}
class WXQYUser {

private String userid;

private String name;

private String mobile;

private String hisid;

public String getUserid() {
    return userid;
}

public void setUserid(String userid) {
    this.userid = userid;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getMobile() {
    return mobile;
}

public void setMobile(String mobile) {
    this.mobile = mobile;
}

public String getHisid() {
    return hisid;
}

public void setHisid(String hisid) {
    this.hisid = hisid;
}

}

相关文章
|
5月前
|
运维 监控 搜索推荐
用低代码做了一个又一个项目之后,企业开始寻找可沉淀可复用的架构
企业推进数字化时,低代码因“快速搭建”广受青睐,但随规模扩大,系统维护难、重复建设、逻辑缠绕等问题凸显。真正挑战不在工具,而在缺乏可复用、可持续演进的能力体系。低代码的价值不应止于“做得快”,而应转向“沉淀得住”——通过统一模型、模块化组件、标准化流程,构建可继承、可装配的产品化能力。
263 0
|
5月前
|
JSON 算法 安全
调用拼多多开放平台 API 获取店铺列表
本文介绍如何通过拼多多开放平台API获取店铺列表,涵盖接口调用流程、参数构造、签名生成及响应处理,助开发者安全高效实现店铺信息查询。
701 0
|
5月前
|
人工智能 运维 监控
Flink 智能调优:从人工运维到自动化的实践之路
作者:黄睿 阿里云智能集团产品专家 本文基于阿里云 Flink 平台的实际实践经验整理,希望能为广大流计算从业者提供有价值的参考。
337 26
Flink 智能调优:从人工运维到自动化的实践之路
|
5月前
|
存储 JSON 关系型数据库
如何在MySQL中查询存储为JSON格式的数据
以上就是在MySQL中查询JSON格式数据的一些方法。在实际使用中,针对不同的查询需求,要选择合适的JSON路径表达式和函数进行数据查询。随着实际情况的复杂性增加,可能会需要更复杂的路径表达式和JSON处理函数的组合来实现目标。尽管介绍的内容较为综合,但目的是为了给出一个可操作的视野,来处理存储在MySQL中的JSON数据。在对这些方法有了一定了解之后,可以更进一步地深入学习和探索更多高级的用法。
310 8
|
8月前
|
SQL Java 数据库连接
事务的七种传播行为及其应用场景
本文介绍了事务的七种传播行为及其应用场景,包括 PROPAGATION_REQUIRED、PROPAGATION_SUPPORTS、PROPAGATION_REQUIRES_NEW 等,帮助开发者理解事务管理机制。同时讲解了 Java 中 SQL 操作与对象数据不同步的问题,强调重新查询与手动管理的必要性,并说明 MyBatis 批量操作的最佳实践。
|
5月前
|
存储 人工智能 分布式计算
中国AI云市场阿里云占比35.8%位列第一
国际权威市场调研机构英富曼(Omdia)发布《中国AI云市场,1H25》报告——2025年上半年,中国AI云市场规模达223亿元,阿里云占比35.8%位列第一,市场份额高于2到4名的总和,凭“AI全栈”继续引领市场发展。
|
安全 物联网 物联网安全
制定统一的物联网技术标准和规范的难点有哪些?
制定统一的物联网技术标准和规范的难点有哪些?
576 58
|
11月前
|
数据采集 存储 NoSQL
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
基于Scrapy-Redis的分布式景点数据爬取与热力图生成
734 67
|
9月前
|
存储 算法 区块链
从零实现Python扫雷游戏:完整开发指南与深度解析
扫雷作为Windows经典游戏,承载了许多人的童年回忆。本文将详细介绍如何使用Python和Tkinter库从零开始构建一个功能完整的扫雷游戏,涵盖游戏设计、算法实现和界面开发的全过程。
665 1
|
存储 缓存 监控
Linux缓存管理:如何安全地清理系统缓存
在Linux系统中,内存管理至关重要。本文详细介绍了如何安全地清理系统缓存,特别是通过使用`/proc/sys/vm/drop_caches`接口。内容包括清理缓存的原因、步骤、注意事项和最佳实践,帮助你在必要时优化系统性能。
1400 78