【golang】动态生成微信小程序二维码实战上:golang整合github.com/silenceper/wechat/v2 实现生成 小程序二维码图片

项目背景

在自研的系统,需要实现类似草料二维码的功能

将我们自己的小程序,通过代码生成相想要的小程序二维码

代码已经上传到 Github 需要的朋友可以自取
https://github.com/ctra-wang/wechat-mini-qrcode

一、源生实现

通过源生API实现对小程序二维码的生成

1、官方API

官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/createQRCode.html

下面是三个官方的API 可以根据需求进行调用

复制代码
CreateWXAQRCodeURL   = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%s"
GetWXACodeURL        = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s"
GetWXACodeUnlimitURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"

2、golang 实现源码

go 复制代码
package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
)

const (
	CreateWXAQRCodeURL   = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%s"
	GetWXACodeURL        = "https://api.weixin.qq.com/wxa/getwxacode?access_token=%s"
	GetWXACodeUnlimitURL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"
)

const (
	// 替换成你的小程序 appiId 和 secretKey
	MINI_APP_LATEST_ID     string = "wxxxxf6"
	MINI_APP_LATEST_SECRET string = "7dfxxx64a"
)

// 通过 普通的源生请求
func main() {
	// 要生成二维码的路径和参数
	_, err := GetQRCode(58)
	if err != nil {
		fmt.Println("Error getting QR code:", err)
		return
	}

}

func GetQRCode(id int) ([]byte, error) {
	//上面生成的access code 判断为空时重新请求
	accessToken, err := requestToken(MINI_APP_LATEST_ID, MINI_APP_LATEST_SECRET)
	if err != nil {
		return nil, err
	}
	strUrl := fmt.Sprintf(CreateWXAQRCodeURL, accessToken)

	// todo: 这里有bug待完善
	parm := make(map[string]string)
	// path 要以?开始
	parm["path"] = fmt.Sprintf("?pathName=/race/pages/group&id=%d", id)
	// page 起始位置不需要 /
	parm["page"] = fmt.Sprintf("pages/home/index")
	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())
	}
	// 发起 post 请求
	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())
	}

	// 生成图片
	png, err := os.Create("data.png")
	_, err2 := png.Write(body)

	if err2 != nil {
		log.Fatal(err2)
	}
	fmt.Println("QR code saved successfully!")
	return nil, nil
}

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
	}
}

3、代码分析 io.ReadAll 文件流

通过接口返回的 resp中的body,通过 io.ReadAll() 方法返回的body为二进制

go 复制代码
body, err := io.ReadAll(resp.Body)
if err != nil {
	return nil, errors.New("get QRCode err :" + err.Error())
}

我们需要通过文件去接收这个文件流

go 复制代码
// 生成图片
png, err := os.Create("data.png")
_, err2 := png.Write(body)

这样我们就可以看到一个data.png的文件产生

二、框架实现

1、官方API

作者: silenceper/wechat

github地址:https://github.com/silenceper/wechat/v2

文档地址:https://silenceper.com/wechat/miniprogram/qrcode.html

2、golang 实现源码

go 复制代码
package main

import (
	"fmt"
	"github.com/silenceper/wechat/v2"
	"github.com/silenceper/wechat/v2/cache"
	miniConfig "github.com/silenceper/wechat/v2/miniprogram/config"
	"github.com/silenceper/wechat/v2/miniprogram/qrcode"
	"log"
	"os"
)

const (

	// 替换成你的小程序 appiId 和 secretKey
	MINI_APP_LATEST_ID     string = "wxxxxf6"
	MINI_APP_LATEST_SECRET string = "7dfxxx64a"
)

func main() {
	// 初始化 Wechat 实例
	wc := wechat.NewWechat()
	//这里本地内存保存access_token,也可选择redis,memcache或者自定cache
	memory := cache.NewMemory()
	//token, _ := requestToken(MINI_APP_LATEST_ID, MINI_APP_LATEST_SECRET)
	cfg := &miniConfig.Config{
		AppID:     MINI_APP_LATEST_ID,
		AppSecret: MINI_APP_LATEST_SECRET,
		Cache:     memory,
	}

	//officialAccount := wc.GetOfficialAccount(cfg)
	mini := wc.GetMiniProgram(cfg)
	fmt.Println("------------")
	qcode := mini.GetQRCode()
	res, err := qcode.CreateWXAQRCode(qrcode.QRCoder{
		Page: "pages/home/index",
		Path: "?pathName=/race/pages/group&id=58",
		//CheckPath:  nil,
		Width: 300,
		//Scene: "pathName=/race/pages/group&id=58",
		//AutoColor:  false,
		//LineColor:  nil,
		//IsHyaline:  false,
		//EnvVersion: "",
	})
	if err != nil {
		return
	}
	// 生成图片
	png, err := os.Create("race.png")
	_, err2 := png.Write(res)

	if err2 != nil {
		log.Fatal(err2)
	}

	fmt.Println("QR code saved successfully!")

}
相关推荐
打小就很皮...1 小时前
HBuilder 发行Android(apk包)全流程指南
前端·javascript·微信小程序
说私域5 小时前
定制开发开源AI智能名片驱动下的海报工厂S2B2C商城小程序运营策略——基于社群口碑传播与子市场细分的实证研究
人工智能·小程序·开源·零售
roman_日积跬步-终至千里8 小时前
【Go语言基础【9】】字符串格式化与输入处理
golang
说私域11 小时前
内容力重塑品牌增长:开源AI大模型驱动下的智能名片与S2B2C商城赋能抖音生态种草范式
人工智能·小程序·开源·零售
比特森林探险记12 小时前
Go 中的 Map 与字符处理指南
c++·算法·golang
比特森林探险记12 小时前
Go 中 map 的双值检测写法详解
java·前端·golang
前端缘梦13 小时前
微信小程序登录方案实践-从账号体系到用户信息存储
前端·微信小程序
哆啦A梦158813 小时前
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/[email protected] 更换为 go-ansible/@v1.1.7
开发语言·golang·ansible
LanLance13 小时前
ES101系列09 | 运维、监控与性能优化
java·运维·后端·elasticsearch·云原生·性能优化·golang
Toby_00914 小时前
tpc udp http
其他·golang