专栏首页Mintimate's BlogJava项目实现消息推送到团队微信,让项目“会说话”
原创

Java项目实现消息推送到团队微信,让项目“会说话”

作者:Mintimate

博客:https://www.mintimate.cn

Mintimate's Blog,只为与你分享

封面嗷

前言

消息推送到团队微信,很多人看了标题,可能不能理解什么意思,其实:

  • 消息:工程项目内的提示消息,比如:项目关联的OCR识别次数接口告罄通知、项目均衡过载通知等消息。
  • 团队微信:企业微信或关联企业微信的个人微信,用于接受消息。

通过上述描述,大家是不是就更能理解了呢?所以,我们项目“说话”,就是让我们Java项目日常使用过程中,一些时间触发时,使用API推送消息至开发者/团队的微信,方便团队维护。类似邮件提醒⏰。

本文推送是直接内置到Java项目内,如:Springboot项目后端。如果需单独搭建推送服务,给其他工程使用,可以使用PHP进行搭建

推送服务

具体来说,推送服务的思路是这样的:

推送服务逻辑

实际的项目中,也可以使用:

场景1:API服务告罄警告

有时候,我们搭建一些项目,会直接使用外部API除了图片。比如:使用腾讯云万象数据,识别图片分类

识别图片分类

这样的接口,肯定是有使用次数限制,在次数快使用完毕,就可以创建一个方法,直接调用实现写好的工具包方法,对微信发送消息:

API使用告罄提醒

场景2:数据库"灾变"

Java作为一门后端语言,数据库的重要性不用多说。如果数据库服务器崩溃了,肯定是要第一时间处理。我们可以写一个监听,来观察数据库的“存活”:

数据库“灾变”提醒

前期准备

前期准备很简单,主要是

Java依赖包

1. Fastjson包

在Maven内,加入Fastjson的包:

添加Fastjson包
<!--Fastjson Alibaba-->
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.75</version>
</dependency>

如果你项目并没有使用Maven进行项目包管理,需要手动下载Fastjson,并添加至项目依赖内:

使用Fastjson,主要是用于处理JSON对象。比如:JSON对象封装、JSON和String互转以及JSON对象解析等。

2. springframework

直接应用springframework的包,主要是想偷懒…… 如果你有更简单的方法实现包含header的HTTP请求,也可以不用springframework的包:

<dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-web</artifactId>
       <version>5.3.3</version>
 </dependency>

微信推送接口申请

微信接口申请,实际上是申请企业微信的接口。但是个人也可以申请。(且后期可以选择推过微信接收推送,实际上不需要多下载安装一个企业微信在手机上。)

1. 应用创建

进入企业微信官网,注册一个企业微信。创建好后。我们选择应用管理,并创建一个应用:

创建应用

2. 获取AgentId和Secret

创建好后,我们获取应用AgentId和Secret:

获取AgentId和Secret

3. 获取企业ID

进入我的企业页面,拉到最下边,可以看到企业ID:

企业ID

4. 绑定个人微信

如果你并不想保留企业微信在手机上,想直接推送消息到自己的个人微信,可以进入「我的企业」 → 「微信插件」,拉到下边扫描二维码,关注以后即可收到推送的消息:

绑定个人微信

通讯原理

综上,你应该在项目内添加了Fastjson,并申请微信接口,得到参数:

  • WECOM_CID:上文步骤中获取的企业ID
  • WECOM_SECRET:上文步骤中获取的应用Secret
  • AGENT_ID:上文步骤中获取的应用AgentId

之所以需要上述消息,主要是用于token的生成,可以看微信开发者文档:

开发文档

而有了token,才可以对微信进行推送。进一步,系统工作时候的原理:

系统工作原理

代码实现

1. 静态属性

我们创建了一个工具类,因为实际使用,肯定是作为一个静态方法使用,不用实例对象。所以,我们创建静态方法:

    // 微信接口获取
    final static String GET_ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
    // 个人企业微信接口参数
    final static String SEND_MESSAGE_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=";
    // 企业微信公司ID
    final static String WECOM_CID = "";
    // 企业微信公司密钥
    final static String WECOM_SECRET = "";
    // 应用ID
    final static String AGENT_ID = "";
    // 发送用户,@all代表企业微信里所有人
    final static String TOUSER = "@all";  
    
    
    // 发送失败
    final static int ERROR_CODE=0;
    // 发送成功
    final static int SUCCESS_CODE=0;
    // 发送状态
    static int STATUS_CODE=ERROR_CODE;

当然,我这边的状态写的可能比较少,所以只写了2个状态。大家后续可以自行更改。另外大家记得填入自己企业微信的WECOM_CIDWECOM_SECRETAGENT_ID

2. Token申请

静态方法内,我已经提前定义Token申请的地址,我们只需要封装参数为JSON,对其请求即可:

// 微信接口获取
    final static String GET_ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";

我们使用RestTemplate发起HTTP请求,先定义一个通用包,用于后续复用:

// HTTP请求发送
private static String HttpRestClient(String url, HttpMethod method, JSONObject json) throws IOException {
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(10 * 1000);
        requestFactory.setReadTimeout(10 * 1000);
        RestTemplate client = new RestTemplate(requestFactory);
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json;charset=UTF-8");
        headers.setContentType(type);
        HttpEntity<String> requestEntity = new HttpEntity(json.toString(), headers);
        //  执行HTTP请求
        ResponseEntity<String> response = client.exchange(url, method, requestEntity, String.class);
        return response.getBody();
    }

之后,写一个方法对其调用:

private static int sendMessage(String sendText, String access_token) {
    String url = SEND_MESSAGE_URL + access_token;
    HttpMethod method = HttpMethod.POST;
    JSONObject json = new JSONObject();
    JSONObject jsonText = new JSONObject();
    jsonText.put("content", sendText);
    json.put("touser", TOUSER);
    json.put("agentid", AGENT_ID);
    json.put("msgtype", "text");
    json.put("text", jsonText);
    //发送http请求并返回结果
    try {
        String result = sendMessageToWechat.HttpRestClient(url, method, json);
        JSONObject obj = JSON.parseObject(result);
        //将Json字符串转化为Json对象
        if ((int) obj.get("errcode") == 200) {
            //从Json对象中提取键值为“status”的键值对,并将键值保存在“status”字符串中
            STATUS_CODE = SUCCESS_CODE;
        }
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    return STATUS_CODE;
}

测试一下:

获取Token成功

3. 携带Token发送消息

首先,创建一个私有方法,对TokenSEND_MESSAGE_URL(https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=)组合的链接🔗,发送content对象。而这个content需要和其他参数组合为JSON对象,其结构:

JSON对象结构

用Fastjson来组合JSON对象很简单:

JSONObject json = new JSONObject();
JSONObject jsonText = new JSONObject();
jsonText.put("content", sendText);
json.put("touser", TOUSER);
json.put("agentid", AGENT_ID);
json.put("msgtype", "text");
json.put("text", jsonText);

用上问提到的方法,再次发送POST请求即可:

private static int sendMessage(String sendText, String access_token) {
	String url = SEND_MESSAGE_URL + access_token;
	HttpMethod method = HttpMethod.POST;
	JSONObject json = new JSONObject();
	JSONObject jsonText = new JSONObject();
	jsonText.put("content", sendText);
	json.put("touser", TOUSER);
	json.put("agentid", AGENT_ID);
	json.put("msgtype", "text");
	json.put("text", jsonText);
	//发送http请求并返回结果
	try {
		String result = sendMessageToWechat.HttpRestClient(url, method, json);
		JSONObject obj = JSON.parseObject(result);
		//将Json字符串转化为Json对象
		if ((int) obj.get("errcode") == 200) {
			//从Json对象中提取键值为“status”的键值对,并将键值保存在“status”字符串中
			STATUS_CODE = SUCCESS_CODE;
		}
	}
	catch (IOException e) {
		e.printStackTrace();
	}
	return STATUS_CODE;
}

理论上,这个方法执行成功,消息就可以直接发送了。但是,这个未来作为系统的工具包,不用去实例,我们再写一个方法封装一下:

public static int sendText(String Text) {
    if (Text == null) {
        return ERROR_CODE;
    }
    String access_token = getAccessToken();
    if (access_token == null || access_token.equals("")) {
        return ERROR_CODE;
    } else {
        sendMessage(Text, access_token);
    }
    return STATUS_CODE;
}

这样,Controller层,就可以直接调用该方法了。

测试使用

最后,我们测试使用一下。为了方便,我就不用Test类去测试,直接使用Main方法去测试:

public static void main(String args[]) {
	sendMessageToWechat.sendText("Mintimate's Blogn" +
                "只为与你分享~😄😄\n" +
                "=> Bilibili:https://space.bilibili.com/355567627\n"+
	"=> 腾讯云社区:https://cloud.tencent.com/developer/user/7704194\n"+
                "=====\n"+
                "<a href='https://www.mintimate.cn'>查看更多</a>");
}
测试代码

运行,即可以看到微信收到通知了:

微信上收到消息

样例代码

有些小伙伴可能想要文中的样例代码,为此我也在Github上进行了开源:

完善思路

这样的推送服务是可以完善的。比如:

Redis存储Token

如果你有看企业微信开发者文档,你会发现Token的有效期是:1800秒。你可以使用Redis进行临时存储缓存。

发送图片

本文演示发送消息,但是接口是可以发送图片、语言等内容。且接受数据均为JSON,可以按本文方法实现:

图片消息
卡片消息

PHP接口

使用Java,直接集成在JavaWeb项目里,固然不错,但是如果想作为一个API接口,那么使用PHP是更好的选择,还可以使用Serverless

总结

综上所述,就是让Java项目“说话”的方案了嗷。当然,肯定有更好的方法,但是推送到微信,也觉得是个好方法嗷~

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

关注作者,阅读全部精彩内容

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅

    本文由微信开发团队工程是由“oneliang”原创发表于WeMobileDev公众号,内容稍有改动。

    JackJiang
  • 一份Java程序员进阶架构师的秘籍,你离架构师还差多远

    Java架构师,首先要是一个Java程序员,熟练使用各种框架,并知道它们实现的原理。jvm虚拟机原理、调优,懂得jvm能让你写出性能更好的代码;池技术,什么对象...

    慕容千语
  • 基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)

    本文原作者:liuyan731,原文地址:liuyan731.github.io/2017/12/05/How-To-Use-APNs-Pushy,内容有改动。

    JackJiang
  • 为什么很多公司都转型go语言开发?Go语言能做什么

    选择Go语言的原因可能会有很多,关于Go语言的特性、优势等,我们在之前的文档中也已经介绍了很多了。但是最主要的原因,应该是基于以下两方面的考虑:

    李海彬
  • GitOps与ChatOps的落地实践

    说到 GitOps 和 ChatOps ,那就不得不谈到 DevOps 。DevOps 作为一种文化,旨在促进开发、测试和运维人员之间的沟通与协作。而促进合作的...

    CNCF
  • 老兵的十年职场之路(三)

    在前面的文章里,如果说第二段经历是我的小高峰,那么接下来我觉得算是一段平峰期吧。至少在技术成长上面是如此,而财富积累更是进入了黯淡期。有个词说的好,遇强则强,当...

    美码师
  • 甲骨文要放弃不赚钱的Java?开发者不安,心痛

    你可能听说过类似的消息了,甲骨文公司不声不响地撤掉了一项社区技术的资金和开发人员支持,而许多消费者和企业合作伙伴已经在这项技术上投入了大把的时间并编写了大量的代...

    用户1667431
  • 以Java后端高级开发为例,讲述面试前的准备点

    由于我做了比较长时间的技术面试官,根据我的面试体会,不少同学收到面试后,什么准备也不会做,到时候就来了。

    Java团长
  • 当你收到面试通知后,如下的准备可以大大提升面试成功率

    由于我做了比较长时间的技术面试官,根据我的面试体会,不少同学收到面试后,什么准备也不会做,到时候问题就来了。

    lyb-geek
  • 基于 Docker 的微服务架构实践

    基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 DevOps,也见证了 Docker 的技术体系的快速发...

    烂猪皮
  • 超全!我整理一波最常用的开源项目

    发这篇文章的起因是看到知乎有个类似的问题,然后感觉高赞的回答不是很让人满意,获得这么高的点赞也是让我很迷。

    cxuan
  • “协力抗疫,码力全开”线上公益黑客马拉松参赛作品展示

    项目简介:此次疫情爆发,身为开发的我想要为社会做点什么,发挥自己的一点点《小热量》!刚好腾讯云开发推出此次活动,于是开发了《小热量》这个小程序。小程序首页为国内...

    腾讯云开发TCB
  • 【干货下载】谷歌、亚马逊等十大公司精选微服务案例

    Rainbond开源
  • 开源半个月收获接近 1k Star!你需要的开源项目都在这里!

    半个月前,我开源了awesome-java ,这是一个 Github 上非常棒的 Java 开源项目集合。是的!就是下面这个这么骚的图标!

    Guide哥
  • 导致你的微服务走向失败的11个原因

    在过去的几年里,我对多个正在进行数字化转型的产品团队进行了架构审查。发现大多数团队都会使用微服务架构来构建产品,他们使用微服务架构的意图都是正确的:更快的开发速...

    架构师修行之路
  • 年度 | TARS开源里程碑回顾

    最近在开源中国举办的开源年终盛典上,开源项目TARS 获得了年度最佳原创开源软件奖。 ? 谈到微服务,人们往往会提起Spring Cloud和Service ...

    腾讯开源
  • Java架构师面试题全分享,你离架构师还有多远?

    经常面试一些候选人,整理了下我面试使用的题目,陆陆续续整理出来的题目很多,所以每次会抽一部分来问。答案会在后面的文章中逐渐发布出来。

    java架构师
  • JAVA架构师面试题,如何成为架构师

    经常面试一些候选人,整理了下我面试使用的题目,陆陆续续整理出来的题目很多,所以每次会抽一部分来问。答案会在后面的文章中逐渐发布出来。 基础题目 Java线程的...

    Java高级架构
  • Kafka系列文章第1篇之Kafka是什么

    如果有幸目睹过系统从零到一的演变过程,大家估计都会有一种感叹,就是随着业务复杂度和流量的不断上升,系统变得越来越难以维护,面对高额的维护成本,攻城师们不得不对现...

    z小赵

扫码关注云+社区

领取腾讯云代金券