微信公众号开发中,需要发送http请求来设置菜单。写了一个程序放在这里,避免每次用postman发请求的麻烦。
需要在程序目录下面放置menu.txt文件,内容就是微信公众号开发中菜单的json格式,比如:
{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "name":"菜单", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"view", "name":"视频", "url":"http://v.qq.com/" }, { "type":"click", "name":"赞一下我们", "key":"V1001_GOOD" }] }] }
golang代码如下:
package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
)
const (
WX_ID = "xxxxxxxx"
WX_SECRECT = "xxxxxxxxxxxxxxxxxxxxxxxx"
REQ_TOEKN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
GET_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s"
SET_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s"
)
func readMenu(path string) []byte {
fi, err := os.Open(path)
if err != nil {
fmt.Println("read file error:", err)
return nil
}
defer fi.Close()
fd, err := ioutil.ReadAll(fi)
if err != nil {
fmt.Println("read menu file error:", err)
return nil
}
return fd
}
func GetToken() string {
url := fmt.Sprintf(REQ_TOEKN_URL, WX_ID, WX_SECRECT)
resp, err := http.Get(url)
if err != nil {
fmt.Println("get token failed")
return ""
}
defer resp.Body.Close()
decoder := json.NewDecoder(resp.Body)
var retMap map[string]interface{}
err = decoder.Decode(&retMap)
if nil != err {
bodySlice, err := ioutil.ReadAll(resp.Body)
fmt.Println("json decode error:", err, string(bodySlice))
return ""
}
token, ok := retMap["access_token"].(string)
if !ok {
fmt.Println("ret package error:", retMap)
return ""
}
return token
}
func SetMenu(file string, token string) bool {
menuSlice := readMenu(file)
if nil == menuSlice {
return false
}
url := fmt.Sprintf(SET_MENU_URL, token)
req, err := http.NewRequest("POST", url, bytes.NewReader(menuSlice))
if nil != err {
fmt.Println("new http request error:", err)
return false
}
client := &http.Client{}
resp, err := client.Do(req)
if nil != err {
fmt.Println("http client do error:", err)
return false
}
defer resp.Body.Close()
decoder := json.NewDecoder(resp.Body)
var retMap map[string]interface{}
err = decoder.Decode(&retMap)
if nil != err {
bodySlice, err := ioutil.ReadAll(resp.Body)
fmt.Println("json decode error:", err, string(bodySlice))
return false
}
fmt.Println("set menu ret:", retMap)
return true
}
func GetMenu(token string) {
url := fmt.Sprintf(GET_MENU_URL, token)
resp, err := http.Get(url)
if nil != err {
fmt.Println("http get error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("read http body error:", err)
return
}
var menuMap map[string]interface{}
err = json.Unmarshal(body, &menuMap)
if err != nil {
fmt.Println("json decode menu failed:", err)
return
}
menuIndent, err := json.MarshalIndent(menuMap, "", " ")
if err != nil {
fmt.Println("json encode format failed:", err)
return
}
fmt.Println("menu info:")
fmt.Println(string(menuIndent))
}
func main() {
menuFile := flag.String("menu", "menu.txt", "menu file path")
setMenu := flag.String("set", "yes", "need to set menu")
flag.Parse()
accessToken := GetToken()
if "" == accessToken {
fmt.Println("get accecss token failed")
return
}
if "yes" == *setMenu {
SetMenu(*menuFile, accessToken)
}
GetMenu(accessToken)
}
python代码如下:
import json
import urllib2
import requests
import getopt
import sys
wxid = "xxxxxxxx"
wxsecrect = "xxxxxxxxxxxxxxxxxxxxxx"
reqTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
getMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s"
setMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%s"
def main(argv):
try:
opts, args = getopt.getopt(argv, "hr", ["help", "read"])
except getopt.GetoptError:
usage()
sys.exit(2)
needSet = True
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-r", "--read"):
needSet = False
fileObj = open("menu.txt")
try:
menuText = fileObj.read()
finally:
fileObj.close()
url = reqTokenUrl % (wxid, wxsecrect)
retStr = urllib2.urlopen(url).read()
ret = json.loads(retStr)
token = ret["access_token"]
if needSet:
url = setMenuUrl % token
resp = requests.post(url, data=menuText)
print resp.text
url = getMenuUrl % token
retStr = urllib2.urlopen(url).read()
print retStr
if __name__ == "__main__":
main(sys.argv[1:])