微信模板消息,动态配置

2023-11-08

微信模板消息

扫码关注公众号


模板消息配置数据库表设计

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for kl_b_template_msg
-- ----------------------------
DROP TABLE IF EXISTS `kl_b_template_msg`;
CREATE TABLE `kl_b_template_msg`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `title` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模板标题',
  `scene_type` int(6) NULL DEFAULT NULL COMMENT '场景类型:1-注册成功通知;2-实名认证通知;3-收款结果通知',
  `template_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模板ID',
  `first` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模板开头',
  `remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '模板结尾',
  `font_color` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '字体颜色',
  `keyword` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '主题词; 关键词,关键字:多个用英文逗号分割',
  `jump_url` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '跳转地址',
  `use_num` int(13) NULL DEFAULT NULL COMMENT '使用/发送次数',
  `is_usable` int(1) NULL DEFAULT NULL COMMENT '是否可用:1-可用;0-停用',
  `extend` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '扩展字段',
  `create_time` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

选择模板微信公众平台,找到适合自己的模板,模板ID 自定义参数进行数据库配置

根据自己业务所需选择适合自己的消息模板进行配置

代码封装service、impl

package com.kalo.yepay.domain.service;

import com.kalo.yepay.domain.pojo.TemplateMsg;

import java.util.List;

public interface TemplateMsgService {

    /**
     * @MethodName:  getTemplateMsg
     * @Param:       [sceneType]
     * @Author:      Calo_Pangu
     * @Date:        2020-1-9 19:34
     * @Description: TODO           根据场景类型获取模板配置
     */
    TemplateMsg getTemplateMsg(Integer sceneType);
    /**
     * @MethodName:  useNum
     * @Param:       [templateMsg]
     * @Author:      Calo_Pangu
     * @Date:        2020-1-9 19:38
     * @Description: TODO           统计模板发送次数
     */
    void useNum(TemplateMsg templateMsg);
    /**
     * @MethodName:  sendTemplateMsg
     * @Param:       [sceneType 模板场景类型, touser 接收者openid, values  模板内容]
     * @Author:      Calo_Pangu
     * @Date:        2020-1-9 19:52
     * @Description: TODO           发送模板消息
     */
    void sendTemplateMsg(Integer sceneType,String userinfoid,List<String> values);
}
package com.kalo.yepay.domain.service.impl;

import com.alibaba.fastjson.JSON;
import com.kalo.yepay.common.service.RedisToolService;
import com.kalo.yepay.domain.mapper.TemplateMsgMapper;
import com.kalo.yepay.domain.pojo.TemplateMsg;
import com.kalo.yepay.domain.pojo.UserAuths;
import com.kalo.yepay.domain.service.TemplateMsgService;
import com.kalo.yepay.domain.service.UserAuthsService;
import com.kalo.yepay.sdk.tempmsg.request.TemplateMsgSend;
import com.kalo.yepay.sdk.tempmsg.util.HttpUtil;
import com.kalo.yepay.utils.DateUtils;
import com.kalo.yepay.utils.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.util.Arrays;
import java.util.List;
import java.util.TreeMap;

/**
 * @ClassName TemplateMsgServiceImpl
 * @Description: TODO :
 * @Author Calo-Pangu
 * @Date 2020-1-9 19:33
 * @Version V1.0
 **/
@Slf4j
@Service
public class TemplateMsgServiceImpl implements TemplateMsgService {

    @Value("${你的application.properties或yml配置}")
    private String requestURL;
    @Value("${你的application.properties或yml配置 这里我是存放redis的 redis存储的key}")
    private String accessTokenKey;
    @Autowired
    private TemplateMsgMapper templateMsgMapper;
    @Autowired
    private RedisToolService redisToolService;
    @Autowired
    private UserAuthsService userAuthsService;

    /**
     * @MethodName: getTemplateMsg
     * @Param: [sceneType]
     * @Author: Calo_Pangu
     * @Date: 2020-1-9 19:34
     * @Description: TODO           根据场景类型获取模板配置
     */
    @Override
    public TemplateMsg getTemplateMsg(Integer sceneType) {
        log.warn("---------------------------------------     根据模板场景类型获取模板配置    ---------------------------------------");
        Example example = new Example(TemplateMsg.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("sceneType", sceneType);
        criteria.andEqualTo("isUsable", 1);
        return templateMsgMapper.selectOneByExample(example);
    }

    /**
     * @MethodName: useNum
     * @Param: [templateMsg]
     * @Author: Calo_Pangu
     * @Date: 2020-1-9 19:38
     * @Description: TODO           统计模板发送次数
     */
    @Override
    public void useNum(TemplateMsg templateMsg) {
        log.warn("---------------------------------------    统计模板发送次数    ---------------------------------------");
        Integer useNum = templateMsg.getUseNum();//使用前次数
        templateMsg.setUseNum(useNum + 1);
        templateMsg.setUpdateTime(DateUtils.getDateTime());
        templateMsgMapper.updateByPrimaryKeySelective(templateMsg);
    }

    /**
     * @MethodName: sendTemplateMsg
     * @Param: [sceneType 模板场景类型, touser 接收者openid, values  模板内容]
     * @Author: Calo_Pangu
     * @Date: 2020-1-9 19:52
     * @Description: TODO           发送模板消息
     */
    @Override
    public void sendTemplateMsg(Integer sceneType,String userinfoid, List<String> values) {
        List<UserAuths> userAuths = userAuthsService.userAuthsList(userinfoid);
        if (values.size() > 0 && userAuths.size() > 0) {
            UserAuths userAuth = userAuths.get(0);
            //1. 拿到模板配置信息
            TemplateMsg templateMsg = getTemplateMsg(sceneType);
            //2. ACCESS_TOKEN 从 Redis 获取  拼接URL
            String sendURL = requestURL.replace("ACCESS_TOKEN", redisToolService.get(accessTokenKey));
            //3. 数据库模板keywords 拿到keyword
            List<String> keywords = Arrays.asList(templateMsg.getKeyword().split(","));
            //4. 构建请求参数
            TemplateMsgSend templateMsgSend = new TemplateMsgSend();
            templateMsgSend.setTouser(userAuth.getOpenid());
            templateMsgSend.setTemplate_id(templateMsg.getTemplateId());
            templateMsgSend.setUrl(templateMsg.getJumpUrl());
            TreeMap<String, TreeMap<String, String>> data = new TreeMap<>();
            String first = templateMsg.getFirst().replace("USER",userAuth.getNick_name());
            data.put("first", templateMsgSend.item(first, templateMsg.getFontColor()));
            for (int i = 0; i < keywords.size(); i++) {
                data.put(keywords.get(i), templateMsgSend.item(values.get(i), templateMsg.getFontColor()));
            }
            data.put("remark", templateMsgSend.item(templateMsg.getRemark(), templateMsg.getFontColor()));
            templateMsgSend.setData(data);
            //5. 发送模板消息
            String request = JSON.toJSONString(templateMsgSend);
            log.warn("发送模板消息请求参数:{}", request);
            JSONObject result = HttpUtil.sendPost(sendURL, request);
            log.warn("发送模板消息返回信息:{}", result);
            //6. 发送成功后统计发送次数
            String errcode = JSONUtil.getValNetsf(result, "errcode");
            String errmsg = JSONUtil.getValNetsf(result, "errmsg");
            //7. 更新模板发送次数
            if ("0".equalsIgnoreCase(errcode) && "ok".equalsIgnoreCase(errmsg)){
                useNum(templateMsg);
            }
        }
    }
}
HttpUtil 工具类
package com.kalo.yepay.sdk.tempmsg.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;

@Slf4j
public class HttpUtil {

    private static final String charset = "UTF-8";
    private static final String requestMode = "POST";
    private static final String NoSuchAlgorithm = "No Such Algorithm Exception [无此算法异常]:{}";
    private static final String KeyManagement = "Key Management Exception [密钥管理异常]:{}";

    @SuppressWarnings("static-access")
    public static JSONObject sendPost(String urls, String data) {
        JSONObject result = new JSONObject();
        StringBuffer sb = new StringBuffer();
        OutputStreamWriter outputStreamWriter = null;
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL(urls);
            trustAllHttpsCertificates();
            HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
            HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();
            httpsConn.setUseCaches(false);
            httpsConn.setDoOutput(true);
            httpsConn.setDoInput(true);
            httpsConn.setFollowRedirects(true);
            httpsConn.setInstanceFollowRedirects(true);
            httpsConn.setRequestMethod(requestMode);
            outputStreamWriter = new OutputStreamWriter(httpsConn.getOutputStream(), charset);
            outputStreamWriter.write(data);
            outputStreamWriter.flush();
            bufferedReader = new BufferedReader(new InputStreamReader(httpsConn.getInputStream(), charset));
            String inputLine;
            while ((inputLine = bufferedReader.readLine()) != null) {
                sb.append(inputLine);
            }
            log.info("HttpClientPost Response Info:[{}]",result.fromObject(sb.toString()));
            return result.fromObject(sb.toString());
        } catch (Exception e) {
            log.error("Key Management Exception [密钥管理异常]", e.getMessage());
        } finally {
            try {
                outputStreamWriter.close();
                bufferedReader.close();
            } catch (IOException e) {
                log.error("IOException [关闭请求流异常]", e.getMessage());
            }
        }
        return result;
    }

    private static void trustAllHttpsCertificates() {
        try {
            javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
            javax.net.ssl.TrustManager tm = new MiTM();
            trustAllCerts[0] = tm;
            javax.net.ssl.SSLContext sc;
            sc = javax.net.ssl.SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (NoSuchAlgorithmException e) {
            log.error(NoSuchAlgorithm, e.getMessage());
        } catch (KeyManagementException e) {
            log.error(KeyManagement, e.getMessage());
        }
    }

    static class MiTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }

        public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
    }

    static HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

}

调用方式

效果展示

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信模板消息,动态配置 的相关文章

随机推荐

  • git. 常用操作总结

    TOC GIT指南 在GIT中任何已经提交的东西几乎总是可以恢复的 甚至那些被删除的分支中的提交或使用 amend选项覆盖的提交也可以恢复 然而任何你未提交的东西丢失后很可能再也找不到 git pull会抓取所有的远程引用 Git在进行提交
  • 【通原】采样频率往往高于原信号的2倍的原因

    采样信号不是理想冲激信号 在采样前 需要添加一个抗混叠滤波器以避免频谱混叠 带宽越低越难设计 因此采样频率设计为原信号的3 5倍
  • paddleoc onnx转换推理

    目录 paddle 文字识别验证代码 onnx c 推理 python onnx识别部分推理示例 感谢博客 PaddleOCR转ONNX模型 推理部分 favorxin的博客 CSDN博客 paddleocr转onnx paddle 文字识
  • 2023年场外个股期权研究报告

    第一章 概况 场外个股期权 Over the Counter Equity Option 是指由交易双方根据自己的需求和意愿 通过协商确定行权价格 行权日期等条款的股票期权 与交易所交易的标准化期权不同 场外个股期权的合同内容可以根据交易双
  • .NET MVC标签扩展(checkbox,radio)

    NET MVC里面自动绑定form表单功能 如 Html TextBox Name Html Hidden hide 名称会自动与后台就行绑定ViewBag Name ViewBag hide 很实用 但是感觉不足的就是 Html Chec
  • Redis学习笔记(转尚硅谷周阳)

    教学视频 Redis官网 Redis中文官网 一 NoSQL入门概述 上 1 互联网时代背景下大机遇 为什么用NoSQL 1 1 单机MySQL的美好年代 在90年代 一个网站的访问量一般都不大 用单个数据库完全可以轻松应付 在那个时候 更
  • 整形提升和数据截断

    整形提升和截断 1 整形提升 2 截断 1 整形提升 提升是将占字节小的元素赋给占字节大的元素时出现的补位现象 截断是将所占字节大的元素赋给所占字节小的元素时会出现数值的舍去现象 下面看代码来分析 include
  • html的日期选择插件

    1 效果 2 文档 https layui gitee io v2 docs 3 引入 官网地址 https layui gitee io v2 引入 在官网下载 jquery 1 7 2 min js layui layui js 4 使
  • 绘制坐标轴:Python实现

    绘制坐标轴 Python实现 在数据可视化领域 坐标轴是一种重要的图形元素 用于显示数据的分布和趋势 Python提供了多种库和工具 可以方便地绘制坐标轴和相关图表 本文将介绍如何使用Python实现绘制坐标轴的功能 并提供相应的源代码示例
  • qt5.10 串口通信 QSerialPort 的使用

    在qt5中 使用QSerialPort进行串口通信 主要用到的QSerialPort 使用步骤 步骤一 在 pro文件中进行声明 QT serialport 在 pro文件中添加这个声明 步骤二 实例化 QSrerialPort QSeri
  • 实现itoa()和atoi()

    atoi 将字符串转换为整型值 实现代码 enum Status valid unvalid int status valid 全局变量标记输入是否非法 long long AtoI const char str bool minus lo
  • ZYNQ #5 - 从vivado工程开始,从emmc启动Linux

    本文从最简单的petalinux需求的vivado工程开始 建立一个能跑起来linux的vivado工程 同时将linux kernel 根文件系统部署在接到SD1接口上的emmc中 qspi flash中放置BOOT BIN uboot唤
  • vite和webpack的区别

    vite和webpack的区别 从底层原理上来说 Vite是基于esbuild预构建依赖 而esbuild是采用go语言编写 因为go语言的操作是纳秒级别 而js是以毫秒计数 所以vite比用js编写的打包器快10 100倍 Vite和We
  • 成为合格管理者的几个关键词

    http www csdn net article 2014 05 05 2819612 Management 职业通路是狭窄的 金字塔 结构很好地描绘了每个人在职场将要走过的路 在职位与薪酬待遇紧密挂钩的当今职场 芸芸技术专家总有一天会面
  • 【Neo4j】第 10 章:图嵌入 - 从图到矩阵

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • Linux 如何查看文件夹的大小(du、df、ls、find)

    Linux 如何查看文件夹的大小 du df ls find 参考链接 https blog csdn net Cappuccino jay article details 125168388 一 du 命令 查看当前目录和子目录文件夹 文
  • 微信小程序中下载app的方法

    微信小程序中下载app的方法 因为微信小程序本身是不推荐引流到外部的 所以正规的方法其实都是被禁止掉的 大致方向是打开内部浏览器 进入应用宝下载页面 如果app接入应用宝 或者是通过右上角的在系统浏览器中打开 自动跳转到App Store中
  • XML中常用转义符

    编写XML代码常用转译符 逻辑与 amp lt 小于 lt gt 大于 gt 双引号 quot XML实体中不允许出现 lt gt 等特殊字符 否则XML语法检查时将出错 如果编写的XML文件必须包含这些字符 则必须分别写成 amp lt
  • vue实现前端人机验证

    最简单的一个例子 安装插件 npm install vue puzzle vcode save
  • 微信模板消息,动态配置

    微信模板消息 扫码关注公众号 模板消息配置数据库表设计 SET NAMES utf8mb4 SET FOREIGN KEY CHECKS 0 Table structure for kl b template msg DROP TABLE