当前位置:网站首页>使用微信公众号给指定微信用户发送信息
使用微信公众号给指定微信用户发送信息
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 # 用户点击信息 跳转的url5.编写接口,发送用户请求
@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
边栏推荐
- win10,在proe/creo中鼠标中键不能放大缩小
- 锐捷交换机基础配置
- 【1374. 生成每种字符都是奇数个的字符串】
- ARTS_202207W2
- 即时通讯开发移动端弱网络优化方法总结
- 工作5年,测试用例都设计不好?来看看大神的用例设计总结
- 为什么限制了Oracle的SGA和PGA,OS仍然会用到SWAP?
- 18. Distributed configuration center nacos
- Greenplum数据库源码分析——Standby Master操作工具分析
- How PROE/Croe edits a completed sketch and brings it back to sketching state
猜你喜欢

Greenplum数据库源码分析——Standby Master操作工具分析

How to install voice pack in Win11?Win11 Voice Pack Installation Tutorial

Debug一个ECC的ODP数据源

Creo5.0草绘如何绘制正六边形

Pytorch模型训练实用教程学习笔记:一、数据加载和transforms方法总结

Greenplum Database Source Code Analysis - Analysis of Standby Master Operation Tools

Win11怎么安装语音包?Win11语音包安装教程

【kali-信息收集】(1.6)服务的指纹识别:Nmap、Amap

How PROE/Croe edits a completed sketch and brings it back to sketching state

nacos installation and configuration
随机推荐
An implementation of an ordered doubly linked list.
LabVIEW 使用VISA Close真的关闭COM口了吗
Gradle系列——Gradle文件操作,Gradle依赖(基于Gradle文档7.5)day3-1
Every calculation, & say what mean
30-day question brushing plan (5)
哈哈!一个 print 函数,还挺会玩啊!
[Kapok] #Summer Challenge# Hongmeng mini game project - Sudoku (3)
57:第五章:开发admin管理服务:10:开发【从MongoDB的GridFS中,获取文件,接口】;(从GridFS中,获取文件的SOP)(不使用MongoDB的服务,可以排除其自动加载类)
短视频软件开发,Android开发,使用Kotlin实现WebView
油猴hook小脚本
Try compiling QT test on Allwinner V853 development board
【kali-信息收集】(1.5)系统指纹识别:Nmap、p0f
Greenplum数据库源码分析——Standby Master操作工具分析
【kali-信息收集】(1.2)SNMP枚举:Snmpwalk、Snmpcheck;SMTP枚举:smtp-user-enum
安装win32gui失败,解决问题
ClassID的计算中,&表示啥意思
C语言实现-直接插入排序(带图详解)
Risc-v Process Attack
【蓝桥杯选拔赛真题47】Scratch潜艇游戏 少儿编程scratch蓝桥杯选拔赛真题讲解
【1374. 生成每种字符都是奇数个的字符串】