有奖捉虫:办公协同&微信生态&物联网文档专题 HOT

准备工作

1. 阅读 微信开放文档 JS-SDK 使用权限签名算法,根据文档提供接口,返回 jsapi_ticket。
2. 阅读 高清语音素材获取接口文档,根据文档提供接口,返回音频数据。
3. 登录公众号后台,在开发 > 开发管理 > 开发设置 > 开发者 ID 中获取公众号 appid appsecret。
注意:
接口需保证下载表现和直接在浏览器调用微信侧接口 https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=ACCESS_TOKEN&media_id=MEDIA_ID 一致,即在浏览器调用接口后下载二进制文件,文件内容需与直接调用微信接口内容一致,否则 SDK 内部无法正常下载及解析音频内容。

获取 access_token

参考 获取 access_token ,获取到 access_token。access_token 用于获取 jsapi_ticket 和 mediaUrl。
let request = require('request-promise')

async function get_token() {
return new Promise((resolve) => {
const appid = ''
const secret = ''
request.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`, (err, res, body) => {
resolve(JSON.parse(body).access_token);
});
})
}
注意:
access_token 日调用上限为2000次,需业务侧做好缓存和更新逻辑。
let request = require('request-promise')
// 用redis来做缓存
let redis = require('redis')
let redisClient = redis.createClient();
redisClient.on('error', err => {
console.log(err)
})
redisClient.connect() // 连接

async function token_cache() {
return new Promise(async (resolve) => {
let token = await redisClient.get("access_token")
if (token == null) {
let access_token = await get_token()
await redisClient.set("access_token", access_token);
await redisClient.expire("access_token", 7000)
resolve(access_token)
} else {
resolve(token)
}
})
}

jsapi_ticket 接口

参考 JS-SDK 使用权限签名算法,获取 jsapi_ticket,将数据存到缓存中,以便下次使用。
let request = require('request-promise')
let express = require('express')
let server = express();
const cors = require('cors'); // 跨域
server.use(cors());

let redis = require('redis')
let redisClient = redis.createClient();
redisClient.on('error', err => {
console.log(err)
})
redisClient.connect() // 连接

server.get('/getTicket', async (req, resp) => {
let jsapi_ticket = await redisClient.get("jsapi_ticket")
if (jsapi_ticket ==null){
const token = await token_cache()
const ticket_url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`
request.get(ticket_url, async (err, res, body) => {
await redisClient.set("jsapi_ticket", JSON.parse(body).ticket);
await redisClient.expire("jsapi_ticket", 7000)
resp.send(JSON.parse(body).ticket)
});
}
else{
resp.send(jsapi_ticket)
}
})

server.listen(5050, () => {
console.log('服务器已就绪')
})

module.exports = server;

mediaUrl 接口

参考 获取高清语音素材 ,获取音频数据。
let request = require('request-promise')
let express = require('express')
let server = express();
const cors = require('cors');
server.use(cors());

server.get('/getMedia', async (req, resp) => {
const token = await token_cache()
let id = req.query.mediaId;
const mediaUrl = `https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=${token}&media_id=${id}`;
request.get(mediaUrl).pipe(resp);
})

server.listen(5050, () => {
console.log('服务器已就绪')
})

module.exports = server;

Node.js 完整示例

使用 express 框架,需要 npm 安装如下依赖。
npm install request-promise express cors redis
示例代码
let request = require('request-promise')
let express = require('express')
let server = express();
const cors = require('cors');
server.use(cors());

let redis = require('redis')
let redisClient = redis.createClient();
redisClient.on('error', err => {
console.log(err)
})
redisClient.connect() // 连接

async function get_token() {
return new Promise((resolve) => {
const appid = ''
const secret = ''
request.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`, (err, res, body) => {
resolve(JSON.parse(body).access_token);
});
})
}

async function token_cache() {
return new Promise(async (resolve) => {
let token = await redisClient.get("access_token")
if (token == null) {
let access_token = await get_token()
await redisClient.set("access_token", access_token);
await redisClient.expire("access_token", 7000)
resolve(access_token)
} else {
resolve(token)
}
})
}

server.get('/getTicket', async (req, resp) => {
let jsapi_ticket = await redisClient.get("jsapi_ticket")
if (jsapi_ticket ==null){
const token = await token_cache()
const ticket_url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`
request.get(ticket_url, async (err, res, body) => {
await redisClient.set("jsapi_ticket", JSON.parse(body).ticket);
await redisClient.expire("jsapi_ticket", 7000)
resp.send(JSON.parse(body).ticket)
});
}
else{
resp.send(jsapi_ticket)
}
})

server.get('/getMedia', async (req, resp) => {
const token = await token_cache()
let id = req.query.mediaId;
const mediaUrl = `https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=${token}&media_id=${id}`;
request.get(mediaUrl).pipe(resp);
})

server.listen(5050, () => {
console.log('服务器已就绪')
})

module.exports = server;