近期网上又出现一股给女朋友做微信公众号推送的潮流,那么别人有的我女朋友也得有不是O.o 简单研究了一下做微信公众号推送的原理,简单来说就是后台服务器做个定时任务,然后定时调用微信公众平台提供的Web API接口(HTTP),发送模板消息(json数据)即可。技术栈及开发流程总结如下:

php微信公众号消息推送(微信公众号每日自动给女朋友推送问候)(1)

1.配置微信公众平台测试号

点击打开微信公众平台链接( 微信公众平台 ),注册申请微信公众测试号。测试号可以体验微信公众平台所有的功能API接口,我们这里主要使用的是 模板消息推送API。 但测试号的局限性是只能使用默认的公众号名称且功能随时可能被下架 有条件的可以申请企业订阅号/服务号(个人认证的订阅号不具有 模板消息推送API 权限,只有企业可以认证服务号)。测试号配置中比较重要的是以下几部分(参考开发文档 模板消息 | 微信开放文档 (qq.com) ):

php微信公众号消息推送(微信公众号每日自动给女朋友推送问候)(2)

php微信公众号消息推送(微信公众号每日自动给女朋友推送问候)(3)

php微信公众号消息推送(微信公众号每日自动给女朋友推送问候)(4)

//JSON数据传输格式示例 { "touser":"OpenID", "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY", "topcolor":"#FF0000", "data":{ "date": { "value":"2022-09-04 星期日", "color":"#173177" }, "remark":{ "value":"♥", "color":"#173177" }, "city": { "value":"北京", "color":"#173177" }, "weather": { "value":"多云转晴", "color":"#173177" }, ... } }

2.数据接口封装

在消息推送模板中,我们需要用到的数据包括气候(天气、温度、城市等)、恋爱天数、生日倒计时天数、彩虹屁语句这几部分,数据的获取方式如下:

2.1 天行数据接口封装

天行接口数据的获取也是通过Web API 发送请求的方式在response中来获取数据(RestTemplate),接口文档如下:

public class DataUtils { /** * 获取 Weather 信息 * @param restTemplate * @return */ public static Weather getWeather(RestTemplate restTemplate){ String responseJson = restTemplate.getForObject(WeChatConfigure.Weather_API, String.class); JSONObject responseResult = JSONObject.parseObject(responseJson); JSONObject jsonObject = responseResult.getJSONArray("newslist").getJSONObject(0); return jsonObject.toJavaObject(Weather.class); } /** * 获取 RainbowPi 信息 * @param restTemplate * @return */ public static String getRainbow(RestTemplate restTemplate){ String responseJson = restTemplate.getForObject(WeChatConfigure.Rainbow_API, String.class); JSONObject responseResult = JSONObject.parseObject(responseJson); JSONObject jsonObject = responseResult.getJSONArray("newslist").getJSONObject(0); return jsonObject.getString("content"); } }

2.2 日期计算工具封装

计算生日倒计时和计算恋爱天数的逻辑不同。计算生日倒计时需要判断生日日期是否已过,而计算恋爱天数相对简单,直接统计时间即可。

public class DataUtils { /** * 计算生日天数 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)); } catch (ParseException e) { e.printStackTrace(); } return days; } }

3.封装推送逻辑3.1 封装配置类

@Component public class WeChatConfigure { public static String Access_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}"; public static String Send_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}"; public static String App_ID; @Value("${WeChat.AppID}") public void setAppID(String AppID) { App_ID = AppID; } public static String App_Secret; @Value("${WeChat.AppSecret}") public void setAppSecret(String AppSecret) { App_Secret = AppSecret; } public static String Open_ID; @Value("${WeChat.OpenID}") public void setOpenID(String OpenID) { Open_ID = OpenID; } public static String Template_ID; @Value("${WeChat.TemplateID}") public void setTemplateID(String TemplateID) { Template_ID = TemplateID; } public static String Top_Color; @Value("${WeChat.TopColor}") public void setTopColor(String TopColor) { Top_Color = TopColor; } public static String Weather_API; @Value("${WeChat.WeatherAPI}") public void setWeatherAPI(String WeatherAPI) { Weather_API = WeatherAPI; } public static String Rainbow_API; @Value("${WeChat.RainbowAPI}") public void setRainbowAPI(String RainbowAPI) { Rainbow_API = RainbowAPI; } public static String Boy_Birthday; @Value("${WeChat.BoyBirthday}") public void setBoyBirthday(String BoyBirthday) { Boy_Birthday = BoyBirthday; } public static String Girl_Birthday; @Value("${WeChat.GirlBirthday}") public void setGirlBirthday(String GirlBirthday) { Girl_Birthday = GirlBirthday; } public static String Love_Day; @Value("${WeChat.LoveDay}") public void setLoveDay(String LoveDay) { Love_Day = LoveDay; } }

3.2 封装实体类

//单条数据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; } } //发送数据集result封装 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; } }

3.3 推送逻辑Controller实现

@Controller public class WeChatController { @Autowired RestTemplate restTemplate; /** * { <!-- -->{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.Open_ID,WeChatConfigure.Template_ID,WeChatConfigure.Top_Color); //1.设置城市与天气信息 Weather weather = DataUtils.getWeather(restTemplate); 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("min_temperature",new DataItem(weather.getLowest(),"#0ace3c")); resultVo.setAttribute("max_temperature",new DataItem(weather.getHighest(),"#dc1010")); resultVo.setAttribute("tips",new DataItem(weather.getTips(),null)); //2.设置日期相关 int love_days = DataUtils.getLoveDays(WeChatConfigure.Love_Day); int girl_birthday = DataUtils.getBirthDays(WeChatConfigure.Girl_Birthday); int boy_birthday = DataUtils.getBirthDays(WeChatConfigure.Boy_Birthday); resultVo.setAttribute("love_days",new DataItem(love_days "","#FFA500")); resultVo.setAttribute("girl_birthday",new DataItem(girl_birthday "","#FFA500")); resultVo.setAttribute("boy_birthday",new DataItem(boy_birthday "","#FFA500")); //3.设置彩虹屁 String rainbow = DataUtils.getRainbow(restTemplate); resultVo.setAttribute("rainbow",new DataItem(rainbow,"#FF69B4")); //4.其他 String remark = "❤"; if(DataUtils.getBirthDays(WeChatConfigure.Love_Day) == 0){ remark = "今天是恋爱周年纪念日!永远爱你~"; }else if(girl_birthday == 0){ remark = "今天是傻元宝贝的生日!生日快乐哟~"; }else if(boy_birthday == 0){ remark = "今天是傻鑫的生日!别忘了好好爱他~"; } resultVo.setAttribute("remark",new DataItem(remark,"#FF1493")); //5.发送请求,推送消息 String responseStr = restTemplate.postForObject(WeChatConfigure.Send_URL, resultVo, String.class, DataUtils.getAccessToken(restTemplate)); printPushLog(responseStr); } /** * 打印 response log * @param responseStr */ private 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); } }

4.封装定时任务

@Component public class PushTask { @Autowired WeChatController weChatController; //每日 早上9点 定时推送 @Scheduled(cron = "0 0 9 * * ?") public void scheduledPush(){ weChatController.push(); } }

5.打包部署腾讯云

项目打包成 jar 包后传到腾讯云服务器上,直接运行即可实现每日推送。

#nohup指令 后台启动jar包,日志信息输出到log.file文件 nohup java -jar xxx-0.0.1-SNAPSHOT.jar > log.file 2>&1 &

来源:https://blog.csdn.net/qq_40772692/article/details/126693268

,