简易的微信公众号管理平台使用指南
前言
1、微信功能实现与管理后台目前是独立的。
2、微信功能实现是基于Jfianl-weixin SDK开发的。
3、管理后台使用的Eova开源框架,如果你不喜欢eova框架可以自行处理后台
4、使用时注意公众号接口的权限【公众号接口权限说明】
如果你对微信开发不是很熟悉可以参考我之前写的博客【微信开发专栏】
如果你对微信支付以及支付宝支付感兴趣可以看看我的开源项目
【Android 微信、支付App支付SDK】【IJPay 让支付触手可及,实现微信、支付宝系列支付】
下载项目并导入Eclipse
环境搭建参考资料【搭建maven环境】 【JDK开发环境搭建及环境变量配置】【安装Mysql5.7并修改初始密码】【微信公众号-Maven开源导入IDE】
微信功能实现源码http://git.oschina.net/javen205/weixin_pro
管理后台实现源码dev分支http://git.oschina.net/javen205/weixin_guide
建议使用Eclipse 、MySQL数据库在doc中
搭建环境、启动项目如果出现问题可以在博客中留言
多环境配置
如果clone下来的项目没有做任何修改直接启动项目将会出现以下异常
为什么会出现这个异常呢? 因为项目pom.xml中设置了多环境,而默认启用的是dev(开发环境) 。所以这里需要在src/main/resources中新建一个dev目录并将production下的配置文件复制到dev目录中。如下图
成为开发者模式
参考wx_config
表具体字段描述可以看备注,其中rmid
是一个唯一的随机数成为开发者模式中会携带此参数来查询公众号的参数。
注意:测试号不支持加密否则会出现NullPointerException,
encrypt
需要设置为0此字段默认也是0。
成为开发URL为:http://域名/[项目名称]/msg?rmid=123456
特别说明:
1、测试号不支持加密、不支持加密、不支持加密
2、正式的公众号需要设置ip白名单,不然会出现invalid ip xxxxx,no in whitelist xxxx
3、授权需要配置授权域名(不会设置点击这里)。如果是正式的公众号还需要上传验证文件来验证域名,直接上传到项目的根目录即可(webapp中)
例子:
多账号管理实现原理
成为开发者模式的路由为msg
、WeiXinMsgController
上的拦截器ConfigInterceptor
主要是通过URL中的rmid
查询数据库中公众号的配置并ApiConfigKit.putApiConfig(ApiConfig)中。在接口需要使用的地方就从Map中取。具体代码参考com.jfinal.weixin.sdk.api.ApiConfigKit
以及com.javen.weixin.Interceptor.ConfigInterceptor
部分代码如下:
/**
* Copyright (c) 2015-2017, Javen Zhou (javen205@126.com).
*
* Licensed under the Apache License, Version 2.0 (the "License");
*/
package com.javen.weixin.Interceptor;
import com.javen.weixin.common.model.Config;
import com.javen.weixin.service.ConfigService;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Controller;
import com.jfinal.kit.StrKit;
/**
* @author Javen
* 2017年6月11日
*/
public class ConfigInterceptor implements Interceptor {
static ConfigService srv = ConfigService.me;
@Override
public void intercept(Invocation inv) {
Controller controller = inv.getController();
String rmid = controller.getPara("rmid");
if (StrKit.isBlank(rmid)) {
throw new IllegalArgumentException("rmid 值不能为空");
}
Config config = srv.getConfigByRmid(rmid);
controller.setSessionAttr("config", config);
if (null == config) {
throw new IllegalArgumentException("rmid:"+rmid+" 值不能用,请联系管理员");
}
srv.getApiConfig(config);
inv.invoke();
}
}
关键字回复
微信公众号交互实现都在WeiXinMsgController
中,关键字回复主要实现代码如下:
/**
* 接收文本消息事件
*/
@Override
protected void processInTextMsg(InTextMsg inTextMsg) {
String msgContent = inTextMsg.getContent().trim();
final String openId = inTextMsg.getFromUserName();
// String rmid = getPara("rmid");//再通过rmid 查询APPId,这里为了方便直接将其存入session
final Config config = (Config) getSession().getAttribute("config");
String appId = config.getAppId();
int appType = config.getAppType();
logger.info(config.toJson());
List<Keyword> keywords = kws.getKeyWord(config.getAppId(), msgContent);
logger.info("keywords>" + JsonKit.toJson(keywords));
if (null != keywords && keywords.size() > 0) {
int size = keywords.size();
Keyword keyword = keywords.get(0);
//异步发送其他的消息
if (size >= 1 && (appType == 1 || appType == 3 || appType == 5)) {
for (int i = 1; i < size; i++) {
Keyword asyncKeyword = keywords.get(i);
Integer async = asyncKeyword.getAsync();
if (async == 1) {
replyMessage(1, true, appId, openId, asyncKeyword);
}
}
}
// 被动回复消息
replyMessage(1,false, appId,openId, keyword);
}
if (msgContent.equals("红包")) {
new Thread(new Runnable() {
public void run() {
logger.info("是发红包的时候了...");
RedPackUtil.sendRedPack(config, 1, openId, IpKit.getRealIp(getRequest()));
}
}).start();
renderNull();
return;
}
renderOutTextMsg(msgContent);
}
部分说明:
1、从请求中获取rmid
(此参数在上文有提到)。
2、再通过rmid
查询wx_confg
表中配置公众号的相关参数。开源项目中是为了方便直接从session中取了。有人要问何时存入到session的呢? 使用的是拦截器(ConfigInterceptor
)上文有提到哦。
3、OK,现在有了appId
相关的参数。那么我们就可以通过appId
来查wx_keyword
表(微信关键字配置表)根据消息的类型作对应的回复即可。
4、20170701支持多消息回复(使用客服接口)
关注回复
在weixin_pro 项目中目前关注回复做了两件事。
1、获取用户信息
2、回复文本、图文、图文以及异步发送红包(20170701支持多消息回复)
关注回复配置表wx_submsg
,如果redpack_id
不为空表示需要发红包。type
为回复消息的类型,回复消息上面有做说明这里就不介绍了。
获取到用户信息保存在wx_user
表中,用户昵称(nick_name
)中包含表情怎么处理? 这里使用最简单的处理方法(UrlEncode编码/UrlDecode解码 ),也可以将mysql表字段定义为utf8mb4同时mysql数据库连接字符串去掉编码方式,不再是utf8,主要是支持的字节数不同。
MySQL在5.5.3版本之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。其实,utf8mb4是utf8的超集,理论上原来使用utf8,然后将字符集修改为utf8mb4,也会不会对已有的utf8编码读取产生任何问题。当然,为了节省空间,一般情况下使用utf8也就够了。
想要了解的更多,请参照浅谈MySQL中utf8和utf8mb4的区别
自定义菜单
自定义菜单【官方接口】
特别注意:
1、自定义菜单最多包括3个一级菜单,每个一级菜单最多包含5个二级菜单。
2、一级菜单最多4个汉字,二级菜单最多7个汉字,多出来的部分将会以“…”代替。
3、创建自定义菜单后,菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。
在weixin_pro 中与菜单相关的有三张表:
1、wx_menutype
菜单类型表
2、wx_custommenu
自定义菜单表
3、wx_matchrulemenu
个性化菜单表
1、在wx_custommenu
中 pid
为0 表示是主菜单,其他为子菜单。二级菜单的pid
为主菜单的id
。type_id
为菜单类型关联表为wx_menutype
,其值如果为11
表示为主菜单并没有子菜单。
2、个性化菜单wx_matchrulemenu
可设置项如下
1、用户标签(开发者的业务需求可以借助用户标签来完成)
2、性别
3、手机操作系统
4、地区(用户在微信客户端设置的地区)
5、语言(用户在微信客户端设置的语言)
在wx_matchrulemenu
中使用menu_group
关联到wx_custommenu
;普通菜单的menu_group
为0,其他跟第1点描述一样。
部分截图:
具体实现代可以查看源码
/weixin_pro/src/main/java/com/javen/weixin/controller/CustomMenuController.java
生成菜单的URL为: http://域名/[项目名称]/menu/create?rmid=123456
添加个性化菜单的URL为: http://域名/[项目名称]/menu/addConditional?rmid=123456
授权获取用户信息
如果你对授权获取用户信息不熟悉可以参考这篇文章
在weixin_pro 中只是把授权参数提出到了数据库wx_authorize
,数据库字段都有备注描述这里就不过多的介绍。
使用授权获取用户信息必要的配置(上传文件验证域名之类的)这里就不多说了可以参考上文。
授权URL:
http://域名/[项目名称]/oauth/toOauth?rmid=123456
回调授权获取用户信息将会保存在wx_user
表中并存入session setSessionAttr("wxuser", user);
授权之后页面转发是根据数据库配置转发的。
核心实现代码都在这里
/weixin_pro/src/main/java/com/javen/weixin/controller/WeiXinOauthController.java
JSSDK的使用
在weixin_pro 中只是先关的参数从数据库中读取而已。具体实现代码/weixin_pro/src/main/java/com/javen/weixin/Interceptor/JSSDKInterceptor.java
页面中使用可以参考/weixin_pro/src/main/webapp/WEB-INF/_view/jssdk.html