微信服务号开发----创建个性化菜单。
1、目的:让公众号的不同用户群体看到不一样的自定义菜单。
2、权限:已认证订阅号和已认证服务号。
3、分组
1、用户分组(开发者的业务需求可以借助用户分组来完成) 2、性别 3、手机操作系统 4、地区(用户在微信客户端设置的地区) 5、语言(用户在微信客户端设置的语言)
4、注意:
1、个性化菜单要求用户的微信客户端版本在iPhone6.2.2,Android 6.2.4以上。 2、菜单的刷新策略是,在用户进入公众号会话页或公众号profile页时,如果发现上一次拉取菜单的请求在5分钟以前,就会拉取一下菜单,如果菜单有更新,就会刷新客户端的菜单。测试时可以尝试取消关注公众账号后再次关注,则可以看到创建后的效果。 3、普通公众号的个性化菜单的新增接口每日限制次数为2000次,删除接口也是2000次,测试个性化菜单匹配结果接口为20000次 4、出于安全考虑,一个公众号的所有个性化菜单,最多只能设置为跳转到3个域名下的链接 5、创建个性化菜单之前必须先创建默认菜单(默认菜单是指使用普通自定义菜单创建接口创建的菜单)。
6、如果删除默认菜单,个性化菜单也会全部删除
5、7个分组类别选一个就可以了,我用的是group_id,这个与微信公众号管理界面中用户管理中的标签一直,只需要将用户设置成哪个标签,那么他就那个group里的,就能看到与其他没在这个标签组里的人不同的菜单。
private int group_id ; private String language ; private String sex; private String country; private String province; private String city; private String client_platform_type;
6、代码
package qwy.wx.pojo.menu; /** * @author: py * @version:2016年12月21日 下午3:38:31 * qwy.wx.pojo.menu.CustomMatchrule.java * @Desc 自定义 菜单匹配规则 */ public class CustomMatchrule { private int group_id ; private String language ; private String sex; private String country; private String province; private String city; private String client_platform_type; public CustomMatchrule(int group_id) { this.group_id = group_id; } // "sex":"1", // "country":"中国", // "province":"广东", // "city":"广州", // "client_platform_type":"2" // "language":"zh_CN" public int getGroup_id() { return group_id; } public void setGroup_id(int group_id) { this.group_id = group_id; } public String getLanguage() { return language; } public void setLanguage(String language) { this.language = language; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getClient_platform_type() { return client_platform_type; } public void setClient_platform_type(String client_platform_type) { this.client_platform_type = client_platform_type; } }
package qwy.wx.pojo.menu; /** * @author: py * @version:2016年12月21日 下午3:35:07 * qwy.wx.pojo.menu.CustomMenu.java * @Desc 自定义菜单 */ public class CustomMenu { private WeChatButton[] button; private CustomMatchrule matchrule; public WeChatButton[] getButton() { return button; } public void setButton(WeChatButton[] button) { this.button = button; } public CustomMatchrule getMatchrule() { return matchrule; } public void setMatchrule(CustomMatchrule matchrule) { this.matchrule = matchrule; } }
7、
package qwy.wx.uitl.menu; import net.sf.json.JSONException; import net.sf.json.JSONObject; import qwy.wx.enums.EnumMethod; import qwy.wx.pojo.menu.ComplexButton; import qwy.wx.pojo.menu.CustomMatchrule; import qwy.wx.pojo.menu.CustomMenu; import qwy.wx.pojo.menu.ViewButton; import qwy.wx.pojo.menu.WeChatButton; import qwy.wx.pojo.menu.WeChatMenuButton; import qwy.wx.uitl.HttpRequestUtil; /** * @author: py * @version:2016年12月21日 下午2:36:38 * qwy.wx.uitl.MenuCustomUtil.java * @Desc */ public class MenuCustomUtil { /**创建个性化菜单**/ public static String createCustomUrl ="https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=ACCESS_TOKEN"; /**删除个性化菜单**/ public static String deleteCustomUrl ="https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=ACCESS_TOKEN"; /***菜单查询*/ public static String MENU_GET_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN"; public static CustomMenu processMenu(int group_id) { WeChatMenuButton btn11 = new WeChatMenuButton(); btn11.setName("我的"); btn11.setType("click"); btn11.setKey("mykey01"); ViewButton btn13 = new ViewButton(); btn13.setName("csdn"); btn13.setType("view"); btn13.setUrl("http://blog.csdn.net/u014520797/article/details/53452757"); WeChatMenuButton btn21 = new WeChatMenuButton(); btn21.setName("C"); btn21.setType("click"); btn21.setKey("mykey02"); ViewButton btn22 = new ViewButton(); btn22.setName("C++"); btn22.setType("view"); btn22.setUrl("http://blog.csdn.net/u014520797/article/details/53946121"); ViewButton btn23 = new ViewButton(); btn23.setName("JAVA"); btn23.setType("view"); btn23.setUrl("http://blog.csdn.net/u014520797/article/details/53452757"); ViewButton btn24 = new ViewButton(); btn24.setName("C#"); btn24.setType("view"); btn24.setUrl("http://blog.csdn.net/u014520797/article/details/53946121"); ViewButton btn31 = new ViewButton(); btn31.setName("GO"); btn31.setType("view"); btn31.setUrl(""); ViewButton btn32 = new ViewButton(); btn32.setName("PHP"); btn32.setType("view"); btn32.setUrl("http://blog.csdn.net/u014520797/article/details/53946121"); ViewButton btn33 = new ViewButton(); btn33.setName("我的java"); btn33.setType("view"); btn33.setUrl("http://blog.csdn.net/u014520797/article/details/53946121"); ComplexButton mainBtn1 = new ComplexButton(); mainBtn1.setName("java"); mainBtn1.setSub_button(new WeChatButton[] { btn13}); ComplexButton mainBtn2 = new ComplexButton(); mainBtn2.setName("py"); mainBtn2.setSub_button(new WeChatButton[] { btn21, btn22, btn23, btn24}); ComplexButton mainBtn3 = new ComplexButton(); mainBtn3.setName("个人中心"); mainBtn3.setSub_button(new WeChatButton[] { btn31, btn32, btn33}); CustomMenu menu = new CustomMenu(); menu.setButton(new WeChatButton[] { mainBtn1, mainBtn2, mainBtn3 }); menu.setMatchrule(new CustomMatchrule(group_id)); return menu; } /** * @date 2016年12月21日下午4:09:58 * @param menu * @param token * @return int * @Des:创建个性化菜单 */ private static int createCustomMenu(CustomMenu menu,CharSequence token) { int result = 0; String requestUrl = createCustomUrl.replace("ACCESS_TOKEN", token); String jsonMenu = JSONObject.fromObject(menu).toString(); System.out.println("菜单createCustomMenu|jsonMenu:"+jsonMenu); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.POST.name(), jsonMenu); System.out.println("菜单createCustomMenu|jsonObject:"+jsonObject); if (null != jsonObject) { boolean containsKey = jsonObject.containsKey("menuid"); if (containsKey) { String menuid = jsonObject.getString("menuid"); System.out.println("menuid|"+menuid); } boolean containsKeyerrcode = jsonObject.containsKey("errcode"); if (containsKeyerrcode) { if (0 != jsonObject.getInt("errcode")) { result = jsonObject.getInt("errcode"); } } } return result; } /** * @date 2016年12月21日下午8:36:17 * @param token * @return String * @Des:查询个性化菜单 */ public static String getMenu(String token){ String requestUrl = MENU_GET_URL.replace("ACCESS_TOKEN", token); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.GET.name(), null); String menu =""; if (null != jsonObject) { try { System.out.println("jsonObject"+jsonObject.toString()); boolean containsValue = jsonObject.containsKey("errcode"); boolean containsValue2 = jsonObject.containsKey("menu"); System.out.println(containsValue+"|"+containsValue2); if(containsValue){ return "menu no exist"; } if(containsValue2){ menu = jsonObject.getString("menu"); } } catch (JSONException e) { e.printStackTrace(); } } return menu; } /** * @date 2016年12月21日下午8:39:40 * @param token void * @Des:删除个性化菜单 */ public static void deleteMenu(String token,String menuid){ String requestUrl = deleteCustomUrl.replace("ACCESS_TOKEN", token); String json ="{\"menuid\":\""+menuid+"\"}"; JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.POST.name(), json); System.err.println("deleteMenu|jsonObject:"+jsonObject.toString()); if (null != jsonObject) { boolean containsKeyerrcode = jsonObject.containsKey("errcode"); if (containsKeyerrcode) { System.err.println("deleteMenu|errcode|"+jsonObject.getInt("errcode")); } } } public static void main(String[] args) { String token = "upjO6Yui5255-bXi2RfVhcv7v687Qk0_1rgB8AoLs5agF4amIQC0W3FPsrjAI1KkrITTAR8QwsLkth-dycxGAFLydlwgsMahLD9E7uHI2QDOHdADAJUN"; createCustomMenu(processMenu(100), token); // getMenu(token); // deleteMenu(token,"416249170"); } }
创建分组
package qwy.wx.uitl.group; import net.sf.json.JSONObject; import qwy.wx.enums.EnumMethod; import qwy.wx.uitl.HttpRequestUtil; /** * @author: py * @version:2016年12月21日 下午2:56:21 * qwy.wx.uitl.group.GroupUtil.java * @Desc 创建分组 * 一个公众账号,最多支持创建100个分组。 * http请求方式: POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/groups/create?access_token=ACCESS_TOKEN POST数据格式:json POST数据例子:{"group":{"name":"test"}} */ public class GroupUtil { public static String createGroup_url="https://api.weixin.qq.com/cgi-bin/groups/create?access_token=ACCESS_TOKEN"; public static String getGroup_url="https://api.weixin.qq.com/cgi-bin/groups/get?access_token=ACCESS_TOKEN"; public static String deleteGroup_url="https://api.weixin.qq.com/cgi-bin/groups/delete?access_token=ACCESS_TOKEN"; public static String addUserGroup_url="https://api.weixin.qq.com/cgi-bin/groups/members/update?access_token=ACCESS_TOKEN"; /** * @date 2016年12月21日下午3:05:41 * @param token * @param groupNme void * @Des:创建分组 * * 成功则返回: * { "group": { "id": 107, "name": "test" } } 失败则返回: errcode */ public static void createGroup(String token, String groupNme){ String json = "{\"group\":{\"name\":\""+groupNme+"\"}}"; String requestUrl = createGroup_url.replace("ACCESS_TOKEN", token); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.POST.name(), json); System.err.println("GroupUtil|createGroup|jsonObject.toString():"+jsonObject.toString()); boolean containsValue = jsonObject.containsKey("errcode"); if(containsValue){ String errcode = jsonObject.getString("errcode"); System.err.println("GroupUtil|createGroup|errcode:"+errcode); } } /** * http请求方式: GET(请使用https协议) https://api.weixin.qq.com/cgi-bin/groups/get?access_token=ACCESS_TOKEN * @param token * @date 2016年12月21日下午3:09:58 void * @Des: */ public static void getGroup(String token){ String requestUrl=getGroup_url.replace("ACCESS_TOKEN", token); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.GET.name(), null); System.err.println("GroupUtil|getGroup|jsonObject.toString():"+jsonObject.toString()); } /** * @date 2016年12月21日下午3:15:45 * @param token * @param id void * @Des:删除分组 */ public static void deleteGroup(String token,int id){ String json = "{\"group\":{\"id\":"+id+"}}"; String requestUrl = deleteGroup_url.replace("ACCESS_TOKEN", token); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.POST.name(), json); System.err.println("GroupUtil|deleteGroup|jsonObject.toString():"+jsonObject.toString()); boolean containsValue = jsonObject.containsKey("errcode"); if(containsValue){ String errcode = jsonObject.getString("errcode"); System.err.println("GroupUtil|deleteGroup|errcode:"+errcode); } } /** * @date 2016年12月21日下午3:26:46 * @param token * @param openid * @param to_groupid void * @Des:移动用户分组 */ public static void addUserGroup(String token,String openid,int to_groupid){ String json ="{\"openid\":\""+openid+"\",\"to_groupid\":"+to_groupid+"}"; String requestUrl = addUserGroup_url.replace("ACCESS_TOKEN", token); JSONObject jsonObject = HttpRequestUtil.httpRequest(requestUrl, EnumMethod.POST.name(), json); System.err.println("GroupUtil|addUserGroup|jsonObject.toString():"+jsonObject.toString()); boolean containsValue = jsonObject.containsKey("errcode"); if(containsValue){ String errcode = jsonObject.getString("errcode"); System.err.println("GroupUtil|addUserGroup|errcode:"+errcode); } } public static void main(String[] args) { String token = "ykKuJB-03xENYJJFiR5aGvom2HHWTc5OM2aALMlzgW0sLTvZiGrRqFDl7Deu2T4aGEjTKmfjOHRitFSM6UmkE0wSTbw3gti4IgnjcaRgb-eel9_Sn42KDuHt0TJU6XC2PODdAIALKZ"; String groupNme ="java"; // createGroup(token, groupNme); getGroup(token); // deleteGroup(token, 102); // addUserGroup(token, "o1wQTvxxt1yhrZbvjNzpotqkOsfo", 100); } //移动用户分组成功 // GroupUtil|addUserGroup|jsonObject.toString():{"errcode":0,"errmsg":"ok"} //创建成功 // GroupUtil|createGroup|jsonObject.toString():{"group":{"id":102,"name":"java"}} //查询成功 // GroupUtil|getGroup|jsonObject.toString(): // {"groups":[{"id":0,"name":"未分组","count":9}, // {"id":1,"name":"黑名单","count":0}, // {"id":2,"name":"星标组","count":0} // ]} //删除成功 // GroupUtil|deleteGroup|jsonObject.toString():{"errcode":0,"errmsg":"ok"}/ }
8、部分代码下载:
http://download.csdn.net/detail/u014520797/9714496
9、补充
微信企业号回调接口配置http://blog.csdn.net/u014520797/article/details/49720601
微信服务号基本配置http://blog.csdn.net/u014520797/article/details/53725287
服务号demo下载:http://download.csdn.net/detail/u014520797/9714496
企业号demo下载:http://download.csdn.net/detail/u014520797/9726045
企业号回调接口demohttp://download.csdn.net/detail/u014520797/9252951