微信公众号--菜单栏的坑


最近连着好几个需求都是和微信相关的,一个是小程序里面的客户会话,后面就是基于的H5开发。坑真多呀,踩了一个又一个。

简单说一下项目里面的需求,由于是小程序电商项目,主要通过好友扫自己的分销码下单并完成从而获得赚钱金额。在小程序首页会有弹框,就是自己的分销码,从而跳到客服消息,发送一个公众号的二维码,引导关注公众号。后面就是公众号里面的个性化菜单栏的实现了。





同样是从首页的弹框跳到客服消息,也是采用的SessionFrom 来实现的, 定义成 fenxiao_ 来识别


这地方主要是跳到客服消息页面给用户发送关注公众号的图片的一个逻辑,这个实现基本上没有什么坑的。给用户发送了公众号图片,就会引导用户关注公众号,现在问题来了,如何识别用户是通过扫码关注,还是通过搜索来关注公众号的呢?

[获取用户基本信息(UnionID机制)](%3Ca href=”https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839"%3Ehttps://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839%3C/a%3E)

一个用户可能关注多个公众号,用户的openid 是不一样的,但用户的UnionId 却是一样的,但要在微信开发平台里面进行绑定。用户关注公众号,通过该接口微信就返回一些用户的基本信息给我们,下面就有用户是通过哪种途径来关注公众号的。


而需求就是通过扫描关注公众号,给用户发送指定信息。

 


  /**
     * 关注事件
     *
     * @param map         事件信息
     * @param userInfo    用户信息
     * @param printWriter 输出流
     */
    @Override
    @Async
    public void subscribe(Map<String, String> map, JSONObject userInfo, PrintWriter printWriter) {
        // todo 公众号还待定 
        String wx_no = map.get("ToUserName");
//        String wx = "gh_xxxxxxxxx";
        String wx = "gh_2xxxxxxxxxx";
        String eventKey = map.get("EventKey");
        if (wx.equals(wx_no)) {    // 分销
            logger.info("进入分销方法:");
            logger.info("用户的基本信息:{}", userInfo);
            logger.info("用户扫码进入:{}", userInfo.get("subscribe_scene"));
            if (userInfo.get("subscribe_scene").equals("ADD_SCENE_QR_CODE")) {
                sendFenxiao(map, userInfo);
                sendFenxiaoTextMessage(map, userInfo);
            }
            return;
        }
    }

通过userInfo 获取subscribe_scene字段的值来判别用户是通过哪种途径来关注公众号的,ADD_SCENE_QR_CODE 通过扫描关注的。如果是就来下面的业务逻辑操作了。此时不用在二维码上下功夫。

在公众号里面,先显示一个菜单栏,然后点击之后,多出现一个收益的菜单栏。如图


通过点击 ,我要赚钱 这一个菜单栏,然后就变为 我要赚钱和查看收益2个菜单栏。 这个过程的实现就个性化菜单栏。
实现个性化菜单栏,主要是给用户打标签,哪些用户可以看见,哪些用户的是看不见的。

个性化菜单接口

而我们这个地方是用户点击“我要赚钱” 给用户生成一个分销码图片和文本消息并发送给用户,然后就变为2个菜单栏。
在点击的过程中,就要给用户打标签了,让用户能够点检后能看到2个菜单栏了。如果用户之前有其他标签,就先取消标签,然后重新给用户打标签。因为设置用户标签,这步操作要在最前面操作。

用户点检菜单栏实现个心化菜单栏的转变的方法,但由于微信在菜单栏这里有缓存,即使用户重新打了标签,不一定立马就能看的见个性化菜单栏。而官方给出的解释是24小时内可以看见。既然是缓存,可以通过取消关注,再次关注就可以看见了。

public void click(Map<String, String> map, JSONObject userInfo, PrintWriter printWriter) {
        logger.info("微信公众号菜单栏点击事件");
        //todo 点击菜单发送消息
        if (map.get("EventKey").equals("fenxiao_caidan1")) {
            if (null != userInfo.get("openid")) {
                Map<Object, Object> maps = new HashMap<>();
                maps.put("openid", userInfo.get("openid"));
                maps.put("unionid", userInfo.get("unionid"));
                maps.put("nickname", userInfo.get("nickname"));
                maps.put("headimgurl", userInfo.get("nickname"));
                maps.put("delFlag", "0");
                maps.put("source", "mmfa");
                JSONObject userres = HttpTools.doPost(GoodsSearchConstant.URL_POST_USERID_SAVE_DEV, maps);
                logger.info("增加新的用户到shopaccount表中:{}", userres);

                Integer a = Integer.valueOf(JedisUtils.get("fenxiaotag0"));
                Integer b = Integer.valueOf(JedisUtils.get("fenxiaotag1"));
                logger.info("查看收益的标签值为:{}", b);


                // 取消用户的标签

                /*JSONObject jsonObject = new JSONObject();
                List<String> openid_list = new ArrayList<>();
                openid_list.add(userInfo.get("openid").toString());
                jsonObject.put("openid_list", openid_list);
                jsonObject.put("tagid", a);
                wxConfigService.reloadMpToken(ConfigUtil.getProperty("fenh5appid"));
                String str = HttpTools.doPostSSL(WxConstants.URL_TAGS_MEMBERS + "?access_token=" + wxApiService.getFenxiaoH5Token(), jsonObject);
                if (str.contains("invalid credential, access_token is invalid or not latest")) {
                    wxConfigService.reloadMpToken(ConfigUtil.getProperty("fenh5appid"));
 
                    str = HttpTools.doPostSSL(WxConstants.URL_TAGS_MEMBERS + "?access_token=" + wxApiService.getFenxiaoH5Token(), jsonObject);
                }
                JSONObject j1 = JSONObject.parseObject(str);
                logger.info("取消用户标签返回值:{}", j1.getInteger("errcode"));*/

                // 如果取消成功就重新定义标签

                //  点击菜单栏 就打标签
                JSONObject object = new JSONObject();
                List<String> openid_lists = new ArrayList<>();
                openid_lists.add(userInfo.get("openid").toString());
                object.put("openid_list", openid_lists);
                object.put("tagid", b);
                wxConfigService.reloadMpToken(ConfigUtil.getProperty("fenh5appid"));
                String strtag = HttpTools.doPostSSL(WxConstants.URL_TAGS_BATCHTAGGING + "?access_token=" + wxApiService.getFenxiaoH5Token(), object);
                if (strtag.contains("invalid credential, access_token is invalid or not latest")) {
 
                    strtag = HttpTools.doPostSSL(WxConstants.URL_TAGS_BATCHTAGGING + "?access_token=" + wxApiService.getFenxiaoH5Token(), object);
                }
                JSONObject j2 = JSONObject.parseObject(strtag);
                if (j2.getInteger("errcode") == 0) {
                    sendImage(map, userInfo.get("openid").toString());
                    sendContext(map);
                }


            }
        }
    }
  

Integer a = Integer.valueOf(JedisUtils.get(“fenxiaotag0”));
Integer b = Integer.valueOf(JedisUtils.get(“fenxiaotag1”));

 这个地方获取的a,b值是用户的标签值,存放在redis 中,下面就看如何设置标签值。

用户标签管理



创建用户标签的实现方法,这步操作要在最前面,执行一次就可以了

/**
    * 创建标签
    *
    * @return
    */
   @RequestMapping(value = "/createTags", method = RequestMethod.GET)
   public Object createTags() {
       logger.info("==== 进入创建用户标签");
       List<JSONObject> list = new ArrayList<>();
       JSONObject jsonObject = new JSONObject();
       Map<Object, Object> tag = new HashMap<>();
       tag.put("name", "我要赚钱");
       jsonObject.put("tag", tag);
       list.add(jsonObject);

       JSONObject jsonObject2 = new JSONObject();
       Map<Object, Object> tag2 = new HashMap<>();
       tag2.put("name", "收益查看");
       jsonObject2.put("tag", tag2);
       list.add(jsonObject2);
       for (int i = 0; i < list.size(); i++) {
           if (null == JedisUtils.get("fenxiaotag" + i)) {
               String str = HttpTools.doPostSSL(WxConstants.URL_CREATE_TAGS + "?access_token=" + wxApiService.getFenxiaoH5Token(), list.get(i));
               JSONObject tags = (JSONObject) JSONObject.parseObject(str).get("tag");
               tags.getInteger("id");
               JedisUtils.set("fenxiaotag" + i, String.valueOf(tags.getInteger("id")));
           }
       }
       logger.info("=====成功创建用户标签");
       return RespResult.respOK("");

   }

实现个性化菜单栏最重要的一步就是给用户打标签.此处就踩坑了.开发微信公众号,官方文档要反复看几遍,不然到处都是坑,由于官方给出demo较少,还是自己多写写测试一下。


文章作者: coderpwh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 coderpwh !
  目录