微信公众号完成自动回复,自定义菜单

news2024/11/13 10:30:10

微信公众号完成自动回复,自定义菜单

  • 首先要获取到微信公众号的开发者权限,这一步省略,可以自行百度

  • 微信公众号对接自己的服务器

 首先第一步需要有自己的服务器和固定的ip,

其中,80/443端口需要有其中一个,

80端口对应http服务,

443端口对应https服务。

然后需要在自己的服务器上编写服务端代码,对应微信公众号的token和秘钥,在微信公众号上填写相应地址,调试通过后对接完成。

对接完成后,用户向龚总好发送的消息会被转发至服务端,你可以根据用户发送的消息做对应的处理

具体操作流程如下:

点击基本服务,然后点击修改配置。

填写自己的服务端地址和接口,填写对应的token和秘钥,服务端必须和客户端保持一致,然后点击提交,成功的话页面会有提示,然后返回上一层页面点击启用即可。

需要注意的是,启用后我们之前在公众号上的菜单将会失效,需要我们用api的方式重新提交一次,所以说,有做过菜单的需要注意,下面是创建菜单的步骤

首先我们需要通过接口获取token

   /*
获取token
 */
    @RequestMapping("/getToken")
    public String getToken() {

        String appId = "xxxxxxxxx"; // 替换为你的AppID
        String appSecret = "xxxxxxxx"; // 替换为你的AppSecret

        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);

        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity, "UTF-8");
                JSONObject jsonObject = new JSONObject(result);

                // 提取access_token
                String accessToken = jsonObject.getString("access_token");
                token = accessToken;

                // 输出access_token
                System.out.println("Access Token: " + accessToken);
                // 在这里你可以解析返回的JSON字符串以获取access_token
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        return null;

    }

然后获取之前的菜单的结构json,有菜单的在此之前请不要启用服务器配置

/*
获取自定义菜单
 */
@RequestMapping("/getMenu")
public String getMenu() {

    String token = "xxxxxxxxxxxxxxxxxxx"; // 替换为你的AppSecret

    String url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=" + token;

    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet(url);

    try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            String result = EntityUtils.toString(entity, "UTF-8");
            JSONObject jsonObject = new JSONObject(result);

            // 提取access_token


            // 输出access_token
            System.out.println("menu: " + jsonObject);
            // 在这里你可以解析返回的JSON字符串以获取access_token
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return null;
}

通过此程序你可以获取自己的菜单结构,如下所示

{ 

   "is_menu_open": 1, 

   "selfmenu_info": { 

       "button": [ 

           { 

               "type": "click", 

               "name": "今日歌曲", 

               "key": "V1001_TODAY_MUSIC"

           }, 

           { 

               "name": "菜单", 

               "sub_button": { 

                   "list": [ 

                       { 

                           "type": "view", 

                           "name": "搜索", 

                           "url": "http://www.soso.com/"

                       }, 

                       { 

                           "type": "view", 

                           "name": "视频", 

                           "url": "http://v.qq.com/"

                       }, 

                       { 

                           "type": "click", 

                           "name": "赞一下我们", 

                           "key": "V1001_GOOD"

                       }

                   ]

               }

           }

       ]

   }}

然后你只需将此json通过创建接口重新创建即可,我这里都用的java。需要在启用服务器后进行配置

 String url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token;

    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost(url);

    // 设置请求体参数为您提供的 JSON 数据
    String jsonBody = 你的菜单结构


    StringEntity requestEntity = new StringEntity(jsonBody, ContentType.APPLICATION_JSON);
    httpPost.setEntity(requestEntity);

    // 设置请求头 Content-Type 为 application/json
    httpPost.setHeader("Content-Type", "application/json");

    try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            String result = EntityUtils.toString(entity, "UTF-8");
            JSONObject jsonObject = new JSONObject(result);

            // 提取access_token

            // 输出access_token
            System.out.println("menu: " + jsonObject);
            // 在这里您可以解析返回的JSON字符串以获取access_token
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            httpClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后就是自动回复,我们要编写代码接收到用户向公众号发送的消息,然后返回我们想要回复的消息即可:此接口必须是你对接微信服务器所填写的接口,否则无法接收:如下

    @RequestMapping("/wx")
    public @ResponseBody
    String wxGZHGetMsg(HttpServletRequest request) {
        System.out.println(request.toString());
        try {
            // 获取请求体内容
            String xmlContent = getRequestBody(request);

            // 使用 Jsoup 解析 XML 内容
            Document document = Jsoup.parse(xmlContent, "", org.jsoup.parser.Parser.xmlParser());

            // 修改 XML 内容
//            modifyXmlimg(document);
            Elements eventElements = document.select("Event");
            if (!eventElements.isEmpty()) {
                String s = modifuxmlMenu(document);

                return s;

            } else {


                return modifyXmlContent(document);
            }


            // 将修改后的 XML 内容转换为字符串

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private String getRequestBody(HttpServletRequest request) throws IOException {// 获取请求体内容
        StringBuilder requestBody = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            String line;
            while ((line = reader.readLine()) != null) {
                requestBody.append(line);
            }
        }
        return requestBody.toString();
    }

由于微信发送的信息室xml格式的,所以我们需要进行一定的处理,我这里使用的是jsonp包所带的方法进行处理的,使用jsonp需要在

Pom文件中引入相关的依赖,如下

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.14.3</version>
</dependency>

此外,这里回复处理xml文件的过程需要大家自己根据情况进行编写,可以配合数据库进行相应的逻辑回答,这里给出xml文件的格式,微信文档中也可以查看到

这是接收到的

<xml>

  <ToUserName><![CDATA[toUser]]></ToUserName>

  <FromUserName><![CDATA[fromUser]]></FromUserName>

  <CreateTime>1348831860</CreateTime>

  <MsgType><![CDATA[text]]></MsgType>

  <Content><![CDATA[this is a test]]></Content>

  <MsgId>1234567890123456</MsgId>

  <MsgDataId>xxxx</MsgDataId>

  <Idx>xxxx</Idx></xml>

回复的话也基本相同,

回复文本消息

<xml>

  <ToUserName><![CDATA[toUser]]></ToUserName>

  <FromUserName><![CDATA[fromUser]]></FromUserName>

  <CreateTime>12345678</CreateTime>

  <MsgType><![CDATA[text]]></MsgType>

  <Content><![CDATA[你好]]></Content></xml>

回复图片消息

<xml>

  <ToUserName><![CDATA[toUser]]></ToUserName>

  <FromUserName><![CDATA[fromUser]]></FromUserName>

  <CreateTime>12345678</CreateTime>

  <MsgType><![CDATA[image]]></MsgType>

  <Image>

    <MediaId><![CDATA[media_id]]></MediaId>

  </Image></xml>

这里需要注意的是,回复消息的时候需要把ToUserNameFromUserName

的value值进行互换,具体过程大家可以自行根据需求编写。

此外,为了区分不同用户的提问状态,我这里使用了Redis进行保存用户提问数据的操作,并且设置1小时超时 ,在用户提问的时候,把用户的id存入Redis,由此可以分辨出每一位用户的问题,做出相对应的回答。

Redis可从网上自行下载安装,在java中使用可以通过pom文件引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

然后编写配置类

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        // 使用GenericJackson2JsonRedisSerializer来序列化和反序列化redis的value值
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}

这里我们通过 bean的方式注入,可以通过@Autowired注入的方式在程序中进行调用,Redis在springboot中的调用方式非常简单,可以使用sava ,find,delete 方式进行存储和删除修改

这里的sava方式我进行了保存时间的设定,timeou是时间参数,

TimeUnit 是时间单位(时/分/秒/毫秒),最小单位为毫秒,超时后会自动删除数据。

public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void save(String key, Object value, long timeout, TimeUnit unit) {
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    public Object find(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    public void delete(String key) {
        redisTemplate.delete(key);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1704179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《云原生安全攻防》--快速识别虚拟机、Docker和K8s集群环境

今天我们将一起学习一个非常实用的技巧&#xff0c;快速识别云原生环境。 对于攻击者而言&#xff0c;随着云原生应用普及&#xff0c;当攻击者获得一个shell权限时&#xff0c;那么这个shell可能处于虚拟主机里&#xff0c;也有可能在一个Docker环境里&#xff0c;或者在K8s集…

Diffusion Model 和 Stable Diffusion 详解

文章目录 Diffusion Model 基础生成模型DDPM概述向前扩散过程前向扩散的逐步过程前向扩散的整体过程 反向去噪过程网络结构训练和推理过程训练过程推理过程优化目标 详细数学推导数学基础向前扩散过程反向去噪过程 Stable Diffusion组成结构运行流程网络结构VAE 模型文本编码器…

数据恢复的救星!快速恢复手机数据的2个秘籍!

当我们的照片、视频、联系人、短信和应用程序丢失时&#xff0c;许多人可能会感到束手无策&#xff0c;无论是珍贵的照片、重要的工作文件还是个人的联系方式&#xff0c;一旦丢失&#xff0c;都可能带来极大的不便和困扰。但随着数据恢复技术的发展&#xff0c;我们有了更多的…

【pm2 - sdk 集成到程序中,典型用法】

pm2作为一款进程管理神器&#xff0c;除了命令行的启动方式外&#xff0c;其还对应有sdk&#xff0c;集成到程序中&#xff0c;我们可以连接到已有或创建pm2的守护进程&#xff0c;与其进行交互&#xff0c;动态&#xff0c;编程式地控制程序的启停等。以下为示例&#xff1a; …

数据结构——不相交集(并查集)

一、基本概念 关系&#xff1a;定义在集合S上的关系指对于a&#xff0c;b∈S&#xff0c;若aRb为真&#xff0c;则a与b相关 等价关系&#xff1a;满足以下三个特性的关系R称为等价关系 (1)对称性&#xff0c;aRb为真则bRa为真&#xff1b; (2)反身性,aRa为真; (3)传递性,aRb为真…

Android studio 连接 adb传输文件到电脑

前提是已经连接到adb window R&#xff1a; 打开控制台adb devices&#xff1a;可以查看已经连接的设备adb pull /storage/emulated/0/Download/aa.png C:\Users\Administrator\Desktop&#xff1a;拉取连接设备的文件 aa.png 到电脑桌面上 (在电脑控制台进行拉取操作) 如果…

XShell免费版的安装配置

官网下载 https://www.xshell.com/zh/free-for-home-school/ 下载地址 通过邮箱验证 新建会话 通过ssh登录树莓派 填写主机IP 点击用户身份验证 成功连接

Swagger测试接口,请求头添加token

概述Swagger 1、概述 在日常开发中&#xff0c;我们的业务需要用户登录&#xff0c;权限控制。但是在某些情况下我们使用Swagger测试接口&#xff0c;部分接口需要携带token&#xff0c;才能访问&#xff0c;就需要在swagger添加token窗口。 效果图&#xff1a; 由 右上角 A…

Autodl如何进行实例使用(同区)

一、首先找到之前保存的实例 二、点击更多然后选择克隆实例 三、选择是否要保存之前的数据盘 四、选择空余的GPU进行创建即可

等了10年,终于迎来RTX5/RTX4全家桶开源,开源,开源! 且免费商用

我们的V4, V5, V6 ,V7开发板都配套了大量的RTX4, RTX5教程和案例&#xff0c;从2015年发布首版RTX4内核教程以来&#xff0c;已经整整10年了。 1、制作这个RTX教程和案例&#xff0c;其实也承受了很大的压力&#xff0c;因为只有RTX内核是免费商用的&#xff0c;中间件并不免费…

spring-boot 3.2 + spring-boot-starter-quartz + HikariCP配置

第一步&#xff0c;添加 spring-boot-starter-quartz 的 maven 依赖。 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> 第二步&#xff0c;在 ap…

【Android14 ShellTransitions】(四)Transition收集动画参与者

这一节的内容在WMCore中&#xff0c;现在Transition已经走到COLLECTING状态了&#xff0c;并且可以收集动画参与者了。 那么Transition是在什么时候去收集动画参与者&#xff1f;回到我们最初的ActivityStarter.startActivityUnchecked&#xff1a; 在调用了TransitionControl…

python爬虫学习(2)——requests模块

520那天我向心仪的女孩要微信&#xff1a;“女神&#xff0c;能给我你的微信号吗&#xff1f;” 女神&#xff1a;“给我——爬&#xff01;&#xff01;&#xff01;&#xff01;” 从那天开始&#xff0c;我就决定要学好爬虫&#xff0c;爬到女神微信号&#xff01;&#xff…

nacos(一) 安装

一 nacos 1.4.7安装 安装 nacos-server nacos官方下载 说明&#xff1a; 下载1.4.7和2.3.2版本,本专栏后续以1.4.7为例进行讲解补充&#xff1a; nacos-server服务端和nacos-client客户端附加&#xff1a; spring 版本、nacos-server、nacos-client版本要适配思考&#xf…

实战项目:飞机坦克大战 —— 面向对象编程之旅

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、项目概览与背景介绍 二、面向对象编程基本概念解析 1. 类与对象 2. 构造函数与属性封…

执法行动高压下,勒索软件攻击仍持续增加

执法行动 最近几年&#xff0c;随着网络犯罪特别是勒索软件犯罪的日益猖獗&#xff0c;勒索软件攻击已经对网络空间安全构成重大威胁。互联网不是法外之地&#xff0c;执法机构也对应加强了执法力度&#xff0c;对全球威胁重大的网络犯罪团伙进行重点打击。对勒索软件团伙所控…

面向对象编程:坦克飞机大战游戏的重构之旅

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、面向对象编程思想入门 坦克对象的定义 属性与行为方法的实现 二、面向过程与面向对象…

利用大语言模型增强网络抓取:一种现代化的方法

本文将探讨大语言模型(LLMs)与网络抓取的集成&#xff0c;以及如何利用LLMs高效地将复杂的HTML转换为结构化的JSON。 作为一名数据工程师&#xff0c;我的职业生涯可以追溯到2016年。那时&#xff0c;我的主要职责是利用自动化工具从不同网站上获取海量数据&#xff0c;这个过…

TiDB学习3:TiKV

目录 1. TiKV架构和作用 2. RocksDB 2.1 写入 2.2 查询 2.3 Column Families列簇 3. 分布式事务 3.1 事务流程 3.2 分布式事务流程 3.3 MVCC 4. Raft与Multi Raft 4.1 Raft日志复制 4.2 Raft Leader选举 5. TiKV- 读写 5.1 数据的写入 5.2 数据的读取ReadIndex …

正邦科技(day1)

1&#xff1a;充电桩工作了两个半小时&#xff0c;已用电量13度电&#xff08;一般的话是一个小时7度电&#xff09; 2&#xff1a;火线&#xff08;红色&#xff0c;棕色&#xff09;&#xff0c;零线&#xff08;蓝色&#xff09; 3&#xff1a;充电桩工作了两个半小时&#…