微信公众号每天定时自动推送消息给女友

692 阅读4分钟

a.png

因为看到了别人秀的所以也想弄弄:

微信图片_20220930173106.jpg

巴拉巴拉......看着还蛮有意思的,走我们也去实现一个。

实现前提准备,资料我们没有企业信息,目前呢我们就只能用测试的了,

通过mp.weixin.qq.com/debug/cgi-b… 这个地址进行申请到appid和appsecret

image.png

微信关注一下:这里是为了方便我们拿的女朋友的微信号的openID

image.png

然后新建消息推送模板

image.png

还有一个准备天气预报的第三方接口,我用到的是天行数据的还用到他的随机温馨语 一个是彩虹屁接口:www.tianapi.com/apiview/181 一个是天气预报接口:www.tianapi.com/apiview/72 我是准备撸完他这个免费的换别的,哈哈哈哈,准备差不多了,

我们开始码代码了。

模板实例:

{{date.DATA}}{{remark.DATA}} 
所在城市:{{city.DATA}} 
今天天气:{{weather.DATA}} 
气温变化:{{minTemperature.DATA}}~{{maxTemperature.DATA}} 
今天建议:{{tips.DATA}} 

今天是我们相恋De第{{loveDays.DATA}}天 
相识在{{acquaintance.DATA}} 
相见在{{meet.DATA}} 
距离宝宝的生日还有{{birthDay.DATA}} 

{{rainbow.DATA}}

我们开始创建一个SpringBoot项目

使用到的依赖pom:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.83</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.8</version>
</dependency>
<dependency>
    <groupId>cn.6tail</groupId>
    <artifactId>lunar</artifactId>
    <version>1.2.24</version>
</dependency>

创建一个application.yaml写好 配置信息:

server:
  port: 9027
wechat:
   # 公众号AppID
  appId: 
  # 公众号密钥
  secret: 
  # 微信openID
  openId: 
  # 公众号模板ID
  templateId: 
  # 颜色
  topColor:
  # 天气接口
  weatherApi: http://api.tianapi.com/tianqi/index
  # 彩虹屁接口
  rainbowApi: http://api.tianapi.com/caihongpi/index
  # 天行数据密钥
  rainbowKey: 
  # 生日(我用的农历生日 月份和日期)
  girlBirthDay: 9-27
  # 相恋时间
  loveDays: 2022-08-28
  # 获取微信token
  accessUrl: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential
  # 推送消息接口
  sendUrl: https://api.weixin.qq.com/cgi-bin/message/template/send
  # 相识时间
  acquaintance: 2022828号
  # 相见时间
  meet: 202296号晚上

数据工具类 DataUtils

/**
 *
 */
public class DataUtils {

    /**
     * 获取 Weather 信息
     *
     * @param
     * @return
     */
    public static Weather getWeather(String url) {
        String result = HttpUtil.get(url);
        JSONObject responseResult = JSONObject.parseObject(result);
        JSONObject jsonObject = responseResult.getJSONArray("newslist").getJSONObject(0);
        return jsonObject.toJavaObject(Weather.class);
    }

    /**
     * 获取 RainbowPi 信息
     *
     * @param
     * @return
     */
    public static String getRainbow(String url) {
        String result = HttpUtil.get(url);
        JSONObject responseResult = JSONObject.parseObject(result);
        JSONObject jsonObject = responseResult.getJSONArray("newslist").getJSONObject(0);
        return jsonObject.getString("content");
    }

    /**
     * 计算生日天数 days
     *
     * @return
     */
    public static int getBirthDays(String birthday) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cToday = Calendar.getInstance(); // 存今天
        Calendar cBirth = Calendar.getInstance(); // 存生日
        int days = 0;
        try {
            cBirth.setTime(dateFormat.parse(birthday)); // 设置生日
            cBirth.set(Calendar.YEAR, cToday.get(Calendar.YEAR)); // 修改为本年
            if (cBirth.get(Calendar.DAY_OF_YEAR) < cToday.get(Calendar.DAY_OF_YEAR)) {
                // 生日已经过了,要算明年的了
                days = (cToday.getActualMaximum(Calendar.DAY_OF_YEAR) - cToday.get(Calendar.DAY_OF_YEAR)) + cBirth.get(Calendar.DAY_OF_YEAR);
            } else {
                // 生日还没过
                days = cBirth.get(Calendar.DAY_OF_YEAR) - cToday.get(Calendar.DAY_OF_YEAR);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return days;
    }


    /**
     * 计算恋爱天数 days
     *
     * @return
     */
    public static int getLoveDays(String loveday) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        int days = 0;
        try {
            long time = System.currentTimeMillis() - dateFormat.parse(loveday).getTime();
            days = (int) (time / (24 * 60 * 60 * 1000)) + 1;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return days;
    }


    /**
     * 获取微信token
     *
     * @param appId
     * @param secret
     * @return
     */
    public static String getAccessToken(String appId, String secret) {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + secret;
        String result = HttpUtil.get(url);
        JSONObject jsonObject = JSONObject.parseObject(result);
        String accessToken = jsonObject.getString("access_token");
        if(Objects.nonNull(accessToken)){
            return accessToken;
        }
        return jsonObject.getString("errmsg");
    }


    /**
     * 获取农历的今天距离生日还有多久
     * @param month 农历月份
     * @param day 农历第几天
     * @return
     */
    public static int getBirthDays(Integer month, Integer day) {
        Calendar calendar = Calendar.getInstance();
        int i = calendar.get(Calendar.MONTH) + 1;
        int year = 0;
        if (month < i) {
            year = calendar.get(Calendar.YEAR)+1;
        }else{
            year = calendar.get(Calendar.YEAR);
        }
        Lunar lunarDate = new Lunar(year, month, day);
        Date date = lunarDate.getSolar().getCalendar().getTime();
        long between = DateUtil.between(new Date(), date, DateUnit.DAY);
        int days = Integer.parseInt(String.valueOf(between));
        return days;
    }
}

结果级 ResultVo


/**
 * @author John
 * @since 2022/9/28 10:08
 **/
public class ResultVo {

    private String touser;
    private String template_id;
    private String topcolor;
    private HashMap<String, DataItem> data;

    private ResultVo(String _touser, String _template_id, String _topcolor, HashMap<String, DataItem> _data) {
        this.touser = _touser;
        this.template_id = _template_id;
        this.topcolor = _topcolor;
        this.data = _data;
    }

    public String getTouser() {
        return touser;
    }

    public String getTemplate_id() {
        return template_id;
    }

    public String getTopcolor() {
        return topcolor;
    }

    public HashMap<String, DataItem> getData() {
        return data;
    }

    public static ResultVo initializeResultVo(String _touser, String _template_id, String _topcolor){
        return new ResultVo(_touser,_template_id,_topcolor,null);
    }

    public static ResultVo initializeResultVo(String _touser, String _template_id, String _topcolor,HashMap<String, DataItem> _data){
        return new ResultVo(_touser,_template_id,_topcolor,_data);
    }

    public ResultVo setAttribute(String key, DataItem item){
        if(this.data==null)this.data = new HashMap<String,DataItem>();
        this.data.put(key,item);
        return this;
    }
}

控制器:

@Slf4j
@Controller
public class WeChatController {

    @Resource
    RestTemplate restTemplate;
    @Autowired
    WeChatConfigure weChatConfigure;
 
    /**
     * {{date.DATA}}
     * {{remark.DATA}}
     * 所在城市:{{city.DATA}}
     * 今日天气:{{weather.DATA}}
     * 气温变化:{{min_temperature.DATA}} ~ {{max_temperature.DATA}}
     * 今日建议:{{tips.DATA}}
     * 今天是我们恋爱的第 {{love_days.DATA}} 天
     * 距离xx生日还有 {{girl_birthday.DATA}} 天
     * 距离xx生日还有 {{boy_birthday.DATA}} 天
     * {{rainbow.DATA}}
     */
    public void push(){
        ResultVo resultVo = ResultVo.initializeResultVo(weChatConfigure.getOpenId(),weChatConfigure.getTemplateId(),weChatConfigure.getTopColor());
        //1.设置城市与天气信息
        Weather weather = DataUtils.getWeather(weChatConfigure.getWeatherApi()+"?key="+weChatConfigure.getRainbowKey()+"&city=深圳");
        resultVo.setAttribute("date",new DataItem(weather.getDate() + " " + weather.getWeek(),"#00BFFF"));
        resultVo.setAttribute("city",new DataItem(weather.getArea(),null));
        resultVo.setAttribute("weather",new DataItem(weather.getWeather(),"#1f95c5"));
        resultVo.setAttribute("minTemperature",new DataItem(weather.getLowest(),"#0ace3c"));//最低温度
        resultVo.setAttribute("maxTemperature",new DataItem(weather.getHighest(),"#dc1010"));//最高温度
        resultVo.setAttribute("tips",new DataItem(weather.getTips(),null));
        //2.设置日期相关
        int love_days = DataUtils.getLoveDays(weChatConfigure.getLoveDays());
        String[] dateBirth = weChatConfigure.getGirlBirthDay().split("-");
        Integer month = Integer.valueOf(dateBirth[0]);
        Integer day = Integer.valueOf(dateBirth[1]);
        String girl_birthday = CalendarUtil.getLunarBirthDays(month,day);
        resultVo.setAttribute("loveDays",new DataItem(love_days+"","#FFA500")); //相恋
        resultVo.setAttribute("birthDay",new DataItem(girl_birthday+"","#FFA500")); //生日
        resultVo.setAttribute("meet",new DataItem(weChatConfigure.getMeet()+"","#FFA500")); //相见
        resultVo.setAttribute("acquaintance",new DataItem(weChatConfigure.getAcquaintance()+"","#FFA500")); //相识
//        resultVo.setAttribute("boy_birthday",new DataItem(boy_birthday+"","#FFA500"));
        //3.设置彩虹屁
        String rainbow =  DataUtils.getRainbow(weChatConfigure.getRainbowApi()+"?key="+weChatConfigure.getRainbowKey());
        resultVo.setAttribute("rainbow",new DataItem(rainbow,"#FF69B4"));
        //4.其他
        String remark = "❤";
        if(DataUtils.getBirthDays(weChatConfigure.getLoveDays()) == 0){
            remark = "今天是恋爱周年纪念日!永远爱你~";
        }
//        else if(girl_birthday == 0){
//            remark = "今天是宝宝的生日!生日快乐哟~";
//        }
//        else if(boy_birthday == 0){
//            remark = "今天是xx的生日!别忘了好好爱他~";
//        }
        resultVo.setAttribute("remark",new DataItem(remark,"#FF1493"));
        //5.发送请求,推送消息
        log.info("appId:{},secret:{}",weChatConfigure.getAppId(),weChatConfigure.getSecret());
        String accessToken = DataUtils.getAccessToken(weChatConfigure.getAppId(), weChatConfigure.getSecret());
        log.info("accessToken:{}",accessToken);
        String responseStr = restTemplate.postForObject(weChatConfigure.getSendUrl()+"?access_token="+accessToken, resultVo, String.class);
        printPushLog(responseStr);
    }
 
    /**
     * 打印 response log
     * @param responseStr
     */
    private static void printPushLog(String responseStr){
        JSONObject jsonObject = JSONObject.parseObject(responseStr);
        String msgCode = jsonObject.getString("errcode");
        String msgContent = jsonObject.getString("errmsg");
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("[ " + dateFormat.format(new Date()) + " ] : messageCode=" + msgCode + ",messageContent=" + msgContent);
    }


}

RestTemplateConfig配置类

/**
 * @author John
 * @since 2022/9/28 17:57
 **/
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        return builder.build();
    }
}

WeChatConfigure 读取yaml文件配置

@Data
@Component
@ConfigurationProperties(prefix = "wechat")
public class WeChatConfigure {
    /**
     * 微信appID
     */
    private String appId;
    /**
     * 微信密钥
     */
    private String secret;
    /**
     * 微信唯一标识
     */
    private String openId;
    /**
     * 模板id
     */
    private String templateId;
    /**
     * 颜色
     */
    private String topColor;
    /**
     * 天气API
     */
    private String weatherApi;
    /**
     * 言语api
     */
    private String rainbowApi;
    /**
     * 言语KEY
     */
    private String rainbowKey;
    /**
     * 女孩的生日
     */
    private String girlBirthDay;
    /**
     * 相恋的时间
     */
    private String loveDays;
    /**
     * token
     */
    private String accessUrl;
    /**
     * 推送消息
     */
    private String sendUrl;
    /**
     * 相识日子

*/
    private String acquaintance;
    /**
     * 相见日子
     */
    private String meet;
}

天气封装实体:(看自己需求需要哪些就接收哪些)

/**
 * @author John
 * @since 2022/9/28 10:36
 **/
@Data
public class Weather {

    private String date;

    private String week;

    private String area;

    private String weather;

    private String tips;

    private String lowest;

    private String highest;
}

DataItem实体封装:

//单条数据Item封装
public class DataItem {
 
    private String value;
    private String color;
 
    public DataItem(String _value, String _color) {
        this.value = _value;
        this.color = _color;
    }
 
    public String getValue() {
        return value;
    }
 
    public void setValue(String value) {
        this.value = value;
    }
 
    public String getColor() {
        return color;
    }
 
    public void setColor(String color) {
        this.color = color;
    }
}

消息定时推送器:

@Slf4j
@Component
public class PushTask {

    @Autowired
    WeChatController weChatController;

    //每日 早上9点 定时推送
    @Scheduled(cron = "0 0 9 * * ?")
    public void scheduledPush() {
        log.info("开始执行了===>推送消息");
        weChatController.push();
        log.info("结束执行了===>推送消息");
    }
}

简单总结一下:写的有点low,将就一下各位大佬根据自己想要更改就好 最最最重要的是 本身就是写着玩,图一个乐子,就不花太多时间啦,写好了,发布服务器运行起来就好或者本地 这本身就是看个人的取舍。

源代码地址: Gitee:gitee.com/zhyjohn_adm…