本文记录如何使用腾讯云云函数生成小程序码
# 前言
之前写过一篇小程序云函数生成小程序码的文章,里面介绍了通过云调用wxacode.get 来生成小程序码的方法,因为采用的是小程序云开发,云调用是免服务端鉴权的,在云函数中使用云调用调用服务端接口无需换取 access_token,只要是在从小程序端触发的云函数中发起的云调用都经过微信自动鉴权,可以在登记权限后直接调用如发送模板消息等开放接口,所以比较方便,但是如果使用腾讯云云开发的话情况就变成了服务端调用了,需要自己在服务端进行小程序全局 access_token 获取,上一篇文章我们介绍了腾讯云云函数实现小程序全局 access_token 刷新 ,这就意味着我们拿到了接口调用凭证,接下来的操作就方便了。
# 程序思路
在云函数内获取接口调用凭证,根据传入参数(如页面路径、scene 值等)直接请求生成小程序码的接口返回图片 buffer 即可。
# 核心代码
请求小程序全局 access_token 并使用云数据库进行缓存,调用 wxacode.getUnlimited
来生成永久小程序码并返回至前端,具体代码如下。
- 信息已脱敏处理,放入了环境变量
'use strict';
const cloudbase = require("@cloudbase/node-sdk");
const rp = require('request-promise')
const app = cloudbase.init({
env: process.env.env
});
const db = app.database();
const appId = process.env.appId
const appSecrect = process.env.appSecrect
const tokenForUrl =
'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + appId + '&secret=' + appSecrect
const qrcodeUrl =
'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token='
exports.main = async (event, context) => {
let param = {}
if (event.queryStringParameters) {
param = { ...event.queryStringParameters }
} else {
param = { ...event }
}
let tokens = await db
.collection('access_tokens')
.get()
let codeToken = ''
if (tokens.data.length > 0) {
let expires_time = tokens.data[0].expires_time
if (parseInt(Date.now() / 1000) > expires_time + 3600) {
let tokenInfoNew = await rp({ url: tokenForUrl })
tokenInfoNew = JSON.parse(tokenInfoNew)
let expires_time = parseInt(Date.now() / 1000)
await db
.collection('access_tokens')
.doc(tokens.data[0]._id)
.update({
access_token: tokenInfoNew.access_token,
expires_time: expires_time
})
codeToken = tokenInfoNew.access_token
} else {
codeToken = tokens.data[0].access_token
}
} else {
let tokenInfoNew = await rp({ url: tokenForUrl })
tokenInfoNew = JSON.parse(tokenInfoNew)
let expires_time = parseInt(Date.now() / 1000)
await db.collection('access_tokens').add({
access_token: tokenInfoNew.access_token,
expires_time: expires_time
})
codeToken = tokenInfoNew.access_token
}
const codeOptions = {
method: 'POST',
url: qrcodeUrl + codeToken,
body: {
page: param.page || 'pages/index/main',
width: 280,
scene: param.scene || 'a=1',
},
json: true,
encoding: null,
}
let buffer = await rp(codeOptions)
return {
isBase64Encoded: true,
statusCode: 200,
headers: {
"content-type": "image/png"
},
body: buffer.toString('base64')
}
};
# 访问示例地址
https://tcb.xuedingmiao.com/mp_code?page=pages/blog/main&scene=tcb_mp_code.md (opens new window)