7

带参数的微信小程序码服务端(golang)生成

 1 year ago
source link: https://ioridy.github.io/2023/03/17/qrcode-for-wechat-mini-program-with-golang/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

带参数的微信小程序码服务端(golang)生成

2023-03-17

微信小程序码共有3个接口可以生成:

  1. 获取小程序码
    POST https://api.weixin.qq.com/wxa/getwxacode?access_token=ACCESS_TOKEN
    该接口用于获取小程序码,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制

    path参数指定扫码进入的页面,最大长度 1024 字节,不能为空可以带参数page/example?foo=bar

  2. 获取不限制的小程序码
    POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
    该接口用于获取小程序码,适用于需要的码数量极多的业务场景。通过该接口生成的小程序码,永久有效,数量暂无限制

    page参数指定扫码进入的页面,非必要参数,不可以带参数page/example

  3. 获取小程序二维码
    POST https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=ACCESS_TOKEN
    获取小程序二维码,适用于需要的码数量较少的业务场景。通过该接口生成的小程序码,永久有效,有数量限制

    path参数指定扫码进入的页面,最大长度 128 字节,不能为空,可以带参数page/example?foo=bar

以上3个接口之间的差异主要在于参数以及可以生成的数量, 接口1和3整体差异比较少(path参数长度不同; 小程序码和小程序二维码),接口2生成数量不受限制,但是指定打开的页面的参数page不能带参数(可以考虑通过scene参数传递,我目前还没验证)

具体的差异和参数可以通过链接查看官方文档

Golang实现

我根据自己的需要,选择了接口1的形式来实现,其他的接口只是接口url和参数的差异,整体流程和调用方式都是一样的。

获取ACCESS_TOKEN

func requestToken(appid, secret string) (string, error) {
u, err := url.Parse("https://api.weixin.qq.com/cgi-bin/token")
if err != nil {
log.Fatal(err)
}
paras := &url.Values{}
//设置请求参数
paras.Set("appid", appid)
paras.Set("secret", secret)
paras.Set("grant_type", "client_credential")
u.RawQuery = paras.Encode()
resp, err := http.Get(u.String())
//关闭资源
if resp != nil && resp.Body != nil {
defer resp.Body.Close()
}
if err != nil {
return "", errors.New("request token err :" + err.Error())
}

jMap := make(map[string]interface{})
err = json.NewDecoder(resp.Body).Decode(&jMap)
if err != nil {
return "", errors.New("request token response json parse err :" + err.Error())
}
if jMap["errcode"] == nil || jMap["errcode"] == 0 {
accessToken, _ := jMap["access_token"].(string)
return accessToken, nil
} else {
//返回错误信息
errcode := jMap["errcode"].(string)
errmsg := jMap["errmsg"].(string)
err = errors.New(errcode + ":" + errmsg)
return "", err
}
}

获取小程序码

func GetQRCode(id string) ([]byte, error) {
//上面生成的access code 判断为空时重新请求
if appAccessTokenForClient == "" {
accessToken, err := requestToken(appId, appSecret)
if err != nil {
return nil, err
}
appAccessTokenForClient = accessToken
}
strUrl := fmt.Sprintf("https://api.weixin.qq.com/wxa/getwxacode?access_token=%s", appAccessTokenForClient)

parm := make(map[string]string)
parm["path"] = fmt.Sprintf("pages/index/index?id=%s", id)
jsonStr, err := json.Marshal(parm)
if err != nil {
return nil, errors.New("json Marshal QRCode paramter err :" + err.Error())
}
req, err := http.NewRequest("POST", strUrl, bytes.NewBuffer([]byte(jsonStr)))
if err != nil {
return nil, errors.New("get QRCode err :" + err.Error())
}

req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, errors.New("get QRCode err :" + err.Error())
}

defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.New("get QRCode err :" + err.Error())
}

return body, nil
}

整个过程主要在调试时比较费时间,微信接口返回的错误信息比较范,记录下主要遇到的几种问题

40159

{\"errcode\":40159,\"errmsg\":\"invalid length for path, or the data is not json string hint: [Id2VBa0339xa11]\"}

主要是检查传递的参数,特别是path对应的长度

我这边是因为从接口2修改为接口1,但是page参数名没有修改为path,导致系统判断path为空,一直提示此错误

40169

errCode: 40169 errMsg: "openapi.wxacode.getUnlimited:fail invalid length for scene, or the data is not json string rid: 62764ad3-09f60c12-58046222"

接口2中scene参数,最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&’()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK