当前位置:网站首页>使用微信公众号给指定微信用户发送信息
使用微信公众号给指定微信用户发送信息
2022-08-01 19:44:00 【苏七qaq】
1.编写接口验证微信方是否接入成功
/*参数 描述
signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串*/
@ApiOperation("验证微信方是否接入成功")
@GetMapping("/weChat") //get方法是为了验证微信方是否接入成功
public String validate(String signature,String timestamp,String nonce,String echostr)
{
//1)将token、timestamp、nonce三个参数进行字典序排序
String[] arr = {WeChatUtils.TOKEN,timestamp,nonce};
Arrays.sort(arr);
//2)将三个参数字符串拼接成一个字符串进行sha1加密
String str = arr[0]+arr[1]+arr[2];
String mySignature = sha1(str);
//获得自己加密的签名
//3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if(StringUtils.equals(mySignature,signature))
{
//原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败
return echostr;
}
return null;
}
注意:token要与配置的token一致
package com.guigusuqi.commonutils.utils;
public class WeChatUtils
{
public static final String TOKEN = "guigusuqi7";
}
2.配置接口信息,为了验证微信方是否接入成功
前提是需要用nginx把80端口的URL代理到项目中的接口路径
upstream questionnaire
{
server 127.0.0.1:8002;
}
server
{
listen 80;
server_name suqiqaq.cn;
location ~ /officialAccount/weChat
{
proxy_pass http://questionnaire;
}
}
3.开始使用微信公众平台的测试号来调用接口
微信测试号配置测试号
4.配置yaml:
weChat:
appID: wx6dda2178c44e613a
appsecret: 0ea9dc58811790c5115e4d44f86ed5f2
templateID: lcNTMFxkf0TlhOVryVHSadjgBG9G5nXaVefkyZ8O9es # 模板id
getAccessTokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${weChat.appID}&secret=${weChat.appsecret} # 获取accessTokenUrl
url: https://wj.qq.com/s2/9294970/8014 # 用户点击信息 跳转的url
5.编写接口,发送用户请求
@Override
public Result sendTemplateInfo(JSONObject jsonData) throws Exception
{
//获取小程序accessToken
String accessToken = obtainAccessTokenUtils.obtainAccessToken();
//消息推送接口
String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
String result = HttpClientUtils.doPost(path, jsonData.toJSONString());
//将微信返回结果解析成json对象
//判断发送模板消息结果
JSONObject obj = JSONObject.parseObject(result);
//将json对象赋值给map
Map<String, Object> map = obj;
//获取错误码 如果code为0,errmsg为ok 代表成功
Integer code = (Integer)map.get("errcode");
String msg = map.get("errmsg").toString();
if (0 != code || !"ok".equals(msg))
{
return Result.fail().code(code).message("消息推送失败,"+msg);
}
return Result.success().message("消息推送成功!");
}
5.1编写接口,通过发送请求getAccessTokenUrl获取access_token
package com.guigusuqi.commonutils.utils;
import com.alibaba.fastjson.JSONObject;
import com.guigusuqi.commonutils.exceptionHandler.GlobalExceptionHandler;
import com.guigusuqi.commonutils.exceptionHandler.HospitalException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import java.io.IOException;
import java.util.Map;
/**
* 公众号发送模板信息给用户所需要的access_token
*/
@Component
public class ObtainAccessTokenUtils
{
@Value("${weChat.getAccessTokenUrl}")
String getAccessTokenUrl;
/**
* 获取AccessToken
* @return
*/
public String obtainAccessToken() throws IOException
{
// 返回的用户信息json字符串
String result = HttpClientUtils.doPost(getAccessTokenUrl, "");
JSONObject obj = JSONObject.parseObject(result);
Map<String, Object> map =obj;
try {
//从结果中取出access_token
String access_token = map.get("access_token").toString();
return access_token;
}catch (Exception e){
//如果返回的结果中有errcode和errmsg,说明接口调用失败
Integer errCode = (Integer) map.get("errcode");
String errMsg = map.get("errmsg").toString();
throw new HospitalException(errCode,"微信公众平台获得access_token失败,"+errMsg);
}
}
}
HttpClientUtils:
package com.guigusuqi.commonutils.utils;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
public class HttpClientUtils
{
//发起一个get请求,返回数据是以json格式返回
public static JSONObject doGet(String url) throws IOException
{
JSONObject jsonObject = null;
CloseableHttpClient client = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
if(entity != null)
{
String result = EntityUtils.toString(entity,"UTF-8");
jsonObject = JSONObject.parseObject(result);
}
httpGet.releaseConnection();;
return jsonObject;
}
//发起一个post请求,返回数据是以json格式返回
public static String doPost(String url,String jsonParam) throws IOException
{
System.out.println(jsonParam);
// 获取连接客户端工具
CloseableHttpClient httpClient = HttpClients.createDefault();
String entityStr = null;
CloseableHttpResponse response = null;
try {
// 创建POST请求对象s
HttpPost httpPost = new HttpPost(url);
if (!"".equals(jsonParam)){
// 创建请求参数
StringEntity s = new StringEntity(jsonParam, "utf-8");
//设置参数到请求对象中
httpPost.setEntity(s);
}
//添加请求头信息
httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
httpPost.addHeader("Content-Type", "application/json");
// 执行请求
response = httpClient.execute(httpPost);
// 获得响应
HttpEntity entity = response.getEntity();
// 将响应结果转换成字符串
entityStr = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 释放连接
if (null != response) {
try {
response.close();
httpClient.close();
} catch (IOException e) {
System.out.println("释放连接出错");
e.printStackTrace();
}
}
}
// 打印响应内容
System.out.println("打印响应内容:"+entityStr);
return entityStr;
}
}
5.2 获得access_token之后,请求消息推送接口,获得发送的结果
@Override
public Result sendTemplateInfo(JSONObject jsonData) throws Exception
{
//获取小程序accessToken
String accessToken = obtainAccessTokenUtils.obtainAccessToken();
//消息推送接口
String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
String result = HttpClientUtils.doPost(path, jsonData.toJSONString());
//将微信返回结果解析成json对象
//判断发送模板消息结果
JSONObject obj = JSONObject.parseObject(result);
//将json对象赋值给map
Map<String, Object> map = obj;
//获取错误码 如果code为0,errmsg为ok 代表成功
Integer code = (Integer)map.get("errcode");
String msg = map.get("errmsg").toString();
if (0 != code || !"ok".equals(msg))
{
return Result.fail().code(code).message("消息推送失败,"+msg);
}
return Result.success().message("消息推送成功!");
}
5.3 得到access_token了,url也有了,下一步就是看看发送模板消息需要哪些入参了
{
"touser":"oLiuN6Z8zlX-ONrjPFsW8FoKKtdI",
"template_id":"lcNTMFxkf0TlhOVryVHSadjgBG9G5nXaVefkyZ8O9es",
"data":{
"first": {
"value":"恭喜你购买成功!",
"color":"#173177"
},
"keyword1":{
"value":"巧克力",
"color":"#173177"
},
"keyword2": {
"value":"39.8元",
"color":"#173177"
},
"remark":{
"value":"欢迎再次购买!",
"color":"#173177"
}
}
}
touser这个参数必须是关注了这个公众号的:
模板id就是yaml文件指定的templateID
边栏推荐
猜你喜欢
升哲科技携全域数字化方案亮相2022全球数字经济大会
安全作业7.25
Try compiling QT test on Allwinner V853 development board
How PROE/Croe edits a completed sketch and brings it back to sketching state
57: Chapter 5: Develop admin management services: 10: Develop [get files from MongoDB's GridFS, interface]; (from GridFS, get the SOP of files) (Do not use MongoDB's service, you can exclude its autom
PHP 安全最佳实践
Win11如何开启剪贴板自动复制?Win11开启剪贴板自动复制的方法
图文详述Eureka的缓存机制/三级缓存
内网穿透 lanproxy部署
【七夕特别篇】七夕已至,让爱闪耀
随机推荐
17、负载均衡
大神经验:软件测试的自我发展规划
Keras deep learning practice - traffic sign recognition
Ruijie switch basic configuration
MySQL你到底都加了什么锁?
不要再使用MySQL online DDL了
Win11怎么安装语音包?Win11语音包安装教程
为你的“架构”安排定期体检吧!
Pytorch模型训练实用教程学习笔记:三、损失函数汇总
百度无人驾驶商业化已“上路”
openresty 动态黑白名单
有序双向链表的实现。
在GBase 8c数据库后台,使用什么样的命令来对gtm、dn节点进行主备切换的操作?
哈哈!一个 print 函数,还挺会玩啊!
The solution to the vtk volume rendering code error (the code can run in vtk7, 8, 9), and the VTK dataset website
Win11如何删除升级包?Win11删除升级包的方法
When installing the GBase 8c database, the error message "Resource: gbase8c already in use" is displayed. How to deal with this?
第55章 业务逻辑之订单、支付实体定义
从普通进阶成优秀的测试/开发程序员,一路过关斩将
【ES】ES2021 我学不动了,这次只学 3 个。