当前位置:网站首页>使用微信公众号给指定微信用户发送信息
使用微信公众号给指定微信用户发送信息
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
边栏推荐
- Compse编排微服务实战
- Pytorch模型训练实用教程学习笔记:一、数据加载和transforms方法总结
- vtk体绘制代码报错的解决办法(代码在vtk7,8,9中都能运行),以及VTK数据集网站
- CMake教程——Leeds_Garden
- DAO development tutorial [WEB3.0]
- Ruijie switch basic configuration
- 18、分布式配置中心nacos
- Creo5.0草绘如何绘制正六边形
- Redis启动时提示Creating Server TCP listening socket *:6379: bind: No error
- cf:D. Magical Array【数学直觉 + 前缀和的和】
猜你喜欢
Risc-v Process Attack
Redis启动时提示Creating Server TCP listening socket *:6379: bind: No error
regular expression
deploy zabbix
cf:D. Magical Array【数学直觉 + 前缀和的和】
openresty 动态黑白名单
【kali-信息收集】(1.4)识别活跃的主机/查看打开的端口:Nmap(网络映射器工具)
开源视界 | StreamNative 盛宇帆:和浪漫的人一起做最浪漫的事
【蓝桥杯选拔赛真题47】Scratch潜艇游戏 少儿编程scratch蓝桥杯选拔赛真题讲解
内网穿透 lanproxy部署
随机推荐
DAO开发教程【WEB3.0】
【周赛复盘】LeetCode第304场单周赛
在GBase 8c数据库后台,使用什么样的命令来对gtm、dn节点进行主备切换的操作?
PHP 安全最佳实践
突破边界,华为存储的破壁之旅
Compse编排微服务实战
有点奇怪!访问目的网址,主机能容器却不行
短视频软件开发,Android开发,使用Kotlin实现WebView
18、分布式配置中心nacos
Tencent Cloud Hosting Security x Lightweight Application Server | Powerful Joint Hosting Security Pratt & Whitney Version Released
XSS range intermediate bypass
Win11如何删除升级包?Win11删除升级包的方法
密码学的基础:X.690和对应的BER CER DER编码
Database Plus 的云上之旅:SphereEx 正式开源 ShardingSphere on Cloud 解决方案
Try compiling QT test on Allwinner V853 development board
CMake教程——Leeds_Garden
第58章 结构、纪录与类
Pytorch模型训练实用教程学习笔记:一、数据加载和transforms方法总结
第59章 ApplicationPart内置依赖注入中间件
大神经验:软件测试的自我发展规划