简而言之只需两步
1.获取access_token
2.拿到access_token,调用api接口发送通知消息
一、如何拿到access_token?
根据官网文档得知需要一个请求和两个参数(corpid、corpsecret)
corpid:登录企业微信后台进行查看(没有的先创建企业微信)
corpsecret:其实就是应用的secret,这时候需要创建一个应用(到时候消息的推送就是由该应用来为我们推送)。AgentId需要记录一下,后面发送通知需要用到
二、发送通知(文本消息为例)
拿到access_token,调用api接口:
https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=ACCESS_TOKEN,将消息内容、消息接收者id、企业应用的id(AgentId)按需放入请求体相应位置,请求调用即可推送
综上所述,一个简单的文本消息推送便完成了,然而这样就结束了吗?根据官方文档提供的消息类型有很多,文本、卡片、文件、语音等等。接下来对此进行一个封装完善。
Access_token封装
public class AccessToken {
private String access_token;
//有效时间(2h,7200s)
private int expires_in;
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int valid_time) {
this.expires_in = valid_time;
}
}
消息封装(文本、文本卡片)
一个基类BaseMessage、两个子类TextMessage、TextcardMessage
public class BaseMessage {
// 否 成员ID列表(消息接收者,多个接收者用‘|’分隔,最多支持1000个)。特殊情况:指定为@all,则向该企业应用的全部成员发送
private String touser;
// 否 部门ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
private String toparty;
// 否 标签ID列表,多个接收者用‘|’分隔,最多支持100个。当touser为@all时忽略本参数
private String totag;
// 是 消息类型
private String msgtype;
// 是 企业应用的id,整型。可在应用的设置页面查看
private int agentid;
public String getTouser() {
return touser;
}
public void setTouser(String touser) {
this.touser = touser;
}
public String getToparty() {
return toparty;
}
public void setToparty(String toparty) {
this.toparty = toparty;
}
public String getTotag() {
return totag;
}
public void setTotag(String totag) {
this.totag = totag;
}
public String getMsgtype() {
return msgtype;
}
public void setMsgtype(String msgtype) {
this.msgtype = msgtype;
}
public int getAgentid() {
return agentid;
}
public void setAgentid(int agentid) {
this.agentid = agentid;
}
}
public class TextMessage extends BaseMessage{
private Text text;
//否 表示是否是保密消息,0表示否,1表示是,默认0
private int safe;
public Text getText() {
return text;
}
public void setText(Text text) {
this.text = text;
}
public int getSafe() {
return safe;
}
public void setSafe(int safe) {
this.safe = safe;
}
}
public class TextcardMessage extends BaseMessage{
//文本
private Textcard textcard;
//btntxt 否 按钮文字。 默认为“详情”, 不超过4个文字,超过自动截断。
public Textcard getTextcard() {
return textcard;
}
public void setTextcard(Textcard textcard) {
this.textcard = textcard;
}
}
public class Text {
//是 消息内容,最长不超过2048个字节
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
public class Textcard {
//是 标题,不超过128个字节,超过会自动截断
private String title;
//是 描述,不超过512个字节,超过会自动截断
private String description;
//是 点击后跳转的链接。
private String url;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
请求Url以及其他静态常量
public class WechatConstant {
public static final String ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
public static final String MESSAGE_SEND_URL = "https://qyapi.weixin.qq.com/cgi-bin/message/send";
public static final String USER_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserid";
public static final int AGENTID = 应用ID;
public static final String CORPID = "企业ID";
public static final String CORPSECRET = "Secret";
}
工具类 IHttp、WechatUtils
public class IHttp {
private static final Logger log = LoggerFactory.getLogger(IHttp.class);
public static final int METHOD_POST = 0;
public static final int METHOD_GET = 1;
private String url;
private String restful;
private Map<String, String> query;
private String body;
private Map<String, String> header;
private Map<String, String> cookie;
private String charSet = "UTF-8";
private int method = 0;
private Integer connectTimeout = 3000;
private Integer socketTimeout = 3000;
private static CloseableHttpClient client = null;
private IHttp() {
}
public static IHttp create() {
return new IHttp();
}
public static IHttp create(String url) {
return create().setUrl(url);
}
public String getUrl() {
return this.url;
}
public IHttp setUrl(String url) {
this.url = url;
return this;
}
public String getRestful() {
return this.restful;
}
public IHttp setRestful(String restful) {
this.restful = restful;
return this;
}
public Map<String, String> getQuery() {
return this.query;
}
public IHttp setQuery(Map<String, String> query) {
this.query = query;
return this;
}
public String getBody() {
return this.body;
}
public IHttp setBody(String body) {
this.body = body;
return this;
}
public Map<String, String> getHeader() {
return this.header;
}
public IHttp setHeader(Map<String, String> header) {
this.header = header;
return this;
}
public Map<String, String> getCookie() {
return this.cookie;
}
public IHttp setCookie(Map<String, String> cookie) {
this.cookie = cookie;
return this;
}
public String getCharSet() {
return this.charSet;
}
public IHttp setCharSet(String charSet) {
this.charSet = charSet;
return this;
}
public Integer getConnectTimeout() {
return this.connectTimeout;
}
public IHttp setConnectTimeout(Integer connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
public Integer getSocketTimeout() {
return this.socketTimeout;
}
public IHttp setSocketTimeout(Integer socketTimeout) {
this.socketTimeout = socketTimeout;
return this;
}
public void setMethod(int method) {
this.method = method;
}
public String post() {
this.setMethod(0);
return this.send();
}
public String get() {
this.setMethod(1);
return this.send();
}
public String send() {
if (IStr.isBlank(this.url)) {
log.warn("不存在的url,无法进行访问.");
IException.throwException("不存在的url,无法进行访问.");
}
StringBuffer surl = new StringBuffer(this.url);
if (IStr.isNotBlank(this.restful)) {
if (!"/".equals(surl.substring(surl.length() - 1))) {
surl.append("/");
}
surl.append(this.restful);
}
if (this.query != null) {
if (!"?".equals(surl.substring(surl.length() - 1))) {
surl.append("?");
}
surl.append(this.getQueryString());
}
HttpRequestBase request = null;
if (this.method == 0) {
request = new HttpPost(surl.toString());
if (IStr.isNotBlank(this.body)) {
((HttpPost)request).setEntity(new StringEntity(this.body, this.getCharSet()));
}
} else if (this.method == 1) {
request = new HttpGet(surl.toString());
} else {
IException.throwException("没有指定");
}
Header[] headers = (Header[])IArray.addAll(((HttpRequestBase)request).getAllHeaders(), this.getHeaderArray());
if (headers != null) {
((HttpRequestBase)request).setHeaders(headers);
}
RequestConfig config = RequestConfig.custom().setConnectTimeout(this.getConnectTimeout()).setSocketTimeout(this.getSocketTimeout()).build();
((HttpRequestBase)request).setConfig(config);
CloseableHttpResponse response = null;
HttpEntity entity = null;
try {
response = getClient().execute((HttpUriRequest)request);
entity = response.getEntity();
String var7 = EntityUtils.toString(entity, this.getCharSet());
return var7;
} catch (Exception var17) {
log.error("HTTP请求失败:[URL=" + this.url + "]", var17);
IException.throwException("HTTP请求失败:[URL=" + this.url + "]", var17);
} finally {
try {
EntityUtils.consume(entity);
} catch (Exception var16) {
log.warn("关闭连接失败:", var16);
}
close(response);
}
return null;
}
public String getQueryString() {
if (this.query == null) {
return "";
} else {
List<NameValuePair> nameValuePairs = new ArrayList();
Iterator var2 = this.query.entrySet().iterator();
while(var2.hasNext()) {
Entry<String, String> entry = (Entry)var2.next();
nameValuePairs.add(new BasicNameValuePair((String)entry.getKey(), (String)entry.getValue()));
}
return URLEncodedUtils.format(nameValuePairs, this.getCharSet());
}
}
public Header[] getHeaderArray() {
if (this.header == null) {
return null;
} else {
List<Header> headers = new ArrayList();
Iterator var2 = this.header.entrySet().iterator();
while(var2.hasNext()) {
Entry<String, String> entry = (Entry)var2.next();
headers.add(new BasicHeader((String)entry.getKey(), (String)entry.getValue()));
}
if (this.cookie != null) {
BasicCookieStore cookieStore = new BasicCookieStore();
Iterator var6 = this.cookie.entrySet().iterator();
while(var6.hasNext()) {
Entry<String, String> entry = (Entry)var6.next();
cookieStore.addCookie(new BasicClientCookie((String)entry.getKey(), (String)entry.getValue()));
}
headers.add(new BasicHeader("Cookie", cookieStore.toString()));
}
return (Header[])headers.toArray(new BasicHeader[0]);
}
}
private static CloseableHttpClient getClient() {
if (client == null) {
client = HttpClients.createDefault();
}
return client;
}
private static void close(CloseableHttpResponse response) {
try {
if (response != null) {
response.close();
}
} catch (Exception var2) {
var2.printStackTrace();
}
}
public static void main(String[] args) {
String response = create("http://101.64.232.240:10800/api/v1/record/querydaily").post();
System.out.println(response);
}
}
public class WechatUtil{
public static Map<String,Object> tokenMap = new HashMap<>();
/**
* 请求头
*/
public static final String APPLICATION_WWW = "application/x-www-form-urlencoded";
public static final String APPLICATION_JSON = "application/json";
private static AccessToken getTokenRes() {
StringBuffer token_url = new StringBuffer(WechatConstant.ACCESS_TOKEN_URL);
token_url.append("?corpid=" + WechatConstant.CORPID);
token_url.append("&corpsecret=" + WechatConstant.CORPSECRET);
Map<String,String> header = new HashMap<>();
header.put("Content-Type", APPLICATION_WWW);
String res = IHttp.create(token_url.toString()).setBody("").setHeader(header).post();
return JSONObject.parseObject(res, AccessToken.class);
}
//刷新token
public static String setAccessToken() {
AccessToken accessToken = getTokenRes();
if (accessToken != null && accessToken.getAccess_token() != null) {
tokenMap.put("access_token",accessToken.getAccess_token());
tokenMap.put("expires_in", accessToken.getExpires_in());
}
return accessToken.getAccess_token();
}
//消息请求体-纯文本
public static String createTextData(String touser,String content) {
Gson gson = new Gson();
TextMessage tm = new TextMessage();
Text t = new Text();
t.setContent(content);
tm.setMsgtype("text");
tm.setAgentid(WechatConstant.AGENTID);
tm.setText(t);
tm.setTouser(touser);
return gson.toJson(tm);
}
//消息请求体-文字卡片
public static String createTextcardData(String touser){
Gson gson = new Gson();
TextcardMessage tcm = new TextcardMessage();
Textcard tc = new Textcard();
tc.setTitle("号外号外");
tc.setDescription("台风要来了,赶紧跑路吧");
tc.setUrl("https://www.baidu.com");
tcm.setAgentid(WechatConstant.AGENTID);
tcm.setMsgtype("textcard");
tcm.setTouser(touser);
tcm.setTextcard(tc);
return gson.toJson(tcm);
}
//根据手机号获取用户
public static String getUserByMobile(String accessToken,String mobile){
StringBuffer url = new StringBuffer(WechatConstant.USER_URL);
url.append("?access_token=" + accessToken);
Map<String,String> header = new HashMap<>();
Map<String,String> body = new HashMap<>();
header.put("Content-Type", APPLICATION_JSON);
body.put("mobile", mobile);
String info = IHttp.create(url.toString()).setBody(JSONObject.toJSONString(body)).setHeader(header).post();
if(IStr.isNotBlank(info)){
JSONObject jsonObj = JSON.parseObject(info);
if(!jsonObj.isEmpty() && jsonObj.getInteger("errcode") == 0){
return jsonObj.getString("userid");
}
}
return "";
}
//发送消息
public static void sendMessage(String accessToken,String body){
StringBuffer token_url = new StringBuffer(WechatConstant.MESSAGE_SEND_URL);
token_url.append("?access_token=" + accessToken);
Map<String,String> header = new HashMap<>();
header.put("Content-Type", APPLICATION_JSON);
String info = IHttp.create(token_url.toString()).setBody(body).setHeader(header).post();
System.out.println(info);
}
}
测试调用
public static void main(String[] args) throws Exception {
String accessToken = IType.getStr(WechatUtil.tokenMap.get("access_token"));
if(IStr.isBlank(accessToken)){
//没有access_token主动调一次刷新
accessToken = WechatUtil.setAccessToken();
}
String body = WechatUtil.createTextData(userid,"发送通知!");
WechatUtil.sendMessage(accessToken, body);
}
效果图: