springboot+微信公众号 实现给女盆友定时发送消息

springboot+微信公众号 实现给女盆友定时发送消息

1.准备工作
申请微信公众号的测试平台,地址:
https://mp.weixin.qq.com/

image-20221116145129223

image-20221116145208234

image-20221116145254880

注意保存以上三个部分,第一个是公众号的ID和秘钥;第二个是扫码关注你的公众号

也就是消息的接收方;第三个是发送消息的模板,可以在这里自定义自己的发送内容,需要记住模板的ID;

申请天行数据接口
https://www.tianapi.com/

2.开始编码

天气接口的实体类

/**
 * 天气api返回信息
 */
@Data
public class WeatherInfo {

    /**
     * 地区
     */
    private String area;

    /**
     * 日期
     */
    private String date;

    /**
     * 星期
     */
    private String week;

    /**
     * 早晚天气变化
     */
    private String weather;

    /**
     * 	天气图标
     */
    private String weatherimg;

    /**
     * 	实时天气
     */
    private String real;

    /**
     * 最低温
     */
    private String lowest;

    /**
     * 	最高温
     */
    private String highest;

    /**
     * 	风向
     */
    private String wind;

    /**
     * 风向360°角度
     */
    private String winddeg;

    /**
     * 	风速,km/h
     */
    private String windspeed;

    /**
     * 风力
     */
    private String windsc;

    /**
     * 日出时间
     */
    private String sunrise;

    /**
     * 日落时间
     */
    private String sunset;

    /**
     * 月升时间
     */
    private String moonrise;

    /**
     * 月落时间
     */
    private String moondown;

    /**
     * 降雨量
     */
    private String pcpn;

    /**
     * 	降雨概率
     */
    private String pop;

    /**
     * 紫外线强度指数
     */
    private String uv_index;

    /**
     * 	能见度,单位:公里
     */
    private String vis;

    /**
     * 	相对湿度
     */
    private String humidity;

    /**
     * 	生活指数提示
     */
    private String tips;
}


发送消息的实体

/**
 * 发送消息实体
 */
@Data
public class WechatSendMsgVo implements Serializable {


    /**
     * 接收人id
     */
    private String touser;

    /**
     * 模板id
     */
    private String template_id;

    /**
     * 模板数据
     */
    private Map<String, WechatTemplateVo> data;

    /**
     * 语言类型 默认中文
     */
    private String lang = "zh_CN";
}

模板消息(可以自定义消息字体的颜色)

/**
 * 模板消息内容值
 */
@Getter
@Setter
public class WechatTemplateVo implements Serializable {

    /**
     * 值
     */
    private String value;

    /**
     * 颜色
     */
    private String color;

    public WechatTemplateVo(String value, String color){
        this.value = value;
        this.color = color;
    }

}

需要使用的接口地址的定义

/**
 * URL常量
 */
public class UrlConstant {

    //获取accessToken
    public final static String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&";

    //微信推送模板消息
    public final static String SEND_TEMPLATE = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";

    //获取关注用户信息
    public final static String GET_USER_LIST = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=";

    //彩虹屁接口
    public final static String CAI_HONG_API = "http://api.tianapi.com/caihongpi/index?key=";

    //早安接口
    public final static String MORNING_API = "http://api.tianapi.com/zaoan/index?key=";

    //天气接口
    public final static String TIAN_QI_API = "http://api.tianapi.com/tianqi/index?key=";

    //笑话接口
    public final static String JOKE_API = "http://api.tianapi.com/joke/index?key=";

    //土味情话接口
    public final static String SAY_LOVE_API = "http://api.tianapi.com/saylove/index?key=";

    //诗句-----wjg
    public final static String SCWD_API = "http://api.tianapi.com/scwd/index?key=";


}

配置文件

#公众号配置
wechat:
  appId: 公众号ID
  appSecret: 秘钥
  tempId: 模板id
  drinkTempId: 模板id
  offDutyTempId: 模板id
  shiTempId: 模板id

  myBirthday:  
  babyBirthday: 
  loveDay: 
  newYear: 


#彩虹屁接口
#天行api配置
tianapi:
  appKey: 在天行数据找到
  area: 北京

/**
 * 天行api配置
 */
@Component
@Data
public class TianApiConfig {

    @Value("${tianapi.appkey}")
    private String appKey;

    @Value("${tianapi.area}")
    private String area;
}










/**
 * 微信配置
 */
@Component
@Data
public class WechatConfig {

    @Value("${wechat.appId}")
    private String appId;

    @Value("${wechat.appSecret}")
    private String appSecret;

    @Value("${wechat.tempId}")
    private String tempId;

    @Value("${wechat.myBirthday}")
    private String myBirthday;

    @Value("${wechat.babyBirthday}")
    private String babyBirthday;

    @Value("${wechat.loveDay}")
    private String loveDay;

    @Value("${wechat.drinkTempId}")
    private String drinkTempId;

    @Value("${wechat.offDutyTempId}")
    private String offDutyTempId;


    @Value("${wechat.shiTempId}")
    private String shiTempId;


    @Value("${wechat.newYear}")
    private String newYear;
}

业务层

public interface WeiXinService {

    //获取accessToken
    String getAccessToken(String appId, String appSecret);

    //获取用户信息
    List<String> getUserList(String accessToken);

    //发送模板消息
    JSONObject sendMsg(WechatSendMsgVo sendMsgVo,String token, String openId);

    //彩虹屁信息
    String getCaiHongPiInfo(String appKey);

    //早安
    String getZaoAnInfo(String appKey);

    //天气信息
    WeatherInfo getWeatherInfo(String appKey, String city);

    //笑话
    String getJoke(String appKey);

    //土味情话
    String getSayLove(String appKey);

    //wjg--诗句
    String getScwd(String appKey) throws IllegalAccessException;
}

@Service
public class WeiXinServiceImpl implements WeiXinService {

    Logger logger = LoggerFactory.getLogger(WeiXinServiceImpl.class);

    @Override
    public String getAccessToken(String appId, String appSecret) {
        String requestUrl = UrlConstant.ACCESS_TOKEN_URL + "appid=" + appId + "&secret=" + appSecret;
        String resp = HttpUtil.get(requestUrl);
        JSONObject result = JSONUtil.parseObj(resp);
        logger.info("获取access_token:" + resp);
        String token = result.getStr("access_token");
        logger.info("token:" + token);
        return token;
    }

    @Override
    public List<String> getUserList(String accessToken) {
        String requestUrl =  UrlConstant.GET_USER_LIST+ accessToken;
        String resp = HttpUtil.get(requestUrl);
        JSONObject result = JSONUtil.parseObj(resp);
        logger.info("用户列表:" + resp);
        JSONArray openIdJsonArray = result.getJSONObject("data").getJSONArray("openid");
        List<String> openIds = JSONUtil.toList(openIdJsonArray, String.class);
        return openIds;
    }


    @Override
    public JSONObject sendMsg(WechatSendMsgVo sendMsgVo, String token, String openId) {
        //请求路径
        String requestUrl = UrlConstant.SEND_TEMPLATE  + token;
        //参数转json
        String json = JSONUtil.parseObj(sendMsgVo).toString();
        String resp = HttpUtil.createPost(requestUrl).body(json).execute().body();
        JSONObject result = JSONUtil.parseObj(resp);
        logger.info("发送消息:" + resp);
        return result;
    }

    @Override
    public String getCaiHongPiInfo(String appKey) {
        //请求地址
        String requestUrl = UrlConstant.CAI_HONG_API + appKey;
        String resp = HttpUtil.createGet(requestUrl).contentType("application/x-www-form-urlencoded;charset=UTF-8").charset("UTF-8").execute().body();
        JSONObject obj = JSONUtil.parseObj(resp);
        logger.info("obj"+obj.toString());
        JSONArray newslist = obj.getJSONArray("newslist");
        String content = ((JSONObject) newslist.get(0)).getStr("content");
        return content;
    }

    @Override
    public String getZaoAnInfo(String appKey) {
        //请求地址
        String requestUrl = UrlConstant.MORNING_API + appKey;
        String resp = HttpUtil.createGet(requestUrl).contentType("application/x-www-form-urlencoded;charset=UTF-8").charset("UTF-8").execute().body();
        JSONObject obj = JSONUtil.parseObj(resp);
        logger.info("obj"+obj.toString());
        JSONArray newslist = obj.getJSONArray("newslist");
        String content = ((JSONObject) newslist.get(0)).getStr("content");
        return content;
    }

    @Override
    public WeatherInfo getWeatherInfo(String appKey, String city) {
        //请求地址
        String requestUrl = UrlConstant.TIAN_QI_API + appKey + "&city=" + city;
        String resp = HttpUtil.createGet(requestUrl).contentType("application/x-www-form-urlencoded;charset=UTF-8").charset("UTF-8").execute().body();
        JSONObject obj = JSONUtil.parseObj(resp);
        logger.info("obj"+obj.toString());
        JSONArray newslist = obj.getJSONArray("newslist");
        List<WeatherInfo> weatherInfos = JSONUtil.toList(newslist, WeatherInfo.class);
        return weatherInfos.get(0);
    }

    @Override
    public String getJoke(String appKey) {
        //请求地址
        String requestUrl = UrlConstant.JOKE_API + appKey + "&num=1";
        String resp = HttpUtil.createGet(requestUrl).contentType("application/x-www-form-urlencoded;charset=UTF-8").charset("UTF-8").execute().body();
        JSONObject obj = JSONUtil.parseObj(resp);
        logger.info("obj"+obj.toString());
        JSONArray newslist = obj.getJSONArray("newslist");
        String content = ((JSONObject) newslist.get(0)).getStr("content");
        return content;
    }

    @Override
    public String getSayLove(String appKey) {
        //请求地址
        String requestUrl = UrlConstant.SAY_LOVE_API + appKey;
        String resp = HttpUtil.createGet(requestUrl).contentType("application/x-www-form-urlencoded;charset=UTF-8").charset("UTF-8").execute().body();
        JSONObject obj = JSONUtil.parseObj(resp);
        logger.info("obj"+obj.toString());
        JSONArray newslist = obj.getJSONArray("newslist");
        String content = ((JSONObject) newslist.get(0)).getStr("content");
        return content;
    }

    @Override
    public String getScwd(String appKey) throws IllegalAccessException {
        //请求地址
        String requestUrl = UrlConstant.SCWD_API+ appKey;
        String resp = HttpUtil.createGet(requestUrl).contentType("application/x-www-form-urlencoded;charset=UTF-8").charset("UTF-8").execute().body();
        JSONObject obj = JSONUtil.parseObj(resp);
        logger.info("obj"+obj.toString());
        JSONArray newslist = obj.getJSONArray("newslist");
        StringBuffer content = new StringBuffer();
        JSONObject toJSONObject=null;
        for (int i = 0; i <newslist.size(); i++) {
             toJSONObject = newslist.getJSONObject(i);
        }
       // String content = ((JSONObject) toJSONObject.get(0)).getStr("question");

            if(toJSONObject.getStr("question")!=null){
                content.append( toJSONObject.getStr("question")+"\n");
            }
            if(toJSONObject.get("answer_a")!=null){
                content.append(toJSONObject.get("answer_a")+"\n");
            }
            if(toJSONObject.get("answer_b")!=null){
                content.append(toJSONObject.get("answer_b")+"\n");
            }
            if(toJSONObject.get("answer_c")!=null){
                content.append(toJSONObject.get("answer_c")+"\n");
            }
            if(toJSONObject.get("answer")!=null){
                content.append(toJSONObject.get("answer")+"\n");
            }
            if(toJSONObject.get("analytic")!=null){
                content.append(toJSONObject.get("analytic")+"\n");
            }


        return content.toString();
    }


}

定时任务

/**
 * 微信定时任务
 */
@Configuration
@EnableScheduling
public class WechatTask {

    @Resource
    private WeiXinService weiXinService;

    @Resource
    private WechatConfig wechatConfig;

    @Resource
    private TianApiConfig tianApiConfig;



    //线程池
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        return taskScheduler;
    }
    /**
     * 微信模板消息推送
     * @throws ParseException
     */
    @Scheduled(cron="0 30 6 ? * * ")
    public void sendTemplateMsg() throws ParseException {
        //配置及数据
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String date = simpleDateFormat.format(new Date());
        String appId = wechatConfig.getAppId();
        String appSecret = wechatConfig.getAppSecret();
        String babyBirthday = wechatConfig.getBabyBirthday();
        String myBirthday = wechatConfig.getMyBirthday();
        String loveDay = wechatConfig.getLoveDay();
        String appKey = tianApiConfig.getAppKey();
        String area = tianApiConfig.getArea();
        String newyear=wechatConfig.getNewYear();
        //获取微信token
        String token = weiXinService.getAccessToken(appId,appSecret);
        //获取关注用户
        List<String> userList = weiXinService.getUserList(token);
        for (String openId : userList) {
            //发送消息实体
            WechatSendMsgVo sendMsgVo = new WechatSendMsgVo();
            //设置模板id
            sendMsgVo.setTemplate_id(wechatConfig.getTempId());
            //设置接收用户
            sendMsgVo.setTouser(openId);
            Map<String, WechatTemplateVo> map = new HashMap<>();
            //获取早安语句
            String zaoAnInfo = weiXinService.getZaoAnInfo(appKey);
            map.put("morning", new WechatTemplateVo("老婆大人~~~ 早安!"+zaoAnInfo,"#ff6666"));
            //获取天气
            WeatherInfo weatherInfo = weiXinService.getWeatherInfo(appKey, area);
            //日期
            map.put("date", new WechatTemplateVo(weatherInfo.getDate(),null));
            //星期
            map.put("week",new WechatTemplateVo(weatherInfo.getWeek(),null));
            //城市
            map.put("city",new WechatTemplateVo(weatherInfo.getArea(),"#9900ff"));
            //天气
            map.put("weather",new WechatTemplateVo(weatherInfo.getWeather(),"#CD96CD"));
            //最低气温
            map.put("lowest",new WechatTemplateVo(weatherInfo.getLowest(),"#A4D3EE"));
            //最高气温
            map.put("highest",new WechatTemplateVo(weatherInfo.getHighest(),"#CD3333"));


            //降水概率
            if(weatherInfo.getPop()==null){
                map.put("pop",new WechatTemplateVo(0+"%","#A4D3EE"));
            }else
            {  map.put("pop",new WechatTemplateVo(weatherInfo.getPop()+"%","#A4D3EE"));}



            //今日建议
            map.put("tips",new WechatTemplateVo(weatherInfo.getTips(),"#FF7F24"));
            //相爱天数
            int loveDays = fun(loveDay, date);
            map.put("loveDay",new WechatTemplateVo(loveDays+"","#EE6AA7"));
            //我的生日
            int myDay = fun2(myBirthday, date);
            map.put("myBirthday",new WechatTemplateVo(myDay+"","#EE6AA7"));
            //宝贝生日
            int babyDay = fun2(babyBirthday, date);
            map.put("babyBirthday",new WechatTemplateVo(babyDay+"","#EE6AA7"));
            //过年
            int newyear1 =fun2(newyear,date);
            map.put("newyear", new WechatTemplateVo(newyear1+"","#EE6AA7"));


            //彩虹屁
            String caiHongPiInfo = weiXinService.getCaiHongPiInfo(appKey);
            map.put("pipi",new WechatTemplateVo(caiHongPiInfo,"#E066FF"));

            sendMsgVo.setData(map);
            JSONObject entries = weiXinService.sendMsg(sendMsgVo,token, openId);
        }
    }

    @Scheduled(cron = "0 0 10,14,16 * * ? ")
    public void sendDrinkMsg() {
        //配置及数据
        String appId = wechatConfig.getAppId();
        String appSecret = wechatConfig.getAppSecret();
        String appKey = tianApiConfig.getAppKey();
        //获取微信token
        String token = weiXinService.getAccessToken(appId, appSecret);
        //获取关注用户
        List<String> userList = weiXinService.getUserList(token);
        for (String openId : userList) {
            //发送消息实体
            WechatSendMsgVo sendMsgVo = new WechatSendMsgVo();
            //设置喝水模板id
            sendMsgVo.setTemplate_id(wechatConfig.getDrinkTempId());
            //设置接收用户
            sendMsgVo.setTouser(openId);
            Map<String, WechatTemplateVo> map = new HashMap<>();
            //获取笑话
            String joke = weiXinService.getJoke(appKey);
            map.put("joke", new WechatTemplateVo(joke, "#ff6666"));
            sendMsgVo.setData(map);
            JSONObject entries = weiXinService.sendMsg(sendMsgVo, token, openId);
        }
    }

    @Scheduled(cron = "0 01 17 ? * *")
    public void sendoffDutyMsg(){
        String content = "卸载上班的压力,删除上班的烦恼,设置明天的斗志,下载轻松的话题,安装快乐的心情,播放灿烂的笑容。";
        //配置及数据
        String appId = wechatConfig.getAppId();
        String appSecret = wechatConfig.getAppSecret();
        String appKey = tianApiConfig.getAppKey();
        //获取微信token
        String token = weiXinService.getAccessToken(appId,appSecret);
        //获取关注用户
        List<String> userList = weiXinService.getUserList(token);
        for (String openId : userList) {
            //发送消息实体
            WechatSendMsgVo sendMsgVo = new WechatSendMsgVo();
            //设置喝水模板id
            sendMsgVo.setTemplate_id(wechatConfig.getOffDutyTempId());
            //设置接收用户
            sendMsgVo.setTouser(openId);
            Map<String, WechatTemplateVo> map = new HashMap<>();
            //获取笑话
            String sayLove = weiXinService.getSayLove(appKey);
            map.put("tips",new WechatTemplateVo(content,"#ff6666"));
            map.put("sayLove", new WechatTemplateVo(sayLove,"#E066FF"));
            sendMsgVo.setData(map);
            JSONObject entries = weiXinService.sendMsg(sendMsgVo,token, openId);
        }
    }

    @Scheduled(cron = "0 0 0/1 * * ? ")
    public void sendscwdMsg() throws IllegalAccessException {
        //配置及数据
        String appId = wechatConfig.getAppId();
        String appSecret = wechatConfig.getAppSecret();
        String appKey = tianApiConfig.getAppKey();
        //获取微信token
        String token = weiXinService.getAccessToken(appId,appSecret);
        //获取关注用户
        List<String> userList = weiXinService.getUserList(token);
        for (String openId : userList) {
            //发送消息实体
            WechatSendMsgVo sendMsgVo = new WechatSendMsgVo();
            //设置喝水模板id
            sendMsgVo.setTemplate_id(wechatConfig.getShiTempId());
            //设置接收用户
            sendMsgVo.setTouser(openId);
            Map<String, WechatTemplateVo> map = new HashMap<>();
            //获取笑话
            String shi = weiXinService.getScwd(appKey);
            map.put("shi",new WechatTemplateVo(shi,"#ff6666"));
            sendMsgVo.setData(map);
            JSONObject entries = weiXinService.sendMsg(sendMsgVo,token, openId);
        }
    }

    public int fun(String s1,String s2) throws ParseException {
        //指定格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //获取Date
        Date t1 = simpleDateFormat.parse(s1);
        Date t2 = simpleDateFormat.parse(s2);

        //获取时间戳
        Long time1 = t1.getTime();
        Long time2 = t2.getTime();
        Long num = time2- time1;
        Long day= num/24/60/60/1000;
        //返回相差天数
        return day.intValue();
    }

    public int fun2(String s1,String s2) throws  ParseException {
        //指定格式
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //获取Date
        Date t1 = simpleDateFormat.parse(s1);
        Date t2 = simpleDateFormat.parse(s2);

        //获取时间戳
        Long time1 = t1.getTime();
        Long time2 = t2.getTime();
        Long num = time1- time2;
        Long day= num/24/60/60/1000;
        //返回相差天数
        return day.intValue();
    }

}

最后打成jar包,部署到linux云服务器即可,就可以定时发送了~~~~~

3.出现的问题

在部署到云服务器上时发现同一时间只能执行一个定时任务,后排查得知,使用springboot自带的定时任务,默认是单线程的,最后我写了一个线程池,完美解决!!~~

image-20221116152333944

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值