微信公众号定时推送消息

2023-05-16

先上一波效果图!

 

 

一、微信公众号测试平台

地址: http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

需要的数据:

 

 

二、代码实现 

纪念日工具类:

package Monster.weixin.tuisong.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * @ClassName JiNianRi
 * @Description TODO
 * @Author Monster
 * @Date 2022/8/26 17:32
 */
public class JiNianRi {
    /**
     * 恋爱
     */
    static String lianAi = "2022-02-15";
    /**
     * 领证
     */
    static String linZheng = "2023-02-15";
    /**
     * 结婚
     */
    static String jieHun = "2022-07-08";
    /**
     * 生日
     */
    static String shengRi = "2023-04-19";

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 过去多少天
     * @param date
     * @return
     */
    public static int before(String date) {
        int day = 0;
        try {
            long time = System.currentTimeMillis() - simpleDateFormat.parse(date).getTime();
            day = (int) (time / 86400000L);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return day;
    }


    /**
     * 还剩多少天
     * @param date
     * @return
     */
    public static int after(String date) {
        int day = 0;
        try {
            long time = simpleDateFormat.parse(date).getTime() - System.currentTimeMillis();
            day = (int) (time / 86400000L);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return day;
    }

    public static int getJieHun() {
        return before(jieHun);
    }

    public static int getLinZheng() {
        return before(linZheng);
    }

    public static int getLianAi() {
        return before(lianAi);
    }

    public static int getShengRi(){
        return after(shengRi);
    }

    public static void main(String[] args) {
        System.out.println(getJieHun());
    }
}

请求http的帮助类:

package Monster.weixin.tuisong.util;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeaderElementIterator;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

/**
 * 请求http的帮助类
 */
public class HttpUtil {
    static final int retry = 3;
    static PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
    static ConnectionKeepAliveStrategy myStrategy;

    public HttpUtil() {
    }

    public static String doPost(String url, String data) {
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).setKeepAliveStrategy(myStrategy).setDefaultRequestConfig(RequestConfig.custom().setStaleConnectionCheckEnabled(true).build()).build();
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(20000).setConnectionRequestTimeout(10000).build();
        httpPost.setConfig(requestConfig);
        String context = "";
        if (data != null && data.length() > 0) {
            StringEntity body = new StringEntity(data, "utf-8");
            httpPost.setEntity(body);
        }

        httpPost.addHeader("Content-Type", "application/json");
        CloseableHttpResponse response = null;

        try {
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            context = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception var16) {
            var16.getStackTrace();
        } finally {
            try {
                response.close();
                httpPost.abort();
            } catch (Exception var15) {
                var15.getStackTrace();
            }

        }

        return context;
    }

    public static String getUrl(String url) throws ClientProtocolException, IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String var7;
        try {
            HttpGet httpGet = new HttpGet(url);
            httpGet.addHeader("Connection", "close");
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(18000).setConnectTimeout(5000).setConnectionRequestTimeout(18000).build();
            httpGet.setConfig(requestConfig);
            CloseableHttpResponse response1 = httpclient.execute(httpGet);

            try {
                Object entity;
                if (response1.getStatusLine().getStatusCode() != 200) {
                    if (response1.getStatusLine().getStatusCode() != 404) {
                        return null;
                    }

                    entity = "";
                    return (String)entity;
                }

                entity = response1.getEntity();
                String result = EntityUtils.toString((HttpEntity)entity);
                EntityUtils.consume((HttpEntity)entity);
                var7 = result;
            } finally {
                response1.close();
            }
        } finally {
            httpclient.close();
        }

        return var7;
    }

    static void close(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (Exception var2) {
            }
        }

    }

    static void close(InputStream inputStream) {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (Exception var2) {
                var2.printStackTrace();
            }
        }

    }

    static {
        connectionManager.setMaxTotal(1000);
        connectionManager.setDefaultMaxPerRoute(1000);
        myStrategy = new ConnectionKeepAliveStrategy() {
            public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
                BasicHeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator("Keep-Alive"));

                String param;
                String value;
                do {
                    if (!it.hasNext()) {
                        return 60000L;
                    }

                    HeaderElement he = it.nextElement();
                    param = he.getName();
                    value = he.getValue();
                } while(value == null || !param.equalsIgnoreCase("timeout"));

                return Long.parseLong(value) * 1000L;
            }
        };
    }
}

百度地图API:https://lbsyun.baidu.com/apiconsole/key#/home

package Monster.weixin.tuisong.util;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * @ClassName Tianqi
 * @Description TODO
 * @Author Monster
 * @Date 2022/8/26 16:45
 */
public class Tianqi {
    private static String ak = "你的百度地图API密钥ak";  // 百度地图API密钥ak
    private static String district_id = "440400";   //珠海行政区划代码
//    private static String district_id = "440100";   //广州行政区划代码

    public static JSONObject getNanjiTianqi() {
        String result = null;
        JSONObject today = new JSONObject();
        try {
            result = HttpUtil.getUrl("https://api.map.baidu.com/weather/v1/?district_id=" + district_id + "&data_type=all&ak=" + ak);
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getString("message").equals("success")) {
                JSONArray arr = jsonObject.getJSONObject("result").getJSONArray("forecasts");
                String location = jsonObject.getJSONObject("result").getString("location");
                String now = jsonObject.getJSONObject("result").getString("now");
                String s = (location + now).replace("}{", ",");
                String ss = arr.getJSONObject(0).toString();
                String msg = (s + ss).replace("}{", ",");
                today = JSONObject.parseObject(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return today;
    }

    public static void main(String[] args) {
        System.out.println(getNanjiTianqi());
    }
}

彩虹屁API:https://www.tianapi.com/apiview/181

package Monster.weixin.tuisong.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @ClassName CaiHongPi
 * @Description TODO
 * @Author Monster
 * @Date 2022/8/26 17:26
 */
public class CaiHongPi {
    private static String key = "你的彩虹屁key";
    private static String url = "http://api.tianapi.com/caihongpi/index?key=";
    private static List<String> jinJuList = new ArrayList<>();
    private static String name = "老婆";

    public static String getCaiHongPi() {
        //默认彩虹屁
        String str = "阳光落在屋里,爱你藏在心里";
        try {
            JSONObject jsonObject = JSONObject.parseObject(HttpUtil.getUrl(url+key).replace("XXX", name));
            if (jsonObject.getIntValue("code") == 200) {
                str = jsonObject.getJSONArray("newslist").getJSONObject(0).getString("content");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 载入金句库
     */
    static {
        InputStream inputStream = CaiHongPi.class.getClassLoader().getResourceAsStream("jinju.txt");
        try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) {
            String str = "";
            String temp = "";
            while ((temp = br.readLine()) != null) {
                if (!StringUtils.isEmpty(temp)) {
                    str = str + "\r\n" + temp;
                } else {
                    jinJuList.add(str);
                    str = "";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String getJinJu() {
        Random random = new Random();
        return jinJuList.get(random.nextInt(jinJuList.size()));
    }

    public static void main(String[] args) {
        System.out.println(getJinJu());
    }
}

消息推送:

package Monster.weixin.tuisong.util;

import com.alibaba.fastjson.JSONObject;
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;

/**
 *@ClassName Pusher
 *@Description TODO
 *@Author Monster
 *@Date 2022/8/26 16:03
 */
public class Pusher {
    /**
     * 测试号的appId和secret
     */
    private static String appId = "测试号的appId";
    private static String secret = "测试号的secret";
    //模版id
    private static String templateId = "模版id";

    public static void push(String openId){
        //1,配置
        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
        wxStorage.setAppId(appId);
        wxStorage.setSecret(secret);
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxStorage);
        //2,推送消息
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openId)
                .templateId(templateId)
                //.url("https://30paotui.com/")//点击模版消息要访问的网址
                .build();
        //3,如果是正式版发送模版消息,这里需要配置你的信息
        //        templateMessage.addData(new WxMpTemplateData("name", "value", "#FF00FF"));
        //                templateMessage.addData(new WxMpTemplateData(name2, value2, color2));
        //填写变量信息,比如天气之类的
        JSONObject todayWeather = Tianqi.getNanjiTianqi();
        templateMessage.addData(new WxMpTemplateData("riqi",todayWeather.getString("date") + "  "+ todayWeather.getString("week"),"#00BFFF"));
        templateMessage.addData(new WxMpTemplateData("chengshi",todayWeather.getString("province") + todayWeather.getString("city"),"#8E2323"));

//        templateMessage.addData(new WxMpTemplateData("tianqi",todayWeather.getString("text_day"),"#3232CD"));
        templateMessage.addData(new WxMpTemplateData("fengli",todayWeather.getString("wind_class"),"#DEB887"));
        templateMessage.addData(new WxMpTemplateData("fengxiang",todayWeather.getString("wind_dir"),"#FF7F50"));

        templateMessage.addData(new WxMpTemplateData("low",todayWeather.getString("low") + "","#173177"));
        templateMessage.addData(new WxMpTemplateData("high",todayWeather.getString("high")+ "","#FF6347" ));
        templateMessage.addData(new WxMpTemplateData("shishi",todayWeather.getString("temp"),"#7093DB"));

        templateMessage.addData(new WxMpTemplateData("lianai",JiNianRi.getLianAi()+"","#FF1493"));
        templateMessage.addData(new WxMpTemplateData("shengri",JiNianRi.getShengRi()+"","#FFA500"));
        templateMessage.addData(new WxMpTemplateData("caihongpi",CaiHongPi.getCaiHongPi(),"#FF69B4"));
        templateMessage.addData(new WxMpTemplateData("jinju",CaiHongPi.getJinJu()+"","#C71585"));
        //templateMessage.addData(new WxMpTemplateData("jiehun",JiNianRi.getJieHun()+""));
//        templateMessage.addData(new WxMpTemplateData("linzhen",JiNianRi.getLinZhen()+"","#FF6347"));
        String beizhu = "";
        if(JiNianRi.getJieHun() % 365 == 0){
            beizhu = "今天是结婚纪念日哦!";
        }
        if(JiNianRi.getLianAi() % 365 == 0){
            beizhu = "今天是恋爱纪念日哦!";
        }
        /*if(JiNianRi.getLinZhen() % 365 == 0){
            beizhu = "今天是领证纪念日哦!";
        }*/
        templateMessage.addData(new WxMpTemplateData("beizhu",beizhu,"#FF0000"));
        String tianqi = todayWeather.getString("text_day");
        if(tianqi.indexOf('晴') != -1){
            templateMessage.addData(new WxMpTemplateData("tianqi","今天" + todayWeather.getString("text_day") + ",注意防暑防晒,不要贪'凉'哦~_~","#3232CD"));
        }
        if(tianqi.indexOf('雨') != -1){
            templateMessage.addData(new WxMpTemplateData("tianqi","今天" + todayWeather.getString("text_day") + ",记得带伞哦~_~","#3232CD"));
        }
        if(tianqi.indexOf('云') != -1){
            templateMessage.addData(new WxMpTemplateData("tianqi","今天" + todayWeather.getString("text_day") + ",一缕思念化清风,丝丝凉意到身边~_~","#3232CD"));
        }

        try {
            System.out.println(templateMessage.toJson());
            System.out.println(wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage));
        } catch (Exception e) {
            System.out.println("推送失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
}

定时任务:

package Monster.weixin.tuisong.job;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import Monster.weixin.tuisong.util.Pusher;

/**
 *@ClassName JobWorker
 *@Description TODO
 *@Author Monster
 *@Date 2022/8/26 16:00
 */
@Component
public class JobWorker {
    //要推送的用户微信号
    private static String openId = "oFjg591hpCAE1o9Oc2TMsMNZo";
    private static String openId2 = "oFjgj5qf8LS9ba5LZ6Tu484XI";

    @Scheduled(cron = "0/30 * * * * ?")   // 每30秒执行一次
//    @Scheduled(cron = "0 30 7 * * ?")       //每天7:30执行一次
    public void goodMorning(){
            Pusher.push(openId);
//            Pusher.push(openId2);
    }
}

测试:

package Monster.weixin.tuisong.controller;

/**
 *@ClassName PushController
 *@Description TODO
 *@Author Monster
 *@Date 2022/8/26 15:48
 */
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import Monster.weixin.tuisong.util.Pusher;

@RestController
public class PushController {
    //要推送的用户openid
    private static String mxp = "oFjg591hpCAE1o9Oc2TMsMZo";
    private static String zyd = "odbd-66ygdSTCldsJ6s0kxXA";


    /**
     * 微信测试账号推送
     *
     */
    @GetMapping("/push")
    public void push() {
        Pusher.push(mxp);
    }

    /**
     * 微信测试账号推送
     * */
    @GetMapping("/push/zyd")
    public void pushZyd() {
        Pusher.push(zyd);
    }


    /**
     * 微信测试账号推送
     * */
    @GetMapping("/push/{id}")
    public void pushId(@PathVariable("id") String id) {
        Pusher.push(id);
    }
}

配置文件:

spring.application.name=weixin.tuisong
server.port=9999

金句:可以加些自己喜欢的,内容太长只做展示。

Positive thinking initiates more happiness!
积极的思考带来更多的快乐。

Failure is the fog through which we glimpse triumph.
透过失败的迷雾,才能瞥见胜利的光辉。

Trust is earned.
信任是要靠行动争取的。

Tears will never help.
眼泪永远没办法帮上忙。

The only way to achieve the impossible is to believe it is possible.
实现“不可能”唯一的方法,就是相信它是可能的。

We all carry something with us.
我们都在负重前行。

Don't you love New Year's Day? You get to start all over!
你不喜欢过新年吗?你能一切从头开始!

Where did the time go?
时间都到哪去了?

Everybody deserves to be loved.
每个人都值得被爱。

模板:

{{riqi.DATA}}
{{chengshi.DATA}}

天气:{{tianqi.DATA}}
风力:{{fengli.DATA}}
风向:{{fengxiang.DATA}}
最低温度:{{low.DATA}} ℃
最高温度:{{high.DATA}} ℃
当前温度:{{shishi.DATA}} ℃
今天是我们恋爱的第 {{lianai.DATA}} 天
距离你的生日还有 {{shengri.DATA}} 天

{{caihongpi.DATA}}
{{jinju.DATA}}

部署到服务器:

华为云:新人注册会有一个月的免费体验时间!
https://console.huaweicloud.com/ecm/?agencyId=0c396fbe4b0e4f3e9963caa85af706fa&region=cn-south-1&locale=zh-cn#/ecs/manager/vmListx​​​​​​​x

 步骤:

        1.将项目打包jar包

        2.将项目上传到服务器

        3.使用后台启动方式启动项目

# 后台启动并记录日志信息到logs.log文件
nouhp java -jar jar包  &> logs.log &

记得点赞和关注哦!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信公众号定时推送消息 的相关文章

  • 三、Ubuntu 18.04系统调试(命令/换源)

    目录 一 常用命令 二 Ubuntu 18 04换源 2 1便捷方法 2 2命令行方法 xff08 较为复杂 xff0c 但可查看防止后期有些错误是因为源导致的源文件 xff09 一 常用命令 目录操作 pwd 查看当前目录 cd 返回上一
  • 使用VScode远程操作虚拟机(ubuntu)

    1 VSCode安装 2 打开Ubuntu 使用ifconfig 获取系统接口 3 打开remote ssh 4 配置好相关属性 5 开启远程连接输入密码即可连接
  • 学习率(Learing Rate)的作用以及如何调整

    1 什么是学习率 学习率 Learning rate 作为监督学习以及深度学习中重要的超参 xff0c 其决定着目标函数能否收敛到局部最小值以及何时收敛到最小值 合适的学习率能够使目标函数在合适的时间内收敛到局部最小值 这里以梯度下降为例
  • Pytorch 中net.train() 和 net.eval()的作用和如何使用?

    一般在训练模型的代码段加入 xff1a model train 在测试模型时候加入 xff1a model eval 同时发现 xff0c 如果不写这两个程序也可以运行 xff0c 这是因为这两个方法是针对在网络训练和测试时采用不同方式的情
  • Qt 子窗口内嵌到父窗口中

    有时需要把一个子窗口内嵌进入父窗口当中 我们可以这样做 1 新建一个QWidget 或者QDialog的子类 ClassA xff08 父类为ClassB xff09 2 在新建类的构造函数中添加设置窗口属性 setWindowFlags
  • 用Cmake 编译OpenCV常见的错误

    minGW32 make遇到的错误1 xff1a 37 Linking CXX shared library bin libopencv core341 dll CMakeFiles opencv core dir objects a me
  • 卷积 反卷积 上采样 下采样 区别

    1 卷积 就是利用卷积核 步长前进 卷积整个图片 2 反卷积 反卷积的具体操作 原图输入尺寸为 1 xff0c 3 xff0c 3 xff0c 3 对应 batch size channels width height 反卷积tconv 6
  • Go语言操作数据库MySQL

    连接 Go语言中的database sql包提供了保证SQL或类SQL数据库的泛用接口 xff0c 并不提供具体的数据库驱动 使用database sql包时必须注入 xff08 至少 xff09 一个数据库驱动 我们常用的数据库基本上都有
  • 解决Git请求错误问题

    git clone gits github com Cloning into 39 FdogSerialize 39 git 39 remote gits 39 is not a git command See 39 git help 39
  • Reactor 模式

    Reactor 翻译过来的意思是 反应堆 xff0c 可能大家会联想到物理学里的核反应堆 xff0c 实际上并不是的这个意思 这里的反应指的是 对事件反应 xff0c 也就是来了一个事件 xff0c Reactor 就有相对应的反应 响应
  • MATLAB画图调整分辨率

    问题 xff1a 经常需要用MATLAB画图 xff0c 但是保存之后分辨率不高 xff0c 特别是需要放大的情况下 解决 xff1a 对于下面这种画出的图形 选择 文件 61 gt 导出设置 61 gt 渲染 61 gt 分辨率 选择60
  • C语言中常见的逻辑错误

    常见错误一 xff1a 61 和 61 61 混在一起 int main int ret if ret 61 1 return 0 结果 xff1a 变量被错误赋值 xff0c 逻辑判断错误 错误二 xff1a 定义较大的全局变量造成 编译
  • Qt中常见的位置和尺寸

    QPoint类的介绍 QPoint 类封装了我们常用用到的坐标点 x y 常用的 API 如下 构造函数 构造一个坐标原点 即 0 0 QPoint QPoint 参数为 x轴坐标 y轴坐标 QPoint QPoint int xpos i
  • 关于QT线程运用的三种方式

    QThread 类函数 QThread 类常用 API 构造函数 QThread QThread QObject parent 61 Q NULLPTR 判断线程中的任务是不是处理完毕了 bool QThread isFinished co
  • 安装Ubuntu22.04+nvidia驱动+CUDA-11.7+GRPMACS patch PLUMED

    首先是Ubuntu22 4的安装 Ubuntu系统一般直接可以使用RUFUS软件制作U盘启动项 xff0c 再依照顺序安装Ubuntu系统 xff0c 这里不赘述 CUDA 11 7 span class token function su
  • Linux部署Nexus私服

    这篇文章主要介绍了Linux搭建自己Nexus私服的实现方法 xff0c 文中通过示例代码介绍的非常详细 xff0c 对大家的学习或者工作具有一定的参考学习价值 一 Nexus介绍 对maven来说仓库分为两类 xff1a 本地仓库和远程仓
  • 元学习和机器学习的对比

    目录 引言机器学习元学习什么是元学习元学习的流程学习学习函数评价学习函数好坏迭代优化 整体框架 元学习和机器学习的对比定义的区别数据集划分的区别损失函数的区别两者之间的共通之处 总结 引言 本篇博客是李宏毅老师元学习课程的笔记 深度学习大部
  • 如何使用C++实现10个数的冒泡排序

    96 96 冒泡排序是一种计算机科学领域的较简单的排序算法 xff0c 是一种简单的适合初学者学习的算法 上图为冒泡排序简单的图片理解 xff0c 将第一个数依次与后面的数进行比较 将数值大的数沉到底部或将数值小的数浮到顶部 简称 大数沉淀
  • 通过Cerebro访问Elasticsearch

    本文以阿里云Elasticsearch为例 xff0c 介绍通过Cerebro访问Elasticsearch的方法 阿里云Elasticsearch兼容开源Elasticsearch的功能 xff0c 以及Security Machine
  • 手把手教您完成Elasticsearch数据迁移

    您可以通过Logstash reindex和OSS等多种方式在Elasticsearch之间迁移数据 本文以阿里云Elasticsearch xff08 简称ES xff09 为例 xff0c 介绍阿里云Elasticsearch间数据迁移

随机推荐