一、场景概述
企业微信作为企业级协同办公平台,其消息通知能力可无缝集成到内部系统中。本文将通过Java代码示例,详细讲解如何快速对接企业微信API,实现自动化消息推送功能,适用于告警通知、审批提醒等业务场景。
二、前置条件准备
-
企业微信管理后台配置
-
登录企业微信管理后台
-
进入「应用管理」→ 创建/选择自建应用
-
记录关键参数:
-
AgentId
(应用ID) -
Secret
(应用密钥) -
CorpId
(企业ID,位于「我的企业」页面)
-
-
-
核心代码实现(发送文本消息)
@Configuration public class WeChatConfig { @Value("${wechat.corpId}") private String corpId; @Value("${wechat.secret}") private String secret; @Value("${wechat.tokenUrl}") private String tokenUrl; @Value("${wechat.agentId}") private String agentId; // 获取 AccessToken 的 URL public String getAccessTokenUrl() { return tokenUrl + "?corpid=" + corpId + "&corpsecret=" + secret; } /** * 其他配置,如 AgentId 等 */ public String getAgentId() { return agentId; } }
3、编写获取企微签名相关代码
注意:这里签名缓存自行设置,不需要每次就去调用企微api,签名失效时间2小时,可自行设置缓存过期时间,我这里利用的redis@Service public class WeChatService { private static final Logger logger = LoggerFactory.getLogger(WeChatService.class); @Autowired private WeChatConfig weChatConfig; /** * Redis 缓存 access_token 的 key */ private static final String QW_ACCESS_TOKEN_CACHE_KEY = "shxd:dekt:qw:access:token"; public String getAccessToken() { Object redisResult = NHRedisUtils.getRedisResult(QW_ACCESS_TOKEN_CACHE_KEY); if (redisResult == null) { String newToken = refreshAccessToken(); if (newToken == null) { throw new RuntimeException("无法获取企业微信 AccessToken"); } return newToken; } return String.valueOf(redisResult); } private String refreshAccessToken() { try { String url = weChatConfig.getAccessTokenUrl(); RestTemplate restTemplate = new RestTemplate(); String response = restTemplate.getForObject(url, String.class); JSONObject jsonObject = new JSONObject(response); logger.error("获取企业微信 token 成功:{}", jsonObject); String accessToken = jsonObject.getString("access_token"); if (accessToken == null || accessToken.isEmpty()) { logger.error("获取企业微信 AccessToken 失败,返回为空"); return null; } // 加入 Redis,缓存 110 分钟(提前 10 分钟刷新) NHRedisUtils.addRedis(QW_ACCESS_TOKEN_CACHE_KEY, 110, accessToken); return accessToken; } catch (Exception e) { logger.error("获取企业微信 AccessToken 失败", e); return null; } } }
4、发送消息
@Service public class WeChatMessageService { private static final Logger logger = LoggerFactory.getLogger(WeChatMessageService.class); @Autowired private WeChatService weChatService; @Autowired private WeChatConfig weChatConfig; private static final String SEND_MESSAGE_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token="; public boolean sendTextMessage(String userId, String content) { // 获取 AccessToken String accessToken = weChatService.getAccessToken(); String url = SEND_MESSAGE_URL + accessToken; // 构造请求体 JSONObject message = new JSONObject(); message.put("touser", userId); message.put("msgtype", "text"); message.put("agentid", weChatConfig.getAgentId()); JSONObject text = new JSONObject(); text.put("content", content); message.put("text", text); try { RestTemplate restTemplate = new RestTemplate(); // 移除默认的StringHttpMessageConverter(这里防止中文乱码) restTemplate.getMessageConverters().removeIf(converter -> converter instanceof StringHttpMessageConverter); // 添加支持UTF-8的StringHttpMessageConverter StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8); converter.setWriteAcceptCharset(false); // 重要!关闭默认字符集 restTemplate.getMessageConverters().add(0, converter); // 设置请求头,确保 Content-Type 是 UTF-8 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setAcceptCharset(Collections.singletonList(StandardCharsets.UTF_8)); HttpEntity<String> request = new HttpEntity<>(message.toJSONString(), headers); String response = restTemplate.postForObject(url, request, String.class); logger.error("发送企业微信消息返回数据:{}", response); // 解析返回结果 JSONObject jsonResponse = JSONObject.parseObject(response); int errcode = jsonResponse.getIntValue("errcode"); if (errcode == 0) { return true; } else { logger.error("发送企业微信消息失败,错误码:{},错误信息:{}", errcode, jsonResponse.getString("errmsg")); return false; } } catch (Exception e) { logger.error("发送企业微信消息请求失败", e); return false; } } }
-
发送图文消息
只需改变消息体即可,如下
// 构造请求体 JSONObject message = new JSONObject(); message.put("touser", userId); message.put("msgtype", "news"); message.put("agentid", weChatConfig.getAgentId()); // 创建 articles 数组 JSONArray articles = new JSONArray(); JSONObject article = new JSONObject(); article.put("title", "标题"); // 图文标题(必填) article.put("description", "我是描述"); // 图文描述 article.put("url", "https://xf.xdsisu.edu.cn/ydxg"); // 点击后跳转链接 article.put("picurl", "https://img0.baidu.com/it/u=1077282731,2234353719&fm=253&fmt=auto&app=120&f=JPEG?w=800&h=800"); // 图文封面的图片链接(可选) articles.add(article); JSONObject news = new JSONObject(); news.put("articles", articles); message.put("news", news); message.put("safe", 0);
效果如下:
注意:一定要在应用里面配置可信域名,不然会出现{"errcode":60020,"errmsg":"not allow to access from your ip ip不被允许访问的错误信息 -
扩展
如果是本地图片,没有地址的话,可以调用企微的上传图片接口,会返回给你一个url,这个url在企微内部永久有效。上传图片文档地址
代码如下:
public String uploadImage(byte[] bytes, String accessToken) { if (bytes == null || bytes.length == 0) { return null; } try { // 构建请求 String uploadUrl = "https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token="+accessToken; HttpEntity<MultiValueMap<String, Object>> requestEntity = buildRequestEntity(bytes); logger.error("开始上传图片,数据大小:{} bytes", bytes.length); // 发送请求 ResponseEntity<String> response = restTemplate.postForEntity(uploadUrl, requestEntity, String.class); // 响应处理 // 解析JSON响应 String responseBody = response.getBody(); if (StringUtils.isBlank(responseBody)) { logger.error("图片上传返回空响应"); return null; } com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSON.parseObject(responseBody); int errcode = json.getIntValue("errcode"); if (errcode != 0) { String errmsg = json.getString("errmsg"); logger.error("图片上传失败,错误码:{},错误信息:{}", errcode, errmsg); return null; } String url = json.getString("url"); if (StringUtils.isBlank(url)) { logger.error("图片上传成功但未返回url"); return null; } logger.error("图片上传成功,url:{}", url); return url; } catch (RestClientException e) { logger.error("图片上传请求失败,accessToken:{}", accessToken, e); } catch (JSONException e) { logger.error("响应数据解析失败", e); } return null; }
平台声明:以上文章转载于《CSDN》,文章全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,仅作参考。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qijing19991210/article/details/146221603