• 使用微信公众号给指定微信用户发送信息


    1.编写接口验证微信方是否接入成功

    1. /*参数 描述
    2. signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    3. timestamp 时间戳
    4. nonce 随机数
    5. echostr 随机字符串*/
    6. @ApiOperation("验证微信方是否接入成功")
    7. @GetMapping("/weChat") //get方法是为了验证微信方是否接入成功
    8. public String validate(String signature,String timestamp,String nonce,String echostr)
    9. {
    10. //1)将token、timestamp、nonce三个参数进行字典序排序
    11. String[] arr = {WeChatUtils.TOKEN,timestamp,nonce};
    12. Arrays.sort(arr);
    13. //2)将三个参数字符串拼接成一个字符串进行sha1加密
    14. String str = arr[0]+arr[1]+arr[2];
    15. String mySignature = sha1(str);
    16. //获得自己加密的签名
    17. //3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
    18. if(StringUtils.equals(mySignature,signature))
    19. {
    20. //原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败
    21. return echostr;
    22. }
    23. return null;
    24. }

     注意:token要与配置的token一致

    1. package com.guigusuqi.commonutils.utils;
    2. public class WeChatUtils
    3. {
    4. public static final String TOKEN = "guigusuqi7";
    5. }

    2.配置接口信息,为了验证微信方是否接入成功

     前提是需要用nginx把80端口的URL代理到项目中的接口路径

    1. upstream questionnaire
    2. {
    3. server 127.0.0.1:8002;
    4. }
    5. server
    6. {
    7. listen 80;
    8. server_name suqiqaq.cn;
    9. location ~ /officialAccount/weChat
    10. {
    11. proxy_pass http://questionnaire;
    12. }
    13. }

    3.开始使用微信公众平台的测试号来调用接口

    微信测试号配置测试号

    4.配置yaml:

    1. weChat:
    2. appID: wx6dda2178c44e613a
    3. appsecret: 0ea9dc58811790c5115e4d44f86ed5f2
    4. templateID: lcNTMFxkf0TlhOVryVHSadjgBG9G5nXaVefkyZ8O9es # 模板id
    5. getAccessTokenUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${weChat.appID}&secret=${weChat.appsecret} # 获取accessTokenUrl
    6. url: https://wj.qq.com/s2/9294970/8014 # 用户点击信息 跳转的url

    5.编写接口,发送用户请求

    1. @Override
    2. public Result sendTemplateInfo(JSONObject jsonData) throws Exception
    3. {
    4. //获取小程序accessToken
    5. String accessToken = obtainAccessTokenUtils.obtainAccessToken();
    6. //消息推送接口
    7. String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
    8. String result = HttpClientUtils.doPost(path, jsonData.toJSONString());
    9. //将微信返回结果解析成json对象
    10. //判断发送模板消息结果
    11. JSONObject obj = JSONObject.parseObject(result);
    12. //将json对象赋值给map
    13. Map map = obj;
    14. //获取错误码 如果code为0,errmsg为ok 代表成功
    15. Integer code = (Integer)map.get("errcode");
    16. String msg = map.get("errmsg").toString();
    17. if (0 != code || !"ok".equals(msg))
    18. {
    19. return Result.fail().code(code).message("消息推送失败,"+msg);
    20. }
    21. return Result.success().message("消息推送成功!");
    22. }

    5.1编写接口,通过发送请求getAccessTokenUrl获取access_token

    1. package com.guigusuqi.commonutils.utils;
    2. import com.alibaba.fastjson.JSONObject;
    3. import com.guigusuqi.commonutils.exceptionHandler.GlobalExceptionHandler;
    4. import com.guigusuqi.commonutils.exceptionHandler.HospitalException;
    5. import org.springframework.beans.factory.annotation.Value;
    6. import org.springframework.stereotype.Component;
    7. import org.springframework.web.bind.annotation.GetMapping;
    8. import java.io.IOException;
    9. import java.util.Map;
    10. /**
    11. * 公众号发送模板信息给用户所需要的access_token
    12. */
    13. @Component
    14. public class ObtainAccessTokenUtils
    15. {
    16. @Value("${weChat.getAccessTokenUrl}")
    17. String getAccessTokenUrl;
    18. /**
    19. * 获取AccessToken
    20. * @return
    21. */
    22. public String obtainAccessToken() throws IOException
    23. {
    24. // 返回的用户信息json字符串
    25. String result = HttpClientUtils.doPost(getAccessTokenUrl, "");
    26. JSONObject obj = JSONObject.parseObject(result);
    27. Map map =obj;
    28. try {
    29. //从结果中取出access_token
    30. String access_token = map.get("access_token").toString();
    31. return access_token;
    32. }catch (Exception e){
    33. //如果返回的结果中有errcode和errmsg,说明接口调用失败
    34. Integer errCode = (Integer) map.get("errcode");
    35. String errMsg = map.get("errmsg").toString();
    36. throw new HospitalException(errCode,"微信公众平台获得access_token失败,"+errMsg);
    37. }
    38. }
    39. }

    HttpClientUtils:

    1. package com.guigusuqi.commonutils.utils;
    2. import com.alibaba.fastjson.JSONObject;
    3. import org.apache.http.HttpEntity;
    4. import org.apache.http.client.methods.CloseableHttpResponse;
    5. import org.apache.http.client.methods.HttpGet;
    6. import org.apache.http.client.methods.HttpPost;
    7. import org.apache.http.entity.StringEntity;
    8. import org.apache.http.impl.client.CloseableHttpClient;
    9. import org.apache.http.impl.client.HttpClients;
    10. import org.apache.http.util.EntityUtils;
    11. import java.io.IOException;
    12. public class HttpClientUtils
    13. {
    14. //发起一个get请求,返回数据是以json格式返回
    15. public static JSONObject doGet(String url) throws IOException
    16. {
    17. JSONObject jsonObject = null;
    18. CloseableHttpClient client = HttpClients.createDefault();
    19. HttpGet httpGet = new HttpGet(url);
    20. CloseableHttpResponse response = client.execute(httpGet);
    21. HttpEntity entity = response.getEntity();
    22. if(entity != null)
    23. {
    24. String result = EntityUtils.toString(entity,"UTF-8");
    25. jsonObject = JSONObject.parseObject(result);
    26. }
    27. httpGet.releaseConnection();;
    28. return jsonObject;
    29. }
    30. //发起一个post请求,返回数据是以json格式返回
    31. public static String doPost(String url,String jsonParam) throws IOException
    32. {
    33. System.out.println(jsonParam);
    34. // 获取连接客户端工具
    35. CloseableHttpClient httpClient = HttpClients.createDefault();
    36. String entityStr = null;
    37. CloseableHttpResponse response = null;
    38. try {
    39. // 创建POST请求对象s
    40. HttpPost httpPost = new HttpPost(url);
    41. if (!"".equals(jsonParam)){
    42. // 创建请求参数
    43. StringEntity s = new StringEntity(jsonParam, "utf-8");
    44. //设置参数到请求对象中
    45. httpPost.setEntity(s);
    46. }
    47. //添加请求头信息
    48. httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)");
    49. httpPost.addHeader("Content-Type", "application/json");
    50. // 执行请求
    51. response = httpClient.execute(httpPost);
    52. // 获得响应
    53. HttpEntity entity = response.getEntity();
    54. // 将响应结果转换成字符串
    55. entityStr = EntityUtils.toString(entity, "UTF-8");
    56. } catch (Exception e) {
    57. e.printStackTrace();
    58. } finally {
    59. // 释放连接
    60. if (null != response) {
    61. try {
    62. response.close();
    63. httpClient.close();
    64. } catch (IOException e) {
    65. System.out.println("释放连接出错");
    66. e.printStackTrace();
    67. }
    68. }
    69. }
    70. // 打印响应内容
    71. System.out.println("打印响应内容:"+entityStr);
    72. return entityStr;
    73. }
    74. }

    5.2 获得access_token之后,请求消息推送接口,获得发送的结果

    1. @Override
    2. public Result sendTemplateInfo(JSONObject jsonData) throws Exception
    3. {
    4. //获取小程序accessToken
    5. String accessToken = obtainAccessTokenUtils.obtainAccessToken();
    6. //消息推送接口
    7. String path = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
    8. String result = HttpClientUtils.doPost(path, jsonData.toJSONString());
    9. //将微信返回结果解析成json对象
    10. //判断发送模板消息结果
    11. JSONObject obj = JSONObject.parseObject(result);
    12. //将json对象赋值给map
    13. Map map = obj;
    14. //获取错误码 如果code为0,errmsg为ok 代表成功
    15. Integer code = (Integer)map.get("errcode");
    16. String msg = map.get("errmsg").toString();
    17. if (0 != code || !"ok".equals(msg))
    18. {
    19. return Result.fail().code(code).message("消息推送失败,"+msg);
    20. }
    21. return Result.success().message("消息推送成功!");
    22. }

    5.3 得到access_token了,url也有了,下一步就是看看发送模板消息需要哪些入参了

     

    1. {
    2. "touser":"oLiuN6Z8zlX-ONrjPFsW8FoKKtdI",
    3. "template_id":"lcNTMFxkf0TlhOVryVHSadjgBG9G5nXaVefkyZ8O9es",
    4. "data":{
    5. "first": {
    6. "value":"恭喜你购买成功!",
    7. "color":"#173177"
    8. },
    9. "keyword1":{
    10. "value":"巧克力",
    11. "color":"#173177"
    12. },
    13. "keyword2": {
    14. "value":"39.8元",
    15. "color":"#173177"
    16. },
    17. "remark":{
    18. "value":"欢迎再次购买!",
    19. "color":"#173177"
    20. }
    21. }
    22. }

    touser这个参数必须是关注了这个公众号的: 

     模板id就是yaml文件指定的templateID

  • 相关阅读:
    Golang 结构化日志包 log/slog 详解(二):Handler
    附参考文献丨艾美捷Cholesterol胆固醇说明书
    GaiaDB-X 获选北京国家金融科技认证中心「数据领域首批专项示范与先行单位」
    经典算法之分块查找法(Java实现)
    Python量化交易-动量交易策略
    【Verilog刷题篇】硬件工程师进阶1|序列检测
    Java抽象类和接口
    Stable Diffusion是什么
    okcc呼叫中心的的录音功能
    实验一 将调试集成到vscode
  • 原文地址:https://blog.csdn.net/weixin_45974277/article/details/126103571