赞
踩
最近需要定时提示同事分享文章等,因此做了一个企业微信机器人定时发送消息。
1.根据文档里的JSON格式,我们先定义要用到的消息实体对象和枚举类。
(1) Message
/** * @description: 企业微信机器人消息实体类 * @author: DreamflyChen * @create: 2020-08-30 13:03 */ @Data public class Message { /** * 消息类型 */ private MessageTypeEnum msgtype; /** * 文本消息 */ private JSONObject text; /** * 图片消息 */ private JSONObject image; /** * 表示是否是保密消息,0表示否,1表示是,默认0 */ private Integer safe; }
(2) ImageMessage
/** * @description: 图片类型消息 * @author: DreamflyChen * @create: 2020-08-30 13:16 */ @Data public class ImageMessage { /** * 图片内容的base64编码 * 注:图片(base64编码前)最大不能超过2M,支持JPG,PNG格式 */ private String base64; /** * 图片内容(base64编码前)的md5值 */ private String md5; }
(3) TextMessage
/** * @description: 文本消息实体类 * @author: DreamflyChen * @create: 2020-08-30 13:11 */ @Data public class TextMessage { /** * 文本内容,最长不超过2048个字节,必须是utf8编码(必填) */ private String content; /** * userid的列表,提醒群中的指定成员(@某个成员),@all表示提醒所有人,如果开发者获取不到userid,可以使用mentioned_mobile_list * (非必填) */ private List<String> mentioned_list; /** * 手机号列表,提醒手机号对应的群成员(@某个成员),@all表示提醒所有人 */ private List<String> mentioned_mobile_list; }
(4)MessageTypeEnum 消息类型枚举
/** * 消息类型枚举 * * @author DreamflyChen * @create 2020-8-30 14:25:06 */ @Getter @Slf4j public enum MessageTypeEnum { unknown_type(-1, "未知类型"), text(1, "文本类型"), image(2, "图片类型"); private final int value; private final String desc; MessageTypeEnum(int value, String desc) { this.value = value; this.desc = desc; } /** * 根据值返回枚举 * * @param value * @return */ public static MessageTypeEnum getEnumByValue(int value) { for (MessageTypeEnum v : MessageTypeEnum.values()) { if (v.getValue() == value) { return v; } } return unknown_type; } /** * 根据编码获取描述信息 * * @param value * @return */ public static String getDescByValue(String value) { if (StringUtils.isBlank(value)) { return null; } try { int discount = Integer.parseInt(value.trim()); for (MessageTypeEnum v : MessageTypeEnum.values()) { if (v.getValue() == discount) { return v.getDesc(); } } return "未知类型: " + value; } catch (Exception e) { log.info("字符串格式转数字异常,str: {}", value); return null; } } }
2.封装处理器,主要是发送消息的方法,图片转Base64字符串(注意要去掉换行符,这一点官网文档没有说明),文件md5加密。
(1) ImageManager
/** * @description: 图片处理 * @author: DreamflyChen * @create: 2020-08-29 23:05 */ @Slf4j public class ImageManager { /** * @Description 图片转base64字符串 * @param imgUrl 图片路径(Resources目录下, 如/img/pic1.png) * @return */ public static String imageToBase64Str(String imgUrl) { InputStream inputStream; byte[] data; try { inputStream = ImageManager.class.getResourceAsStream(imgUrl); data = new byte[inputStream.available()]; inputStream.read(data); inputStream.close(); } catch (IOException e) { log.error("图片转base64字符串异常, 异常信息如下:{}", e.getMessage()); return null; } // 加密 BASE64Encoder encoder = new BASE64Encoder(); //去掉换行符 String result = encoder.encode(data).replaceAll("\r|\n", ""); return result; } /** * @Description 生成文件的md5值 * @param fileUrl 文件路径(Resources目录下, 如/img/pic1.png) * @return MD5值 */ public static String getStringMd5(String fileUrl) throws Exception { String value; //toURI() 解决中文路径乱码问题 String path = ImageManager.class.getResource(fileUrl).toURI().getPath(); try (FileInputStream in = new FileInputStream(path)) { MappedByteBuffer byteBuffer = in.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, new File(path).length()); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(byteBuffer); BigInteger bi = new BigInteger(1, md5.digest()); value = bi.toString(16); } return value; } }
(2) MessageManager
/** * @description: 消息处理器 * @author: DreamflyChen * @create: 2020-08-30 13:33 */ @Slf4j public class MessageManager { public static boolean sendMessage(Message message, String webHookAddress) { OkHttpClient client = new OkHttpClient.Builder() // 设置连接超时时间 .connectTimeout(10, TimeUnit.SECONDS) // 设置读取超时时间 .readTimeout(20, TimeUnit.SECONDS) .build(); MediaType contentType = MediaType.parse("application/json; charset=utf-8"); RequestBody body = RequestBody.create(JSONObject.toJSONString(message), contentType); Request request = new Request.Builder().url(webHookAddress).post(body).addHeader("cache-control", "no-cache").build(); try { Response response = client.newCall(request).execute(); byte[] datas = response.body().bytes(); String respMsg = new String(datas); JSONObject resultJSON = JSONObject.parseObject(respMsg); if (resultJSON.getIntValue("errcode") == 0) { log.info("消息发送成功!"); return true; } log.error("消息发送失败, 错误信息如下: {}", resultJSON.getString("errmsg")); return false; } catch (IOException e) { log.error("消息发送失败, 异常信息如下: {}", e.getMessage()); return false; } } }
3.定时任务例子,使用@Scheduled
注解与Cron表达式, 跑main
方法可以立刻看到效果哦!
在线Cron表达式生成地址:https://qqe2.com/cron
/** * @description: 日报提醒和分享任务 * @author: DreamflyChen * @create: 2020-08-29 21:51 */ @Component public class DailyTipAndShareTask { @Scheduled(cron = "0 0 10 ? * 1") public void ShareTip() throws Exception { String webHookAddress = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=..."; //发送文本消息 Message message = new Message(); message.setMsgtype(MessageTypeEnum.text); TextMessage textMessage = new TextMessage(); textMessage.setContent("这里写文本消息内容。"); textMessage.setMentioned_list(Arrays.asList("user id list")); JSONObject text = JSONObject.parseObject(JSONObject.toJSONString(textMessage)); message.setText(text); MessageManager.sendMessage(message, webHookAddress); //发送图片消息 message.setText(null); message.setMsgtype(MessageTypeEnum.image); ImageMessage imageMessage = new ImageMessage(); imageMessage.setBase64(ImageManager.imageToBase64Str("/img/朱茵.jpg")); imageMessage.setMd5(ImageManager.getStringMd5("/img/朱茵.jpg")); JSONObject image = JSONObject.parseObject(JSONObject.toJSONString(imageMessage)); message.setImage(image); MessageManager.sendMessage(message, webHookAddress); } public static void main(String[] args) throws Exception { new DailyTipAndShareTask().ShareTip(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。