|
@@ -0,0 +1,237 @@
|
|
|
|
|
+package menu
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "encoding/json"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+
|
|
|
|
|
+ "github.com/silenceper/wechat/context"
|
|
|
|
|
+ "github.com/silenceper/wechat/util"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+const (
|
|
|
|
|
+ menuCreateURL = "https://api.weixin.qq.com/cgi-bin/menu/create"
|
|
|
|
|
+ menuGetURL = "https://api.weixin.qq.com/cgi-bin/menu/get"
|
|
|
|
|
+ menuDeleteURL = "https://api.weixin.qq.com/cgi-bin/menu/delete"
|
|
|
|
|
+ menuAddConditionalURL = "https://api.weixin.qq.com/cgi-bin/menu/addconditional"
|
|
|
|
|
+ menuDeleteConditionalURL = "https://api.weixin.qq.com/cgi-bin/menu/delconditional"
|
|
|
|
|
+ menuTryMatchURL = "https://api.weixin.qq.com/cgi-bin/menu/trymatch"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+//Menu struct
|
|
|
|
|
+type Menu struct {
|
|
|
|
|
+ *context.Context
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//reqMenu 设置菜单请求数据
|
|
|
|
|
+type reqMenu struct {
|
|
|
|
|
+ Button []*Button `json:"button,omitempty"`
|
|
|
|
|
+ MatchRule *MatchRule `json:"matchrule,omitempty"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//reqDeleteConditional 删除个性化菜单请求数据
|
|
|
|
|
+type reqDeleteConditional struct {
|
|
|
|
|
+ MenuID int64 `json:"menuid"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//reqMenuTryMatch 菜单匹配请求
|
|
|
|
|
+type reqMenuTryMatch struct {
|
|
|
|
|
+ UserID string `json:"user_id"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//resConditionalMenu 个性化菜单返回结果
|
|
|
|
|
+type resConditionalMenu struct {
|
|
|
|
|
+ Button []Button `json:"button"`
|
|
|
|
|
+ MatchRule MatchRule `json:"matchrule"`
|
|
|
|
|
+ MenuID int64 `json:"menuid"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//resMenuTryMatch 菜单匹配请求结果
|
|
|
|
|
+type resMenuTryMatch struct {
|
|
|
|
|
+ util.CommonError
|
|
|
|
|
+
|
|
|
|
|
+ Button []Button `json:"button"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//ResMenu 查询菜单的返回数据
|
|
|
|
|
+type ResMenu struct {
|
|
|
|
|
+ util.CommonError
|
|
|
|
|
+
|
|
|
|
|
+ Menu struct {
|
|
|
|
|
+ Button []Button `json:"button"`
|
|
|
|
|
+ MenuID int64 `json:"menuid"`
|
|
|
|
|
+ } `json:"menu"`
|
|
|
|
|
+ conditionalmenu []resConditionalMenu `json:"conditionalmenu"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//MatchRule 个性化菜单规则
|
|
|
|
|
+type MatchRule struct {
|
|
|
|
|
+ GroupID int32 `json:"group_id,omitempty"`
|
|
|
|
|
+ Sex int32 `json:"sex,omitempty"`
|
|
|
|
|
+ Country string `json:"country,omitempty"`
|
|
|
|
|
+ Province string `json:"province,omitempty"`
|
|
|
|
|
+ City string `json:"city,omitempty"`
|
|
|
|
|
+ ClientPlatformType int32 `json:"client_platform_type,omitempty"`
|
|
|
|
|
+ Language string `json:"language,omitempty"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//NewMenu 实例
|
|
|
|
|
+func NewMenu(context *context.Context) *Menu {
|
|
|
|
|
+ menu := new(Menu)
|
|
|
|
|
+ menu.Context = context
|
|
|
|
|
+ return menu
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//SetMenu 设置按钮
|
|
|
|
|
+func (menu *Menu) SetMenu(buttons []*Button) error {
|
|
|
|
|
+ accessToken, err := menu.GetAccessToken()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ uri := fmt.Sprintf("%s?access_token=%s", menuCreateURL, accessToken)
|
|
|
|
|
+ reqMenu := &reqMenu{
|
|
|
|
|
+ Button: buttons,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response, err := util.PostJSON(uri, reqMenu)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ var commError util.CommonError
|
|
|
|
|
+ err = json.Unmarshal(response, &commError)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if commError.ErrCode != 0 {
|
|
|
|
|
+ return fmt.Errorf("SetMenu Error , errcode=%d , errmsg=%s", commError.ErrCode, commError.ErrMsg)
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//GetMenu 获取菜单配置
|
|
|
|
|
+func (menu *Menu) GetMenu() (resMenu ResMenu, err error) {
|
|
|
|
|
+ var accessToken string
|
|
|
|
|
+ accessToken, err = menu.GetAccessToken()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ uri := fmt.Sprintf("%s?access_token=%s", menuGetURL, accessToken)
|
|
|
|
|
+ var response []byte
|
|
|
|
|
+ response, err = util.HTTPGet(uri)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ err = json.Unmarshal(response, &resMenu)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if resMenu.ErrCode != 0 {
|
|
|
|
|
+ err = fmt.Errorf("GetMenu Error , errcode=%d , errmsg=%s", resMenu.ErrCode, resMenu.ErrMsg)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ return
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//DeleteMenu 删除菜单
|
|
|
|
|
+func (menu *Menu) DeleteMenu() error {
|
|
|
|
|
+ accessToken, err := menu.GetAccessToken()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ uri := fmt.Sprintf("%s?access_token=%s", menuDeleteURL, accessToken)
|
|
|
|
|
+ response, err := util.HTTPGet(uri)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ var commError util.CommonError
|
|
|
|
|
+ err = json.Unmarshal(response, &commError)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if commError.ErrCode != 0 {
|
|
|
|
|
+ return fmt.Errorf("GetMenu Error , errcode=%d , errmsg=%s", commError.ErrCode, commError.ErrMsg)
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//AddConditional 添加个性化菜单
|
|
|
|
|
+func (menu *Menu) AddConditional(buttons []*Button, matchRule *MatchRule) error {
|
|
|
|
|
+ accessToken, err := menu.GetAccessToken()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ uri := fmt.Sprintf("%s?access_token=%s", menuAddConditionalURL, accessToken)
|
|
|
|
|
+ reqMenu := &reqMenu{
|
|
|
|
|
+ Button: buttons,
|
|
|
|
|
+ MatchRule: matchRule,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response, err := util.PostJSON(uri, reqMenu)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ var commError util.CommonError
|
|
|
|
|
+ err = json.Unmarshal(response, &commError)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if commError.ErrCode != 0 {
|
|
|
|
|
+ return fmt.Errorf("AddConditional Error , errcode=%d , errmsg=%s", commError.ErrCode, commError.ErrMsg)
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//DeleteConditional 删除个性化菜单
|
|
|
|
|
+func (menu *Menu) DeleteConditional(menuID int64) error {
|
|
|
|
|
+ accessToken, err := menu.GetAccessToken()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ uri := fmt.Sprintf("%s?access_token=%s", menuDeleteConditionalURL, accessToken)
|
|
|
|
|
+ reqDeleteConditional := &reqDeleteConditional{
|
|
|
|
|
+ MenuID: menuID,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ response, err := util.PostJSON(uri, reqDeleteConditional)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ var commError util.CommonError
|
|
|
|
|
+ err = json.Unmarshal(response, &commError)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if commError.ErrCode != 0 {
|
|
|
|
|
+ return fmt.Errorf("DeleteConditional Error , errcode=%d , errmsg=%s", commError.ErrCode, commError.ErrMsg)
|
|
|
|
|
+ }
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//MenuTryMatch 菜单匹配
|
|
|
|
|
+func (menu *Menu) MenuTryMatch(userID string) (buttons []Button, err error) {
|
|
|
|
|
+ var accessToken string
|
|
|
|
|
+ accessToken, err = menu.GetAccessToken()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ uri := fmt.Sprintf("%s?access_token=%s", menuTryMatchURL, accessToken)
|
|
|
|
|
+ reqMenuTryMatch := &reqMenuTryMatch{userID}
|
|
|
|
|
+ var response []byte
|
|
|
|
|
+ response, err = util.PostJSON(uri, reqMenuTryMatch)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ var resMenuTryMatch resMenuTryMatch
|
|
|
|
|
+ err = json.Unmarshal(response, &resMenuTryMatch)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if resMenuTryMatch.ErrCode != 0 {
|
|
|
|
|
+ err = fmt.Errorf("MenuTryMatch Error , errcode=%d , errmsg=%s", resMenuTryMatch.ErrCode, resMenuTryMatch.ErrMsg)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ buttons = resMenuTryMatch.Button
|
|
|
|
|
+ return
|
|
|
|
|
+}
|