前几天试着开发了一下公众号,期间踩了一下坑,在此分享一下经验,感兴趣的可以自己搞下,下面开始了。
01 准备工作
—
准备工作
-
首先需要一个可供开发或测试的公众号,没有的话自行申请
-
需要有一个独立公网 ip 的服务器或者可以联网的电脑使用内网穿透工具也可以,下面有详细说明
-
新创建一个 SpringBoot 项目
02 开发前说明
—
开发前说明
公众号平台提供的基础功能如下:
- 创作管理------创建素材,分为图文,视频和图片
- 功能里面------
-
自动回复------可以设置关键字和需要回复的信息
-
自定义菜单------可以设置公众号显示的菜单
-
其它功能暂时没有用过,由于公众号平台提供的功能有限,如果要实现获取位置,获取粉丝数,给粉丝推送消息等复杂功能时,平台提供的功能就无法实现了,这个时候可以自己搭建一个微信服务器,调用公众号平台提供的 api 实现自己的业务逻辑。目前公众号平台提供的所有 api 在这里可以看到。
公众号开发分为正式环境和测试环境,由于未认证的公众号,平台开放的 api 权限有限,建议选择测试帐号进行验证。
如果公众号进行了微信认证后,可以将开发的公众号服务部署在服务器上,就可以正式被关注的人看到了。
查看是否可以认证方式如下:点击帐号头像,点击帐号详情
可以点击申请微信认证,个人帐号,暂不支持认证。
帐号迁移可以将本公众号的所有资源迁移到新的公众号上面。
03 开发公众号流程介绍
—
开发公众号流程介绍
**选择开发者工具
**
跳转后如图
选择公众平台测试帐号,扫码登录进入后界面如下:
appID:每个公众号注册会分配唯一的 id
appsecret:秘钥自动分配,测试帐号过期会失效,正式环境生成后一直有效,除非重置,正式环境的秘钥在获取后需要自行保存,界面不会展示
URL:后端服务的 ip 地址,微信只支持 80 端口
Token:随意设置的字符串,与微信服务器建立连接的时候使用
后台服务器启动后点提交,提示配置成功,代表与微信服务器验证通过。
需要配置好网络,本地启动服务后提交
如果提示配置失败,检查后台服务器 ip 地址是否正确
以内网穿透的方式,访问本地服务,下面提供两种工具
花生壳 花生壳既是内网穿透软件、端口映射软件。功能比较齐全,比较简单,也是大家比较耳熟了,支持 tcp,udp.https.http,socket5 应用。有免费版和版。需要下载客户端和官网注册,大致的原理是,在你注册的时候,花生壳给你生成二级域名,本地使用客户端配置本地的 ip 和端口,与花生壳建立连接后,由花生壳解析后把请求转发到自己本地的 ip 和端口上。
网址
nps** **nps 是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持 tcp、udp 流量转发,可支持任何 tcp、udp 上层协议(访问内网网站、本地支付接口调试、ssh 访问、远程桌面,内网 dns 解析等等……),此外还支持内网 http 代理、内网 socks5 代理、p2p 等,并带有功能强大的 web 管理端。
开源项目地址:
有独立 ip 地址的服务器可以使用这种方式,说明文档比较详细,因此下面简单介绍一下使用方法:
由于后台代码在本地,如果修改了内容需要部署到服务器上才能验证效果,非常不方便,因此可以使用 nps 代理本地网络。由于版本非常全,直接直接下载对应系统版本即可,我下载的版本如下:对应服务端和客户端的
下载完成进行解压和安装
sudo chmod +x installsudo ./install
安装完成后服务端启动 nps nps 默认开启 80/443 进行域名解析
可以看到 nps 启动了,并监听了 80 端口
本地登录服务器 ip:8080 ,默认帐号 admin 密码 123
登录后界面如下:
选择菜单 客户端 点击新增
输入备注后,其它可以留空,点击保存
在客户端列表,点击新增客户端左侧的 + 号,将客户端指令复制出来,在本地客户端执行如下命令,会看到连接成功的日志
刷新客户端状态,可以看到已经连接成功了,然后我们点击右侧的主机
连接成功只是表示服务器和客户端建立了连接,但是外网还是无法直接访问我们内网 ip 和端口,需要添加一个域名解析,域名解析默认端口是 80,我们将服务器的请求转发到内网的 ip 和端口上,实现了外网对我们本地网络的访问
后台项目配置与启动
后台使用 SpringBoot 框架搭建,需要引入的依赖如下:
这个是一个用于简化公众号开发的工具
<dependency>
<groupId>com.github.liyiorg</groupId>
<artifactId>weixin-popular</artifactId>
<version>2.8.28</version>
</dependency>
测试帐号的配置信息,根据页面信息,自己配置即可
创建 controller ,增加一个请求路径,这个地址用于与服务器验证和收发消息,与测试帐号上面配置的路径一样,在测试帐号点提交的时候就会请求这个路径,对微信服务器请求的参数进行校验,校验成功则连接成功
@RequestMapping("/test")
public void test(@RequestParam Map<String, String> param, HttpServletRequest request, HttpServletResponse response) throws Exception {
ServletInputStream inputStream = request.getInputStream();
ServletOutputStream outputStream = response.getOutputStream();
// 算出来的签名
String signature = param.get("signature");
String echostr = param.get("echostr");
String timestamp = param.get("timestamp");
String nonce = param.get("nonce");
// 对称加密 本地
String token = WXConf.getTokenString();
if (StringUtils.isEmpty(signature) || StringUtils.isEmpty(timestamp)) {
outputStreamWrite(outputStream, "faild request");
return;
}
if (echostr != null) {
outputStreamWrite(outputStream, echostr);
return;
}
// 验证请求签名
if (!signature.equals(SignatureUtil.generateEventMessageSignature(token, timestamp, nonce))) {
log.error("The request signature is invalid");
return;
}
if (inputStream != null) {
// 转换XML
EventMessage eventMessage = XMLConverUtil.convertToObject(EventMessage.class, inputStream);
log.info("eventMessage:" + JSON.toJSONString(eventMessage));
String key = eventMessage.getFromUserName() + "__" + eventMessage.getToUserName() + "__" + eventMessage.getMsgId() + "__" + eventMessage.getCreateTime();
log.info("key:" + key);
if (EXPIRE_KEY.exists(key)) {
// 重复通知不作处理
System.err.println("重复通知不作处理");
return;
} else {
EXPIRE_KEY.add(key);
}
outputStreamWrite(outputStream,"success");
}
}
private void outputStreamWrite(OutputStream outputStream, String text) {
try {
outputStream.write(text.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
}
}
成功建立连接后,我们可以验证平台提供的 api,使用方法如下:
使用我们上面引入的工具,比如创建自定义菜单,使用 MenuApi.menuCreate 传入对应的参数,请求该接口即可创建菜单
@ApiOperation("创建菜单")
@GetMapping("/createMenu")
public JsonResult<String> createMenu() {
String json ="{\n" +
"\"button\": [\n" +
"{\n" +
"\"type\": \"view\",\n" +
"\"name\": \"今日热榜\",\n" +
"\"url\": \"https://tophub.today/\"\n" +
"},\n" +
"{\n" +
"\"type\": \"view\",\n" +
"\"name\": \"搜索\",\n" +
"\"url\": \"http://www.soso.com/\"\n" +
"},\n" +
"{\n" +
"\"name\": \"更多\",\n" +
"\"sub_button\": [\n" +
"{\n" +
"\"type\": \"view_limited\",\n" +
"\"name\": \"关于我们\",\n" +
"\"media_id\": \"7g1XYnELxCdD4xWz04p7tXsnPNpZrv7l5zgAHQGNJqk\"\n" +
"},\n" +
"{\n" +
"\"type\": \"click\",\n" +
"\"name\": \"联系我们\",\n" +
"\"key\": \"V1001_GOOD\"\n" +
"}\n" +
"]\n" +
"}\n" +
"]\n" +
"}";
我把想要测试的 api 使用 swagger 生成了 api 文档,直接在页面传入参数操作也很方便。如下:
执行完成后,扫描这个测试帐号二维码即可实时查询 api 效果。
欢迎交流!!欢迎关注我们
码云地址
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于