加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

使用golang快速开发微信公众平台(三):定制菜单

发布时间:2020-12-16 18:26:15 所属栏目:大数据 来源:网络整理
导读:在搞定使用golang快速开发微信公众平台(二):获取accessToken后,我们可以开始着手自定义菜单 自定义菜单简单粗暴,post请求里塞入要定义的菜单即可。 开始搓代码 func PushWxMenuCreate(accessToken string,menuJsonBytes []byte) error { postReq,err := ht

在搞定使用golang快速开发微信公众平台(二):获取accessToken后,我们可以开始着手自定义菜单


自定义菜单简单粗暴,post请求里塞入要定义的菜单即可。

开始搓代码

func PushWxMenuCreate(accessToken string,menuJsonBytes []byte) error {

    postReq,err := http.NewRequest("POST",strings.Join([]string{"https://api.weixin.qq.com/cgi-bin/menu/create","?access_token=",accessToken},""),bytes.NewReader(menuJsonBytes))

    if err != nil {
        fmt.Println("向微信发送菜单建立请求失败",err)
        logUtils.GetLog().Error("向微信发送菜单建立请求失败",err)
        return err
    }

    postReq.Header.Set("Content-Type","application/json; encoding=utf-8")

    client := &http.Client{}
    resp,err := client.Do(postReq)
    if err != nil {
        fmt.Println("client向微信发送菜单建立请求失败",err)
        logUtils.GetLog().Error("client向微信发送菜单建立请求失败",err)
        return err
    } else {
        fmt.Println("向微信发送菜单建立成功")
    }
    defer resp.Body.Close()

    return nil
}

func createWxMenu(o orm.Ormer) {

    //btn1 := models.Btn{Name: "进入商城",Url: "http://www.baidu.com/",Btype: "view"}
    //btn2 := models.Btn{Name: "会员中心",Key: "molan_user_center",Btype: "click"}
    //btn3 := models.Btn{Name: "我的",Url: "http://www.baidu.com/user_view",Btype: "view"}
    //
    //btns := []models.Btn{btn1,btn2,btn3}
    //wxMenu := models.WxMenu{Button: btns}
    //menuJsonBytes,err := json.Marshal(wxMenu)

    menuStr := `{
            "button": [
            {
                "name": "进入商城","type": "view","url": "http://www.baidu.com/"
            },{

                "name":"管理中心","sub_button":[
                        {
                        "name": "用户中心","type": "click","key": "molan_user_center"
                        },{
                        "name": "公告","key": "molan_institution"
                        }]
            },{
                "name": "资料修改","url": "http://www.baidu.com/user_view"
            }
            ]
        }`

    //if err == nil {

    //fmt.Println("生成的菜单json--->",menuStr)

    at := models.WxAccessToken{Id: 1}
    o.ReadOrCreate(&at,"id")
    //发送建立菜单的post请求
    WxPlatUtil.PushWxMenuCreate(at.AccessToken,[]byte(menuStr))
    //} else {
    //  logUtils.GetLog().Error("微信菜单json转换错误",err)
    //}
}

使用struct来生成json收到了惨不忍睹的效果,于是我干脆粗暴的把json直接写出来传进去。。。

用户在点击菜单的时候,会把响应信息以post请求的方式发送到我们在服务器配置中填写的URL中去,即使用beego快速开发微信公众平台(一):开启服务器配置中的 /wx_connect。而这一点文档压根不提,如果你是上来就做的支付功能,做到这一步一定会问候文档作者的八辈祖宗。

好在我们机智的把支付功能放在了后面,并未对咱们的思路造成混乱,所以接下来还是无压力的。

当用户点击菜单,微信服务器会post过来一个xml,类似这样:

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[FromUser]]></FromUserName>
<CreateTime>123456789</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[VIEW]]></Event>
<EventKey><![CDATA[www.qq.com]]></EventKey>
<MenuId>MENUID</MenuId>
</xml>

我们可以找到是发给谁的(ToUserName) 哪个用户触发的(FromUserName) 通过什么方式触发的(Event EventKey),解析这个xml就行

都闪开 我要搓代码了:

WxConnect.go

//type WxMenuEvent struct {
// ToUserName string `xml:"ToUserName"`
// FromUserName string `xml:"FromUserName"`
// CreateTime int64 `xml:"CreateTime"`
// MsgType string `xml:"MsgType"`
// Event string `xml:"Event"` //VIEW 
// EventKey string `xml:"EventKey"`
// MenuId string `xml:"MenuId"`
// ScanCodeInfo *ScanCodeInfo `xml:"ScanCodeInfo"` //专属于扫码
// Content string `xml:"Content"`
// Ticket string `xml:"Ticket"`
//}
//type ScanCodeInfo struct {
// ScanType string `xml:"ScanType"`
// ScanResult string `xml:"ScanResult"`
//}
//微信菜单用户点击 扫码响应
func (c *WxConnectController) Post() {

    if bytes,err := ioutil.ReadAll(c.Ctx.Request.Body); err == nil {

        //解析xml
        wxEvent := new(models.WxMenuEvent)
        if err := xml.Unmarshal(bytes,wxEvent); err == nil {

            //处理菜单点击
            dealWithMenuEvent(&wxEvent)

        } else {
            fmt.Println("微信菜单用户点击、扫码响应错误",err)
        }
    } else {
        fmt.Println("微信菜单用户点击、扫码解析body错误",err)
    }

    c.EnableRender = false
}

func dealWithMenuEvent(wxEvent **models.WxMenuEvent){
    switch wxEvent.Event {
            case "VIEW"://说明是点击底部菜单栏进入商城页面
            case "CLICK"://点击按钮
                if strings.EqualFold(wxEvent.EventKey,"molan_user_center") {
                    //点击用户中心
                } else if strings.EqualFold(wxEvent.EventKey,"molan_institution") {
                    //点击公告
                }
            case "subscribe"://扫码

            if strings.Contains(wxEvent.EventKey,"qrscene") {
                //未关注过商城 扫描他人二维码首次关注
                upperId := strings.Split(wxEvent.EventKey,"_")[1]//EventKey:qrscene_16 这个16就是upper在数据库的id 注意不是wxid

            } else {
                //关注(扫官方二维码 而不是扫个人二维码)
            }


            case "SCAN"://已关注 扫描他人二维码
            }
}

这里扫码比较恶心,eventKey可以作为识别是当前用户扫哪个用户的码,qrscene_xxxx 这个xxxx是你自己设的,大家知道就行。
到这一步,响应基本算是走完了。

但是 GRD需求总是不放过我们

老板说了:我想知道是哪个用户点了某个按钮,然后根据不同用户给予不同的响应。
这就需要用到WxMenuEvent.FromUserName,这个FromUserName是用户openID,注意这玩意不是用户的微信号。

官网是这样写的:

快闪开我憋不住了:

func FetchWxInfoAndIcon(o orm.Ormer,openid,wxUserInforUrl string) (*models.WxUserInfo,error) {

    at := models.WxAccessToken{Id: 1}
    o.ReadOrCreate(&at,"id")

    requestLine := strings.Join([]string{wxUserInforUrl,at.AccessToken,"&openid=","&lang=zh_CN"},"")

    resp,err := http.Get(requestLine)
    if err != nil || resp.StatusCode != http.StatusOK {
        fmt.Println("发送get请求获取 wxUserInfo 错误",err)
        logUtils.GetLog().Error("发送get请求获取 wxUserInfo 错误",err)
        return nil,err
    }

    defer resp.Body.Close()
    body,err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("发送get请求获取 wxUserInfo 读取返回body错误",err)
        logUtils.GetLog().Error("发送get请求获取 wxUserInfo 读取返回body错误",err
    }

    if bytes.Contains(body,[]byte("errcode")) {

        ater := models.AccessTokenErrorResponse{}
        err = json.Unmarshal(body,&ater)

        if err != nil {
            fmt.Printf("发送get请求获取 wxUserInfo 的错误信息 %+vn",ater)
            logUtils.GetLog().Error("发送get请求获取 wxUserInfo 的错误信息 %+vn",ater)
            return nil,err
        }
        return nil,fmt.Errorf("%s",ater.Errmsg)

    } else {
        atr := models.WxUserInfo{}
        err = json.Unmarshal(body,&atr)
        if err != nil {
            fmt.Println("发送get请求获取 wxUserInfo 返回数据json解析错误",err)
            logUtils.GetLog().Error("发送get请求获取 wxUserInfo 返回数据json解析错误",err)
            return nil,0.0,err
        }
        return &atr,nil
    }
}

好了,我们现在拿到了用户的昵称头像,搞定收工

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读