给女朋友写的,每日推送暖心消息
2023-03-12

在掘金上看到有用Python、node、egg写的给女朋友发每日提醒消息的文章,感觉挺有意思的,自己用Java给女友整了一个。

环境准备

  • SpringBoot 2.5.6

  • Hutool 5.7.15

    Hutool是一个小而全的Java工具类库

    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.7.15</version>
    </dependency>
    
  • 天气接口:https://www.tianqiapi.com/

  • 每日一句:https://v1.hitokoto.cn/

公众号准备

因为个人只能创建订阅号,不能使用模板消息所以用的微信公众号的测试账号,可以使用所有高级功能,缺点不能改名字,也可以用网页版微信来实现

1. 申请测试账号:申请地址

2. 让你的她扫描二维码关注这个公众号

QQ截图20211115151111.png

3. 创建模板

  • 每日消息

    {{dateTime.DATA}} 
    今天是 我们相恋的第{{love.DATA}}天 
    距离你的生日还有{{birthday.DATA}}天 
    今日天气 {{wea.DATA}} 
    当前温度 {{tem.DATA}}度 
    最高温度 {{tem1.DATA}}度 
    最低温度 {{tem2.DATA}}度 
    空气质量 {{airLevel.DATA}} 
    风向 {{win.DATA}} 
    每日一句 {{message.DATA}}
    
  • 晚安消息

    {{dateTime.DATA}} 已经11点了哦,早点睡觉,晚安! 
    ❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️
    
  • 干饭

    干饭人,干饭魂,干饭都是人上人!
     🍚干饭干饭 冲冲冲 !🍚
    

模板接口请求Json

接口文档:https://mp.weixin.qq.com/debug/cgi-bin/readtmpl?t=tmplmsg/faq_tmpl

{
    "touser":"OPENID",
    "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
"url":"http://weixin.qq.com/download",
    "topcolor":"#FF0000",
    "data":{
            "User": {
                "value":"黄先生",
                "color":"#173177"
            }
    }
}

实体类

配置类

创建一个配置类,用来存储配置信息

@Component
@ConfigurationProperties(prefix = "send")
public class Config {

    /**
     * 微信appid
     */
    private String appid;

    /**
     * 微信appSecret
     */
    private String secret;

    /**
     * 发送用户
     */
    private String touser;

    /**
     * 天气接口
     */
    private String weaAppid;
    private String weaAppsecret;
    /**
     * 城市名
     */
    private String city;
    // 省略getting setting方法,可以用lombok
  

参数实体类

我把请求的Json中的data里的数据封装成了一个实体类,方便使用

public class Data {
    private String value;
    private String color;
    public Data(String value, String color) {
        this.value = value;
        this.color = color;
    }
}

配置文件

send:
  # 测试号的appid
  appid:
  # 天气接口的appid 
  wea-appid:
  # 天气接口的appsecret
  wea-appsecret:
  # 城市名
  city:
  # 测试号的appsecret
  secret:
  # 发给谁,测试号二维码右边找到
  touser:

获取数据

获取token

@Autowired
Config config;
static String access_token ;
static Long expiresIn = System.currentTimeMillis();
private void extracted(long now) {
        if(access_token == null || expiresIn > now){
            HashMap<String, Object> paramMap = new HashMap<>();
            paramMap.put("grant_type", "client_credential");
            paramMap.put("appid",config.getAppid());
            paramMap.put("secret",config.getSecret());
            // 获取 token
            String res = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", paramMap);
            System.out.println(res);
            access_token = (String) JSONUtil.parseObj(res).get("access_token");
            expiresIn = (int) JSONUtil.parseObj(res).get("expires_in") + now * 1000 -3000;
            System.out.println(access_token);
            System.out.println(expiresIn);
        }
    }

获取天气

public JSONObject getWeather(){
         HashMap<String, Object> data = new HashMap<>();
         data.put("appid",config.getWeaAppid());
         data.put("appsecret",config.getWeaAppsecret());
         data.put("unescape",1);
         data.put("city",config.getCity());

         String resp = HttpUtil.get("https://www.tianqiapi.com/free/day", data);

         return JSONUtil.parseObj(resp);

     }

每日一句

 public JSONObject getMessage(){
         String s = HttpUtil.get("https://v1.hitokoto.cn/");
         return JSONUtil.parseObj(s);
     }

在一起的时间

 public long getLove(){
         LocalDateTime time = LocalDateTime.of(2019, 1, 4, 0, 0);
         Duration duration = Duration.between(time, LocalDateTime.now());
         return duration.toDays();
     }

生日

public long getBirthay(){
         LocalDateTime now = LocalDateTime.now();
         LocalDateTime time = LocalDateTime.of(2001,9,26,0,0);
         int year = now.getYear();
         if(now.getDayOfYear()>time.getDayOfYear()){
             year++;
         }
         LocalDateTime nextBirthday = LocalDateTime.of(year, 9, 26, 0, 0);
         Duration duration = Duration.between(now, nextBirthday);
         return duration.toDays();
     }

发送模板消息

这里使用了SpringBoot的定时任务需要开启定时任务 @EnableScheduling

@EnableScheduling
@SpringBootApplication
public class WechatMessageApplication {
    public static void main(String[] args) {
        SpringApplication.run(WechatMessageApplication.class, args);
    }
}

干饭人

@Scheduled(cron = "0 0 18 * * ? ")
    public void eat(){
        long now = System.currentTimeMillis();
        extracted(now);

        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 hh:mm:ss");
        String time = sdf.format(now);

        HashMap<String, Object> map = new HashMap<>();
        map.put("touser",config.getTouser());
        map.put("template_id","nkarP-ln5wzVpOyvtHrzw8dpROjl-41U8nXnfR24hAY");
        map.put("topcolor","#FF0000");


        String jsonStr = JSONUtil.toJsonStr(map);
        String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token, jsonStr);
        System.out.println(post);

    }

每日消息


  @Scheduled(cron = "0 0 7 * * ? ")
    public void morning(){
        long now = System.currentTimeMillis();
        extracted(now);

        SimpleDateFormat sdf = new SimpleDateFormat("MM月dd日 hh:mm:ss");
        String time = sdf.format(now);

        HashMap<String, Object> map = new HashMap<>();
        map.put("touser",config.getTouser());
        map.put("template_id","vXYGLvrY3vQv5Bt6ow96WyfNouwcLqtGCLGg6OwxcRc");
        map.put("topcolor","#FF0000");


        HashMap<String, Object> data = new HashMap<>();
        long birthay = getBirthay();
        JSONObject weather = getWeather();
        JSONObject message = getMessage();
        map.put("data",data);
        data.put("dateTime",new Data(time,"#173177"));
        data.put("love",new Data(String.valueOf(getLove()),"#cc33cc"));
        data.put("birthday",new Data(String.valueOf(birthay),"#91C34B"));
        data.put("wea",new Data(weather.getStr("wea"),"#40BFBF"));
        data.put("tem",new Data(weather.getStr("tem"), "#0066ff"));
        data.put("tem1",new Data(weather.getStr("tem_day"), "#ff0033"));
        data.put("tem2",new Data(weather.getStr("tem_night"), "6ECFB8"));
        data.put("airLevel",new Data(weather.getStr("air"), "#ff0000"));
        data.put("win",new Data(weather.getStr("win"), "#858AD6"));
        data.put("message",new Data(message.getStr("hitokoto"),"#8C8C8C"));

        String jsonStr = JSONUtil.toJsonStr(map);
        String post = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token, jsonStr);
        System.out.println(post);

    }

效果预览

每日消息截图

代码

兴致来了,动手就写了,代码还有很多不完善的地方,只是一个能用就行的版本,如有问题欢迎指正 Gitee:https://gitee.com/eeagle/wechat-message Github:https://github.com/JOCK-ONE/wechat-message