本文主要实现给不同的用户推动不同的问候模板

准备工作

申请微信公众平台的测试号

申请微信测试公众号
创建成功后,可以看到appid和appsecret,这个后面认证时需要

申请模板

可自行修改

今天是:{{now.DATA}} 不管那一天,每一天都是想你的一天
当前城市:{{city.DATA}}
今天的天气:{{text.DATA}}
最低气温:{{low.DATA}} 度
最高气温:{{high.DATA}} 度
今天是我们想恋的第:{{scq_day.DATA}} 天
距你的生日还有:{{bir_day.DATA}} 天
{{daily_english_cn.DATA}}
{{daily_english_en.DATA}}

新建成功后,记得保存模板Id后续有用

扫描关注该测试公众号

扫码关注后,记录微信号,后续推送通知用

申请百度天气

申请百度天气

完成认证后,创建一个应用,保存ak

申请天行数据的接口

申请天行数据

  • 申请彩虹屁
  • 申请每日一句

记得保存申请接口的key

开发工作

技术栈

  • springboot 2.7.5
  • swagger 3.0
  • mysql 8.x
  • spring data jpa
  • openfeign

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zhao</groupId><artifactId>daily-weather</artifactId><version>1.0.0</version><name>daily-weather</name><description>微信用户推送消息</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.7.5</spring-boot.version><swagger.version>3.0.0</swagger.version><knife4j.version>3.0.3</knife4j.version><fastjson.version>2.0.15</fastjson.version><openfeign.version>3.1.3</openfeign.version><hutools.version>5.7.5</hutools.version></properties><dependencies><!--hutools--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>${hutools.version}</version></dependency><!--fastjson--><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>${fastjson.version}</version></dependency><!--open feign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>${openfeign.version}</version></dependency><!--weixin-java-mp--><dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-mp</artifactId><version>3.3.0</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>${swagger.version}</version></dependency><!--换掉默认皮肤--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>${knife4j.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.3.7.RELEASE</version><configuration><mainClass>com.zhao.wechat.DailyWeatherApplication</mainClass></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build></project>

配置文件

server:port: 43310
# 微信配置
tencent:wechat:appId: 微信appidappSecret: 微信appSecret# 模板消息集合templatelist:- type: 1templateId: 微信模板id- type: 2templateId: 微信模板id- type: 3templateId: 微信模板id
# 百度天气配置
baidu:server: https://api.map.baidu.comak: 百度数据的ak
# 天行数据
tianxin:server: http://api.tianapi.comkey: 天行数据的key
spring:mvc:pathmatch:matching-strategy: ant_path_matcherdatasource:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://ip:3306/库名?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghaiusername: rootpassword: 564929hikari:minimum-idle: 5# 空闲连接存活最大时间,默认600000(10分钟)idle-timeout: 180000# 连接池最大连接数,默认是10maximum-pool-size: 10# 此属性控制从池返回的连接的默认自动提交行为,默认值:trueauto-commit: true# 连接池名称pool-name: MyHikariCP# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟max-lifetime: 1800000# 数据库连接超时时间,默认30秒,即30000connection-timeout: 30000connection-test-query: SELECT 1jpa:show-sql: true # 默认false,在日志里显示执行的sql语句database: mysqldatabase-platform: org.hibernate.dialect.MySQL5Dialecthibernate:ddl-auto: update #指定为update,每次启动项目检测表结构有变化的时候会新增字段,表不存在时会 新建,如果指定create,则每次启动项目都会清空数据并删除表,再新建naming:#指定jpa的自动表生成策略,驼峰自动映射为下划线格式7implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl#physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# 日志
#logging:
#  config: classpath:logback-spring-dev.xml

统一数据封装

package com.zhao.wechat.advice;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhao.wechat.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/*** 对前端响应结果统一封装*/
@Slf4j
@RestControllerAdvice(basePackages = {"com.zhao.wechat.rest"})
public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {/*** 打印统一请求响应规范*/ApiResponseAdvice(){log.info("启动请求统一响应规范... ...");}/*** 判断是否需要对返回值进行封装* @param returnType the return type* @param converterType the selected converter type* @return*/@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {// 如果返回的结果是Result.class类型就不用封装if (returnType.getParameterType().equals(Result.class)){return false;}return true;}/*** 对返回前端的值统一封装* @param body the body to be written* @param returnType the return type of the controller method* @param selectedContentType the content type selected through content negotiation* @param selectedConverterType the converter type selected to write to the response* @param request the current request* @param response the current response* @return*/@Overridepublic Object beforeBodyWrite(Object body,MethodParameter returnType,MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request,ServerHttpResponse response) {if (returnType.getParameterType().equals(String.class)){// 如果是String类需要特殊处理ObjectMapper objectMapper = new ObjectMapper();try {// 设置响应数据格式为jsonresponse.getHeaders().add("content-type","application/json;charset=UTF-8");return objectMapper.writeValueAsString(Result.success(body));} catch (JsonProcessingException e) {throw new RuntimeException(e);}}return Result.success(body);}}

工程结构

用户controller

package com.zhao.wechat.rest;import com.zhao.wechat.domain.UserInfo;
import com.zhao.wechat.service.UserInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** 用户信息管理视图层*/
@RestController
@RequestMapping("/userInfo")
@Api(tags = "用户信息管理")
public class UserInfoRest {@Autowiredprivate UserInfoService userInfoService;/*** 分页获取所有的用户* @return*/@ApiOperation(value = "分页获取所有的用户")@PostMapping("/queryPage")public Page<UserInfo> queryUserPage(@PageableDefault Pageable pageable){Page<UserInfo> userInfos = userInfoService.queryUserPage(pageable.getPageNumber(), pageable.getPageSize());return userInfos;}/*** 添加或者修改用户*/@ApiOperation(value = "添加或者修改用户")@PostMapping("/saveOrUpdate")public    void saveOrUpdate(@RequestBody UserInfo userInfo){userInfoService.saveOrUpdate(userInfo);}/*** 删除用户*/@ApiOperation(value = "删除用户")@DeleteMapping("/delete")public void deleteUserById(@RequestParam("id") Long id){userInfoService.deleteUserById(id);}}

调用第三方接口

package com.zhao.wechat.remote;import com.zhao.wechat.remote.param.TianXinParam;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;/*** 第三方接口天行数据*/
@FeignClient(value = "TianDataRemoteClient",url = "${tianxin.server}")
public interface TianDataRemoteClient {/*** 获取彩虹屁*/@GetMapping(value = "/caihongpi/index",consumes = {MediaType.APPLICATION_JSON_VALUE},produces = {MediaType.APPLICATION_JSON_VALUE})String queryRainbow(@SpringQueryMap TianXinParam tianXinParam);/*** 获取优美的句子*/@GetMapping(value = "/ensentence/index",consumes = {MediaType.APPLICATION_JSON_VALUE},produces = {MediaType.APPLICATION_JSON_VALUE})String queryEnsentence(@SpringQueryMap TianXinParam tianXinParam);}

推送微信数据

package com.zhao.wechat.service;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.zhao.wechat.config.WechatConfig;import com.zhao.wechat.config.WechatTemplate;
import com.zhao.wechat.config.WechatTemplateList;
import com.zhao.wechat.domain.*;
import com.zhao.wechat.remote.BaiduWeatherRemoteClient;
import com.zhao.wechat.remote.TianDataRemoteClient;
import com.zhao.wechat.remote.param.BaiduWeatherParam;
import com.zhao.wechat.remote.param.TianXinParam;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;@Slf4j
@Service
public class PushDailyWechatImpl implements PushDailyWechat{@Autowiredprivate UserInfoService userInfoService;@Autowiredprivate BaiduWeatherRemoteClient baiduWeatherRemoteClient;@Autowiredprivate TianDataRemoteClient tianDataRemoteClient;/** 微信配置类 **/@Autowiredprivate WechatConfig wechatConfig;/** 模板列表**/@Autowiredprivate WechatTemplateList wechatTemplateList;/** ak **/@Value("${baidu.ak}")private String ak;/** key **/@Value("${tianxin.key}")private String key;/*** 给不同的用户推送消息*/@Overridepublic void pushWechat() throws WxErrorException {// 获取用户列表List<UserInfo> userInfoList = userInfoService.listUserInfo();if (!CollectionUtils.isEmpty(userInfoList)){// 根据用户的type类型和模板type进行匹配for (UserInfo userInfo : userInfoList) {for (WechatTemplate template : wechatTemplateList.getTemplatelist()) {if (userInfo.getType().equals(template.getType())){this.wechatData(userInfo.getWechatId(), template.getTemplateId(),userInfo);}}}}}/*** 封装微信数据* @param wechatId* @param templateId*/private void wechatData(String wechatId,String templateId,UserInfo userInfo) throws WxErrorException {// 创建配置信息WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();wxStorage.setAppId(wechatConfig.getAppId());wxStorage.setSecret(wechatConfig.getAppSecret());WxMpService wxMpService = new WxMpServiceImpl();wxMpService.setWxMpConfigStorage(wxStorage);// 创建模板信息WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder().toUser(wechatId).templateId(templateId).build();// 获取天气预报信息BaiduWeatherParam baiduWeatherParam = BaiduWeatherParam.builder().district_id(userInfo.getDistrictId()).data_type("all").ak(this.ak).build();String queryWeather = baiduWeatherRemoteClient.queryWeather(baiduWeatherParam);log.info("查询的百度天气信息为:{}",queryWeather);BaiduNowWeather baiduNowWeather = ApiResponse.parseBaiduNowData(queryWeather, BaiduNowWeather.class);List<BaiduForecastsWeather> baiduForecastsWeatherList = ApiResponse.parseBaiduForecastsData(queryWeather, BaiduForecastsWeather.class);log.info("baiduNowWeather:{},baiduForecastsWeather:{}",baiduNowWeather,baiduForecastsWeatherList);// 获取彩虹屁TianXinParam tianXinParam = TianXinParam.builder().key(this.key).build();String queryRainbow = tianDataRemoteClient.queryRainbow(tianXinParam);List<TianRainbow> rainbowList = ApiResponse.parseTianData(queryRainbow, TianRainbow.class);// 获取每日一句String queryEnsentence = tianDataRemoteClient.queryEnsentence(tianXinParam);List<TianEnsentence> tianEnsentenceList = ApiResponse.parseTianData(queryEnsentence, TianEnsentence.class);// 封装模板数据templateMessage.addData(new WxMpTemplateData("now", this.pareDateNow(baiduForecastsWeatherList.get(0)),"#FFB6C1"));templateMessage.addData(new WxMpTemplateData("city",userInfo.getCity(),"#B95EA6"));templateMessage.addData(new WxMpTemplateData("text",baiduNowWeather.getText(),"#173177"));templateMessage.addData(new WxMpTemplateData("high",baiduForecastsWeatherList.get(0).getHigh(),"#87cefa"));templateMessage.addData(new WxMpTemplateData("low",baiduForecastsWeatherList.get(0).getLow(),"#FF6347"));templateMessage.addData(new WxMpTemplateData("scq_day",this.calScqDate(userInfo),"#FF1493"));templateMessage.addData(new WxMpTemplateData("bir_day",this.calBirData(userInfo),"#FF00FF" ));templateMessage.addData(new WxMpTemplateData("daily_english_cn",rainbowList.get(0).getContent(),"#800080"));templateMessage.addData(new WxMpTemplateData("daily_english_en",tianEnsentenceList.get(0).getEn(),"#FFA500"));log.info("发送的消息为:{}", JSON.toJSONString(templateMessage));wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);}/*** 计算想认识/想恋日期* @return*/private String calScqDate(UserInfo userInfo){// 获取第一次想认识的时间if (Objects.nonNull(userInfo)){Date scqTime = userInfo.getScqTime();// 计算时间差long between = DateUtil.between(scqTime, DateUtil.date(), DateUnit.DAY);return String.valueOf(between);}return "";}/*** 计算生日* @param userInfo* @return*/private String calBirData(UserInfo userInfo){// 获取用户的出生日期if (Objects.nonNull(userInfo)){Date birTime = userInfo.getBirTime();// 今日日期Calendar today = Calendar.getInstance();// 出生日期Calendar birthDay = Calendar.getInstance();// 设置生日birthDay.setTime(birTime);// 修改为本年int bir;birthDay.set(Calendar.YEAR,today.get(Calendar.YEAR));if (birthDay.get(Calendar.DAY_OF_YEAR) < today.get(Calendar.DAY_OF_YEAR)){// 生日已经过了,计算明年的bir = today.getActualMaximum(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR);bir += birthDay.get(Calendar.DAY_OF_YEAR);} else {// 生日还没过bir = birthDay.get(Calendar.DAY_OF_YEAR) - today.get(Calendar.DAY_OF_YEAR);}return String.valueOf(bir);}return "";}/*** 拼接今日时间* @return*/private String pareDateNow(BaiduForecastsWeather baiduForecastsWeather){// 获取当前日期String now =  DateUtil.format(DateUtil.date(), DatePattern.CHINESE_DATE_PATTERN);// 获取星期几String week = baiduForecastsWeather.getWeek();return now+" "+week;}
}

定时任务

package com.zhao.wechat.job;import com.zhao.wechat.service.PushDailyWechat;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;/*** 推送消息到用户定时任务*/
@Component
public class PushWechatJob {@Autowiredprivate PushDailyWechat pushDailyWechat;/*** 每天早上7点推送到微信* @throws WxErrorException*/@Scheduled(cron = "0 30 7 1/1 * ? ")void  doJob() throws WxErrorException {pushDailyWechat.pushWechat();}
}

效果

推送到微信

使用springboot每日推送早安问候语到用户微信相关推荐

  1. 使用springboot每日推送早安问候语到用户微信【部署篇】

    上一篇介绍文章 上一篇介绍文章 https://blog.csdn.net/weixin_45206218/article/details/127872136 代码仓库 代码仓库 https://gi ...

  2. bars 除障句完整_精选每日一句早安问候语语录49句

    精选每日一句早安问候语语录49句 任何事情都是这样一个过程,决定去做了,就着手去做,一旦找到了舒适区,你就会乐在其中,或许就发现:"喜欢比努力更重要."乐在其中地去坚持一件事,总好 ...

  3. 公众号推送早安问候以及天气预报(JAVA)

    公众号推送早安问候以及天气预报(JAVA) ① 概述 功能点 每天早上可以给指定的微信用户推送消息,经过公众号 可以使用第三方接口丰富推送的消息内容 百度天气api:添加天气信息推送 天行数据api: ...

  4. 用公众号给女朋友推送早安问候(恋爱值♥♥♥♥♥)

    前言 最近,女朋友给我推了一个抖音视频,讲述的是一个女孩子收到了她对象的早安问候,里面文字花花绿绿,问候词都快羞红了我的脸,不过,看的出来她很喜欢.好吧,我懂了.于是,不太会公众号开发的我去B站学习了 ...

  5. 女神节来了,快给那个Ta做个公众号推送早安问候及天气预报,可自动定时推送哦~

    女神节到了,程序员必备撩妹怎会没有方法?微信自动发送问候语以及天气预报,快给那个Ta做一个吧! 通用设置 注意:本小节所有要小本本记下的内容都要填写到配置文件config.txt里的哦~ ▲ *con ...

  6. 图片的宽铺满全屏 微信小程序_2020冬至快乐图片!,图片祝福贺卡,朋友圈冬至早安问候语动态图片微信小程序...

    朋友你好,2020冬至快乐! 冬至的雪,美丽着脸庞,飘逸冬的梦想:冬至的汤,沸腾着喜悦,感受夏的热浪!一年中最冷的时候到了,祝你:快乐如雪,温暖如汤!冬至快乐! 冬至吃饺子,一个饺子一颗心.吃韭菜馅饺 ...

  7. 企业微信每日给女友推送早安,5分钟快速部署,腾讯云部署版本,每日定时发送,天气,鸡汤,纪念日等信息,可自定义通知提醒名称,聊天界面可置顶,内容可查图片。

    企业微信每日给女朋友推送早安,5分钟快速部署,每日定时发送,天气,鸡汤,纪念日等信息,可自定义通知提醒名称,聊天界面可置顶,内容可查图片. 先看效果 直接开搞 准备工作 1.企业id 2.企业应用se ...

  8. 1.8 微信推送早安及天气预报信息(Springboot框架)(二)

    微信推送早安及天气预报信息(搭建框架和代码完善) 目录 一.搭建框架 1. 环境准备 2. 搭建Springboot框架 二.获取代码并完善 1. pom.xml 2. application.yml ...

  9. 1.7 微信推送早安及天气预报信息(Springboot框架)(一)

    微信推送早安及天气预报信息(开发前期准备) 目录 一.申请天行数据API接口 1. 注册 2. 登录 3. 验证邮箱 4. [申请接口] 5. [我的密钥KEY] 二.申请实况天气API接口 1. 注 ...

最新文章

  1. 学java培训开发需要多少钱
  2. java 反射机制_Java反射机制原理探究
  3. python flask 教程_Flask 教程 第一章:Hello, World!
  4. Java程序员新手老手都离不开八大开发工具
  5. 200726C的数据传递方式
  6. wxml代码支持js代码吗_如何取胜:代码支持者的建议
  7. 如何使用Alert 组件
  8. python十大语言领域_十大编程语言榜单
  9. net core 小坑杂记之配置文件读取(不定期更新)
  10. 从零开始搭建ELK+GPE监控预警系统
  11. linux下定时执行sh
  12. 《ANSYS Workbench有限元分析实例详解(静力学)》——第1章 CAE分析步骤1.1 模型简化...
  13. 形式语言与自动机之一 语言与文法
  14. 【读书分享】人性的弱点
  15. http-server 简介
  16. 鹏业安装算量软件功能按钮汇总(一)
  17. 安装 OpenCC 简繁体中文转换
  18. manjaro kde 20.2安装
  19. 中国的超级计算机银河号,美国突然切断GPS,是银河号的一次屈辱,中国:不会再让悲剧发生...
  20. android+客户端+教程,Android新浪客户端开发教程完整版.pdf

热门文章

  1. 【金猿案例展】某保险公司——亚信科技大数据产品,助其数据管理 高效运营...
  2. 项目实战教程来了-4412开发板-zigbee智能家居
  3. only named arguments may follow *expression
  4. CockroachDB分布式SQL层架构解析
  5. USB。标准键盘的报告描述符解析。
  6. linux的java配置与tomcat配置
  7. Embedding理解、Keras实现Embedding
  8. 【English】入门篇之认识26个英文字母
  9. FDM3D打印系列——2、一些基础概念
  10. 金三银四求职季来了!分享几道最常见的app面试题,帮助您更好准备面试求职!