第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 【Java】企业微信群机器人发送消息(文字 图片 MarkDown 文件消息)

【Java】企业微信群机器人发送消息(文字 图片 MarkDown 文件消息)

时间:2021-09-11 03:48:27

相关推荐

【Java】企业微信群机器人发送消息(文字 图片 MarkDown 文件消息)

Java调用企业微信群机器人发送消息

/4/22更新:新增可发送文件消息。

发送文件消息需要先将文件上传到企业微信的临时素材,url为https://qyapi./cgi-bin/webhook/upload_media?type=file&key=**********,这个key就是群机器人Webhook地址的key参数,在代码里我已经处理好了,只要有Webhook地址就行。获取到media_id,再拿media_id和文件一起就可以调用群机器人的发送接口了。

/12/3 周五

主要参考 企业微信接口文档(但这里用的不是文档里的API) 和 企业微信机器人自动发送群消息 提供的方法,

将企业微信群机器人发送文字、图片、MarkDown、文件消息封装成了一个工具类

用于自建的群,即不是使用企业微信api创建的群,不需要群id;主要使用okhttp3调用机器人api和上传文件到临时素材api;有含代理的构造方法和不含代理的构造方法,可根据需要选择调用;参数使用的是JSONObject,防止在用字符串拼接参数时出现各种特殊字符转义问题;发送图片大小不超过2M(企业微信的规定)。

使用步骤:

1.创建群机器人

在企业微信已经建好的群中,添加群机器人(怎么添加可以参考:企业微信机器人发送消息),获取群机器人的Webhook地址

需注意:

(1)因为不是用企业微信api创建的群,没有群id,无法指定群机器人只发送到某一个群,所以建议该机器人不要发布到公司或者添加到其他群

(2)还需注意群机器人Webhook地址的保密性,因为任何人拿到你的地址,就可以朝你的群里发消息了。

关于Webhook

Webhook是一个 API 概念,简单来说, 就是一个接收 HTTP POST(或GET,PUT,DELETE)的URL。

比如说我可以直接在postman测试工具里,带上需要的参数,向群机器人的Webhook地址发送请求,企业微信对应的群里就能收到这个机器人发送的消息。

2. 将工具类放到项目中,需要添加依赖

将工具类放到项目中,代码在最后。

需要在项目pom.xml文件中添加okhttp3图片操作的依赖:

<dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>3.14.9</version></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.10</version></dependency>

(PS:如果图片过大,可能导致base64编码结果过长超过String的最大长度,导致图片发送失败。另外,企业微信也有规定图片不能超过2M.)

3.调用

(1)直接new一个WeChatBotUtils,带上群机器人Webhook地址和代理服务器相关配置:

WeChatBotUtils robot = new WeChatBotUtils(url, hostname, port);

或者从配置中获取代理信息,就可以用第二个构造方法:

WeChatBotUtils robot = new WeChatBotUtils(url, true);

(如果不需要使用代理,改为false就可以了)

IDEA将代理信息配置在启动参数的方法如下图:

(2)带上对应消息内容参数,调用sendTextMsg(String msg)、sendImgMsg(String path)、sendMarKDownMsg(String msg)、sendFileMsg(String path)方法,即可发送请求:

robot.sendTextMsg(msg);

4.返回参数

除了调用群机器人正常发送消息,还可能会有一些请求报错,比如图片大小无效、md5值不匹配等等,具体原因可以查看 企业微信全局错误码。

5.代码

0积分下载资源:Java企业微信群机器人发送消息,可以直接放到项目里使用。

以下是代码:

package com.ruoyi.project.tool.robot;import com.alibaba.fastjson.JSONObject;import okhttp3.*;import mons.codec.digest.DigestUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import .InetSocketAddress;import .Proxy;import java.util.Base64;import java.util.concurrent.TimeUnit;/*** 微信群机器人*/public class WeChatBotUtils {private Logger log = LoggerFactory.getLogger(this.getClass());// 配置的群机器人Webhook地址private String botUrl;// 配置代理服务器private String hostname;private int port;// 需要使用代理时调用的构造函数public WeChatBotUtils(String botUrl, String hostname, int port) {this.botUrl = botUrl;this.hostname = hostname;this.port = port;}// 直接从配置中获取代理信息public WeChatBotUtils(String botUrl, boolean byProxy) {this.botUrl = botUrl;if (byProxy) {hostname = System.getProperty("proxyHost");port = Integer.valueOf(System.getProperty("proxyPort"));}}/*** 发送文字消息** @param msg 需要发送的消息* @return* @throws Exception*/public String sendTextMsg(String msg) throws Exception {JSONObject text = new JSONObject();text.put("content", msg);JSONObject reqBody = new JSONObject();reqBody.put("msgtype", "text");reqBody.put("text", text);reqBody.put("safe", 0);return callWeChatBot(reqBody.toString());}/*** 发送图片消息,需要对图片进行base64编码并计算图片的md5值** @param path 需要发送的图片路径* @return* @throws Exception*/public String sendImgMsg(String path) throws Exception {String base64 = "";String md5 = "";// 获取Base64编码try {FileInputStream inputStream = new FileInputStream(path);byte[] bs = new byte[inputStream.available()];inputStream.read(bs);base64 = Base64.getEncoder().encodeToString(bs);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}// 获取md5值try {FileInputStream inputStream = new FileInputStream(path);byte[] buf = new byte[inputStream.available()];inputStream.read(buf);md5 = DigestUtils.md5Hex(buf);} catch (IOException e) {e.printStackTrace();}JSONObject image = new JSONObject();image.put("base64", base64);image.put("md5", md5);JSONObject reqBody = new JSONObject();reqBody.put("msgtype", "image");reqBody.put("image", image);reqBody.put("safe", 0);return callWeChatBot(reqBody.toString());}/*** 发送MarKDown消息** @param msg 需要发送的消息* @return* @throws Exception*/public String sendMarKDownMsg(String msg) throws Exception {JSONObject markdown = new JSONObject();markdown.put("content", msg);JSONObject reqBody = new JSONObject();reqBody.put("msgtype", "markdown");reqBody.put("markdown", markdown);reqBody.put("safe", 0);return callWeChatBot(reqBody.toString());}/*** 发送文件消息,需要先将文件上传到企业微信临时素材,再根据获取的media_id调用群机器人** @param path 需要发送的文件路径* @return* @throws Exception*/public String sendFileMsg(String path) throws Exception {File file = new File(path);// 构造RequestBody对象,用来携带要提交的数据;需要指定MediaType,用于描述请求/响应 body 的内容类型MediaType contentType = MediaType.parse("application/form-data; boundary");RequestBody body = RequestBody.create(contentType, file);RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("file", file.getName(), body).build();// 上传到临时素材String key = botUrl.substring(botUrl.indexOf("key="));System.out.println(key);String mediaUrl = "https://qyapi./cgi-bin/webhook/upload_media?type=file&"+key;log.info("将文件" + path+ "上传到临时素材:" + mediaUrl);String respMsg = okHttp(requestBody, mediaUrl);// 获取临时素材idJSONObject result = JSONObject.parseObject(respMsg);String media_id = result.getString("media_id");JSONObject fileJson = new JSONObject();fileJson.put("media_id", media_id);JSONObject reqBody = new JSONObject();reqBody.put("msgtype", "file");reqBody.put("file", fileJson);reqBody.put("safe", 0);// 调用群机器人发送消息return callWeChatBot(reqBody.toString());}/*** 调用群机器人** @param reqBody 接口请求参数* @throws Exception 可能有IO异常*/public String callWeChatBot(String reqBody) throws Exception {log.info("请求参数:" + reqBody);// 构造RequestBody对象,用来携带要提交的数据;需要指定MediaType,用于描述请求/响应 body 的内容类型MediaType contentType = MediaType.parse("application/json; charset=utf-8");RequestBody body = RequestBody.create(contentType, reqBody);// 调用群机器人String respMsg = okHttp(body, botUrl);if ("0".equals(respMsg.substring(11, 12))) {log.info("向群发送消息成功!");} else {log.info("请求失败!");// 发送错误信息到群sendTextMsg("群机器人推送消息失败,错误信息:\n" + respMsg);}return respMsg;}/**** @param body 携带需要提交的数据* @param url 请求地址* @return* @throws Exception*/public String okHttp(RequestBody body, String url) throws Exception {// 构造和配置OkHttpClientOkHttpClient client;if(hostname != null && port != 0){client = new OkHttpClient.Builder().proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(hostname, port))) // 内网使用代理,不需要可注释.connectTimeout(10, TimeUnit.SECONDS) // 设置连接超时时间.readTimeout(20, TimeUnit.SECONDS) // 设置读取超时时间.build();} else{client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS) // 设置连接超时时间.readTimeout(20, TimeUnit.SECONDS) // 设置读取超时时间.build();}// 构造Request对象Request request = new Request.Builder().url(url).post(body).addHeader("cache-control", "no-cache") // 响应消息不缓存.build();// 构建Call对象,通过Call对象的execute()方法提交异步请求Response response = null;try {response = client.newCall(request).execute();} catch (IOException e) {e.printStackTrace();}// 请求结果处理byte[] datas = response.body().bytes();String respMsg = new String(datas);log.info("返回结果:" + respMsg);return respMsg;}}

6.调用

public static void main(String[] args) throws Exception {String botUrl = "https://qyapi./cgi-bin/webhook/send?key=**********";WeChatBotUtils weChatBot = new WeChatBotUtils(botUrl, true);// 发送文本消息weChatBot.sendTextMsg("测试消息\n" + "hello world!");// 发送图片消息weChatBot.sendImgMsg("C:/User/Desktop/test.jpg");// 发送MarkDown消息String markdownMsg ="测试:您的会议室已经预定,稍后会同步到`邮箱` \n" +" >**事项详情** \n" +" >事项:<font color=\"info\">开会</font> \n" +" >组织者:@admin \n" +" >参与者:@admin \n" +" >\n" +" >会议室:<font color=\"info\">广州TIT 1楼 301</font>\n" +" >日期:<font color=\"warning\">4月22日</font>\n" +" >时间:<font color=\"comment\">上午9:00-11:00</font>\n" +" >\n" +" >请准时参加会议。\n";weChatBot.sendMarKDownMsg(markdownMsg);// 发送文件消息weChatBot.sendFileMsg("C:/User/Desktop/test.xlsx");}

就介么简单~ ^_^

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。