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

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

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

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

 首先第一步需要有自己的服务器和固定的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.rhkb.cn/news/333176.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

唯众云课堂:领航智慧教育,赋能职教未来,打造高效人才培养新平台

随着《中国智慧教育发展报告 2023》的发布&#xff0c;智慧教育被正式定义为数字教育发展的高级阶段。然而&#xff0c;各职院在智慧教育的发展道路上&#xff0c;往往面临着诸多挑战&#xff0c;如缺乏一体化教学平台、优质教学资源不足等。唯众凭借深厚的产业洞察与教育实践经…

【云原生】K8s管理工具--Kubectl详解(一)

一、陈述式管理 1.1、陈述式资源管理方法 kubernetes 集群管理集群资源的唯一入口是通过相应的方法调用 apiserver 的接口kubectl 是官方的 CLI 命令行工具&#xff0c;用于与 apiserver 进行通信&#xff0c;将用户在命令行输入的命令&#xff0c;组织并转化为apiserver 能识…

一文搞透常见的Python编码陷阱(上)(分析+案例)

一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 一、别忘了冒号 1. if 语句 2. while 语句 3. for 语句 4. 函数定义 5. 类定义 6. try/except 语句 …

太速科技-基于FPGA Spartan6 的双路光纤PCIe采集卡(2路光纤卡)

基于FPGA Spartan6 的双路光纤PCIe采集卡(2路光纤卡) 1、板卡概述   板卡采用xilinx Spartan6系列芯片&#xff0c;支持 PCI Express Base Specification 1.1 x1。内含丰富的逻辑资源和存储单元&#xff0c;板卡FPGA外接双片32M*16bit DDR2缓存器&#xff0c;支持乒乓操作。…

Ubuntu执行命令出现乱码,菱形符号

1、问题描述 如题&#xff0c;Ubuntu执行命令出现乱码&#xff0c;菱形符号&#xff08;见下图&#xff09;&#xff1a; 2、解决办法 export LC_ALLC 再运行就好了

fpga系列 HDL 00 : 可编程逻辑器件原理

一次性可编程器件&#xff08;融保险丝实现&#xff09; 一次性可编程器件&#xff08;One-Time Programmable Device&#xff0c;简称 OTP&#xff09;是一种在制造后仅能编程一次的存储设备。OTP器件在编程后数据不可更改。这些器件在很多应用场景中具有独特的优势和用途。 …

Web组态可视化编辑器 快速绘制组态图

演示地址&#xff1a;by组态[web组态插件] 随着工业智能制造的发展&#xff0c;工业企业对设备可视化、远程运维的需求日趋强烈&#xff0c;传统的单机版组态软件已经不能满足越来越复杂的控制需求&#xff0c;那么实现Web组态可视化界面成为了主要的技术路径。 行业痛点 对于…

nvm安装教程及使用nvm管理多个node版本

文章目录 前言一、nvm 安装教程温馨提示macOS/LinuxWindows 二、安装 node 前言 工作中&#xff0c;你可能会遇到以下场景&#xff1a; 我想使用 pnpm 命令安装依赖&#xff0c;但是在使用 pnpm 命令时提示如下 $ pnpm -v ERROR: This version of pnpm requires at least No…

移动云主机ECS搭建Kubernetes集群:详细步骤与指南

目录 云主机 ECS&#xff1a;云计算的强大引擎什么是云主机ECS&#xff1f;为何选择云主机ECS&#xff1f; 使用移动云ECS进行Kubernetes集群搭建1. 环境准备2. 安装步骤2.1 在每一个节点上执行的操作2.1.1 系统准备2.1.2 安装Docker2.1.3 安装Kubernetes的安装组件 2.2 在Mast…

chrome浏览器驱动下载

跑自动化的时候&#xff0c;需要打开谷歌浏览器&#xff0c;这个时候提示浏览器驱动找不到咋办呢&#xff1f; 1、网上搜索找到了这篇文章&#xff1a;https://www.cnblogs.com/laoluoits/p/17710501.html&#xff1b;按照文章介绍&#xff0c; 首先找到&#xff1a;CNPM Bin…

捷报!恒瑞医药ADC创新药SHR-A1921卵巢癌适应症拟纳入突破性治疗品种公示

近日&#xff0c;恒瑞医药自主研发的TROP-2抗体偶联药物&#xff08;antibody-drug-conjugate, ADC&#xff09;注射用SHR-A1921用于治疗铂耐药复发上皮性卵巢癌、输卵管癌或原发性腹膜癌适应症被国家药品监督管理局药品审评中心拟纳入突破性治疗品种公示名单。今年3月&#xf…

内网安全--域渗透准备知识

目录 知识点&#xff1a; 0x01 0x02 0x03 系列点&#xff1a; Linux主机信息收集 windows主机信息收集 知识点&#xff1a; 0、域产生原因 1、内网域的区别 2、如何判断在域内 3、域内常见信息收集 4、域内自动化工具收集 -局域网&工作组&域环境区别 -域…

Linux如何在目录下灵活创建、浏览、删除百万个文件

文章目录 一、创建百万级小文件1、单核CPU情况2、多核CPU情况3、执行效率对比3.1、单核的顺序执行3.2、多核的并发执行 二、如何列出/浏览这些文件1、查看目录下文件的数量2、列出&#xff1f;3、ls -f&#xff08;关闭排序功能&#xff09;3.1、执行效率对比 4、通过重定向导入…

HiWoo Box边缘计算网关

​在数字化浪潮汹涌的今天&#xff0c;边缘计算网关成为了连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。HiWoo Box&#xff0c;作为一款功能强大的边缘计算网关&#xff0c;不仅具备了传统网关的基本功能&#xff0c;更在数据采集、处理、传输等方面展现出了卓越…

“二叉堆:不是,啊?”

目录 前言一、堆的概念及结构堆的性质&#xff1a;堆的结构:最大堆最小堆堆顶注意 二、堆的实现1.初始化堆2. 堆的插入什么是堆的向上调整算法&#xff1f; 3.堆的删除什么是堆的向下调整算法&#xff1f; 4.获取堆顶的数据5.获取堆的数据个数6.堆的判空7.堆的销毁 三、建堆的时…

一文了解安卓内存抖动

目录 目录一、什么是内存抖动&#xff1f;1.1 Android里的内存抖动1.2 如何直观查看这种现象1.3 内存抖动带来的风险 二、如何避免内存抖动 目录 一、什么是内存抖动&#xff1f; 在程序里&#xff0c;每创建一个对象&#xff0c;就会有一块内存分配给它&#xff0c;每分配一…

超详细的前后端实战项目(Spring系列加上vue3)前后端篇(四)(一步步实现+源码)

兄弟们&#xff0c;继昨天的代码之后&#xff0c;继续完成最后的用户模块开发&#xff0c; 昨天已经完成了关于用户的信息编辑页面这些&#xff0c;今天再完善一下&#xff0c; 从后端这边开始吧&#xff0c;做一个拦截器&#xff0c;对用户做身份校验&#xff0c; 拦截器 这…

燃数科技前端25-40K*14薪一面超简单,下周二面啦

​​​​​​​ 文章末尾扫描二维码领取地址 一面 1、自我介绍 2、低代码如何设计的 3、react路由原理 4、react生命周期 5、什么是回调地狱&#xff0c;如何解决 6、jwt和session有什么区别 7、js文件相互引用有什么问题&#xff1f;如何解决 8、一个很大的json文件…

安卓手机APP开发__平台的架构

安卓手机APP开发__平台的架构 目录 概述 安卓软件栈 Linux内核 硬件抽象层(HAL) 安卓运行时 原生的C/C代码库 Java API框架 系统APP 概述 安卓是一个开源的&#xff0c;基于Linux的软件栈&#xff0c;它创建一个设备和形式因素的很宽的矩阵。 下图展示了安卓平台的所有…

全方位质量保障!龙蜥在内核、软件包、容器镜像、三方模块的 CI 工程实践

编者按&#xff1a;在海量的代码测试和构建中&#xff0c; CI(Continuous Integration)在代码提交阶段&#xff0c;对提高软件质量和开发效率起到了至关重要的作用。2023 龙蜥操作系统大会全面繁荣开发者生态分论坛上&#xff0c;龙蜥社区 QA SIG Maintainer、联通数科 CUlinux…