微信公众号服务平台的自定义菜单、关注自动回复、关键词回复是提升用户交互体验的核心功能。本文将基于 Java 语言,结合微信官方接口规范,完整实现这三类功能的接口开发,并通过可运行的案例代码,讲解从环境准备到功能落地的全流程。
一、开发前准备
1.1 核心依赖
本次开发基于 Spring Boot 框架,需引入以下核心依赖(pom.xml):
<dependencies>
<!-- Spring Boot核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- HTTP请求工具 -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.10.0</version>
</dependency>
<!-- JSON解析工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.25</version>
</dependency>
<!-- 加解密工具(微信消息验签) -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
</dependencies>
1.2 微信公众号配置
- 登录微信公众平台(服务号 / 订阅号),进入「开发 - 基本配置」:
- 获取
AppID和AppSecret; - 配置服务器 IP 白名单(接口调用需校验);
- 配置服务器地址(URL)、令牌(Token)、EncodingAESKey(消息加解密用)。
- 获取
- 权限确认:确保公众号已开通「自定义菜单」「自动回复」接口权限(服务号默认开通,订阅号需认证)。
1.3 核心常量定义
创建WeChatConstant类,统一管理微信接口地址和配置:
public class WeChatConstant {
// 获取access_token接口
public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
// 自定义菜单创建接口
public static final String MENU_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s";
// 自动回复规则创建接口(关注回复/关键词回复)
public static final String AUTO_REPLY_SET_URL = "https://api.weixin.qq.com/cgi-bin/reply/set_autoreply_info?access_token=%s";
// 公众号AppID(替换为自己的)
public static final String APP_ID = "your_appid";
// 公众号AppSecret(替换为自己的)
public static final String APP_SECRET = "your_appsecret";
}
二、核心工具类开发
2.1 AccessToken 获取工具
微信接口调用需先获取access_token(有效期 2 小时,需缓存),创建WeChatTokenUtil:
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import com.alibaba.fastjson.JSONObject;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class WeChatTokenUtil {
private static OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.build();
// 缓存access_token,实际项目建议用Redis
private static String accessToken;
private static long expireTime;
/**
* 获取有效的access_token
*/
public static String getAccessToken() throws IOException {
// 检查token是否过期
if (accessToken == null || System.currentTimeMillis() > expireTime) {
String url = String.format(WeChatConstant.ACCESS_TOKEN_URL,
WeChatConstant.APP_ID, WeChatConstant.APP_SECRET);
Request request = new Request.Builder().url(url).get().build();
try (Response response = client.newCall(request).execute()) {
String respJson = response.body().string();
JSONObject json = JSONObject.parseObject(respJson);
accessToken = json.getString("access_token");
// 过期时间提前10秒,避免网络延迟导致失效
expireTime = System.currentTimeMillis() + (json.getInteger("expires_in") - 10) * 1000;
}
}
return accessToken;
}
}
2.2 HTTP 请求工具
创建WeChatHttpUtil,封装 POST 请求(接口调用主要用 POST):
import okhttp3.MediaType;
import okhttp3.RequestBody;
import java.io.IOException;
public class WeChatHttpUtil {
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
private static OkHttpClient client = new OkHttpClient();
/**
* 发送POST请求(JSON参数)
*/
public static String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
}
三、功能实现
3.1 自定义菜单实现
3.1.1 菜单数据结构设计
微信自定义菜单支持「点击推事件」「跳转 URL」等类型,本次案例创建包含 2 个一级菜单、1 个二级菜单的结构:
import com.alibaba.fastjson.JSONObject;
public class WeChatMenuService {
/**
* 创建自定义菜单
*/
public String createMenu() throws IOException {
// 1. 构建菜单JSON
JSONObject menuJson = new JSONObject();
JSONObject buttonJson = new JSONObject();
// 一级菜单1:首页(跳转URL)
JSONObject menu1 = new JSONObject();
menu1.put("name", "官网首页");
menu1.put("type", "view");
menu1.put("url", "https://www.example.com");
// 一级菜单2:我的服务(包含二级菜单)
JSONObject menu2 = new JSONObject();
menu2.put("name", "我的服务");
JSONObject subButton = new JSONObject();
// 二级菜单1:个人中心(点击事件)
JSONObject subMenu1 = new JSONObject();
subMenu1.put("name", "个人中心");
subMenu1.put("type", "click");
subMenu1.put("key", "USER_CENTER");
// 二级菜单2:帮助中心(跳转URL)
JSONObject subMenu2 = new JSONObject();
subMenu2.put("name", "帮助中心");
subMenu2.put("type", "view");
subMenu2.put("url", "https://www.example.com/help");
subButton.put("sub_button", new JSONObject[]{subMenu1, subMenu2});
menu2.put("sub_button", subButton.getJSONArray("sub_button"));
buttonJson.put("button", new JSONObject[]{menu1, menu2});
menuJson.put("button", buttonJson.getJSONArray("button"));
// 2. 获取access_token,拼接接口URL
String accessToken = WeChatTokenUtil.getAccessToken();
String url = String.format(WeChatConstant.MENU_CREATE_URL, accessToken);
// 3. 调用接口
return WeChatHttpUtil.post(url, menuJson.toJSONString());
}
}
3.2 关注自动回复实现
关注自动回复是用户首次关注公众号时触发的回复,支持「文本」「图片」「图文」等类型,本次实现文本回复:
public class WeChatAutoReplyService {
/**
* 设置关注自动回复
*/
public String setSubscribeReply() throws IOException {
// 1. 构建回复规则JSON
JSONObject replyJson = new JSONObject();
// 关注回复配置
JSONObject subscribeReply = new JSONObject();
subscribeReply.put("type", "text"); // 回复类型:文本
JSONObject textContent = new JSONObject();
textContent.put("content", "欢迎关注XXX公众号!回复【帮助】查看使用指南,回复【客服】联系人工~");
subscribeReply.put("text", textContent);
replyJson.put("subscribe_autoreply_info", subscribeReply);
// 2. 获取access_token,拼接接口URL
String accessToken = WeChatTokenUtil.getAccessToken();
String url = String.format(WeChatConstant.AUTO_REPLY_SET_URL, accessToken);
// 3. 调用接口
return WeChatHttpUtil.post(url, replyJson.toJSONString());
}
}
3.3 关键词回复实现
关键词回复支持「精确匹配」「模糊匹配」,本次实现 2 个关键词规则:
- 精确匹配「帮助」:回复使用指南;
- 模糊匹配「客服」:回复人工客服联系方式。
注意:微信关键词回复接口(set_autoreply_info)需同时传入关注回复和关键词回复,因此需整合配置:
public class WeChatKeywordReplyService {
/**
* 设置关键词回复(含关注回复)
*/
public String setKeywordReply() throws IOException {
// 1. 构建完整回复规则JSON
JSONObject replyJson = new JSONObject();
// 1.1 关注回复(复用之前的配置)
JSONObject subscribeReply = new JSONObject();
subscribeReply.put("type", "text");
JSONObject subscribeText = new JSONObject();
subscribeText.put("content", "欢迎关注XXX公众号!回复【帮助】查看使用指南,回复【客服】联系人工~");
subscribeReply.put("text", subscribeText);
replyJson.put("subscribe_autoreply_info", subscribeReply);
// 1.2 关键词回复配置
JSONObject keywordReply = new JSONObject();
keywordReply.put("is_add_rule", true); // 新增规则(false为覆盖)
// 规则1:精确匹配「帮助」
JSONObject rule1 = new JSONObject();
rule1.put("rule_name", "帮助指南");
rule1.put("match_mode", "exact"); // 精确匹配
rule1.put("keyword_list_info", new JSONObject[]{
new JSONObject().fluentPut("keyword", "帮助")
});
// 规则1回复内容
JSONObject reply1 = new JSONObject();
reply1.put("type", "text");
JSONObject text1 = new JSONObject();
text1.put("content", "【使用指南】\n1. 回复【我的订单】查看订单状态\n2. 回复【优惠券】领取新人福利\n3. 回复【客服】联系人工");
reply1.put("text", text1);
rule1.put("reply_list_info", new JSONObject[]{reply1});
// 规则2:模糊匹配「客服」
JSONObject rule2 = new JSONObject();
rule2.put("rule_name", "客服联系");
rule2.put("match_mode", "contain"); // 模糊匹配
rule2.put("keyword_list_info", new JSONObject[]{
new JSONObject().fluentPut("keyword", "客服")
});
// 规则2回复内容
JSONObject reply2 = new JSONObject();
reply2.put("type", "text");
JSONObject text2 = new JSONObject();
text2.put("content", "人工客服联系方式:\n电话:400-XXXX-XXXX\n工作时间:9:00-18:00");
reply2.put("text", text2);
rule2.put("reply_list_info", new JSONObject[]{reply2});
keywordReply.put("keyword_autoreply_info", new JSONObject(){
{
put("list", new JSONObject[]{rule1, rule2});
}
});
replyJson.put("keyword_autoreply_info", keywordReply.getJSONObject("keyword_autoreply_info"));
// 2. 获取access_token,拼接接口URL
String accessToken = WeChatTokenUtil.getAccessToken();
String url = String.format(WeChatConstant.AUTO_REPLY_SET_URL, accessToken);
// 3. 调用接口
return WeChatHttpUtil.post(url, replyJson.toJSONString());
}
}
四、接口调用与测试
4.1 编写 Controller
创建WeChatController,对外提供调用入口:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
public class WeChatController {
private final WeChatMenuService menuService = new WeChatMenuService();
private final WeChatAutoReplyService autoReplyService = new WeChatAutoReplyService();
private final WeChatKeywordReplyService keywordReplyService = new WeChatKeywordReplyService();
/**
* 创建自定义菜单
*/
@GetMapping("/wechat/createMenu")
public String createMenu() {
try {
return menuService.createMenu();
} catch (IOException e) {
return "创建菜单失败:" + e.getMessage();
}
}
/**
* 设置关注自动回复
*/
@GetMapping("/wechat/setSubscribeReply")
public String setSubscribeReply() {
try {
return autoReplyService.setSubscribeReply();
} catch (IOException e) {
return "设置关注回复失败:" + e.getMessage();
}
}
/**
* 设置关键词回复
*/
@GetMapping("/wechat/setKeywordReply")
public String setKeywordReply() {
try {
return keywordReplyService.setKeywordReply();
} catch (IOException e) {
return "设置关键词回复失败:" + e.getMessage();
}
}
}
4.2 测试步骤
- 替换
WeChatConstant中的APP_ID和APP_SECRET为自己的公众号信息; - 启动 Spring Boot 项目,访问以下接口:
- 创建菜单:
http://localhost:8080/wechat/createMenu; - 设置关注回复:
http://localhost:8080/wechat/setSubscribeReply; - 设置关键词回复:
http://localhost:8080/wechat/setKeywordReply;
- 创建菜单:
- 接口返回
{"errcode":0,"errmsg":"ok"}表示配置成功; - 关注公众号测试关注回复,发送「帮助」「客服」测试关键词回复,查看菜单栏确认菜单创建成功。
五、注意事项
access_token缓存:实际项目中建议用 Redis 缓存,避免频繁调用获取接口(微信限制每天调用次数);- 接口权限:订阅号未认证仅支持部分接口,服务号需确保已开通对应权限;
- 消息加解密:若公众号配置了「安全模式」,接收用户消息时需解密,本文仅实现主动配置接口,接收消息需额外处理;
- 菜单更新:自定义菜单创建后,用户需重新关注或刷新公众号才能看到最新菜单;
- 关键词匹配:模糊匹配(contain)会匹配包含关键词的所有消息,需避免关键词冲突。
六、总结
本文通过 Java+Spring Boot 实现了微信服务平台自定义菜单、关注自动回复、关键词回复的核心接口开发。核心思路是:先获取有效的access_token,再按照微信接口规范构建 JSON 参数,通过 POST 请求调用对应接口。实际项目中,可在此基础上扩展图片 / 图文回复、菜单删除 / 查询、回复规则查询等功能,同时需做好异常处理、日志记录和接口限流,确保系统稳定运行。
5595

被折叠的 条评论
为什么被折叠?



