前提:需要小程序和公众号绑定在同一开放平台!
简述实现步骤:
1.获取accessToken
2.获取公众号关注用户的openid
3.用openid和accessToken去获取公众号关注用户的基本信息(主要是拿到unionid)
4.小程序端获取unionid
5.查找存储公众号用户信息的数据库
6.如果unionid有值,代表用户已经关注公众号
具体步骤:
1.获取accessToken,存储在数据库
微信开放文档
const cloud = require('wx-server-sdk')
const request = require('request')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
const APPID = "从开发者平台获取"
const secret = "从开发者平台获取"
/** 每隔1小时获取接口调用权限Token */
exports.main = async () => {
const url = "https://api.weixin.qq.com/cgi-bin/token"
const paramObj = {
grant_type: "client_credential",
appid: APPID,
secret: secret,
}
let accessTokenObj = await requestFun(url, paramObj)
accessTokenObj = JSON.parse(accessTokenObj)
console.log(accessTokenObj)
let addRes = null
try {
addRes = await addAccessToken(accessTokenObj)
console.log("===== 插入accessToken结果 =====", addRes)
} catch (error) {
addRes = await addAccessToken(accessTokenObj)
// sendErrorMsg(addRes.errMsg)
console.log("===== 插入accessToken结果 =====", error)
}
const totalObj = await getAccessToken(accessTokenObj.access_token)
if (totalObj.total <= 0) {
addRes = await addAccessToken(accessTokenObj)
// sendErrorMsg(addRes.errMsg)
console.log("===== 插入accessToken结果 =====", addRes)
}
return addRes
}
/**
* 发起网络请求
* @param {object} paramObj 请求的参数对象
*/
const requestFun = (url, paramObj) => {
// 请求数据
const opt = {
timeout: 5000, // 设置超时
method: 'GET', //请求方式
url: url,
qs: paramObj
}
// 发起请求
return new Promise((resolve, reject) => {
request(opt, (error, response, data) => {
resolve(data)
})
})
}
/** 将token插入数据库 */
const addAccessToken = async (addObj) => {
const nowTime = new Date().getTime()
addObj.createTime = nowTime
return await db.collection("AccessToken")
.add({
data: addObj
})
}
/** 判断是否插入成功 */
const getAccessToken = async (accessToken) => {
return db.collection("AccessToken").where({
access_token: accessToken
}).count()
}
AppID和AppSecret在下图这里获取
https://mp.weixin.qq.com/
?2.获取公众号关注用户的openid
微信开放文档(官方文档看这里)
const cloud = require('wx-server-sdk')
const request = require('request')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
const db = cloud.database()
/**
* 获取公众号的openid列表
*/
exports.main = async () => {
const accessTokenObj = await getAccessToken()
const accessToken = accessTokenObj.data[0].access_token //取最新的token
const nextOpenidObj = await getOpenidList(accessToken)
return nextOpenidObj
}
/**
* 从数据库获取accessToken
*/
const getAccessToken = async () => {
return await db.collection("AccessToken")
.where({})
.orderBy('createTime', 'desc') //降序排序,获取最新的token
.limit(1)
.get()
}
/**
* 从数据库拿到最后一个openid
* 用于更新每日新增的关注用户数据
* */
const getNextOpenid = async () => {
return await db.collection("publicUserList")
.where({})
.orderBy('createTime', 'desc')
.limit(1)
.get()
}
/**
* 执行获取新的openid 函数
* 每日执行一次,每次最多更新1300条
* @param {string} accessToken 接口申请Token
* */
const getOpenidList = async (accessToken) => {
const nextOpenidObj = await getNextOpenid()
let nextOpenid = ""
if (nextOpenidObj.data.length >= 1) { //如果有值
nextOpenid = nextOpenidObj.data[0].openid //获取排序完最新的用户openid
}
const url = "https://api.weixin.qq.com/cgi-bin/user/get"
const paramObj = {
access_token: accessToken,
next_openid: nextOpenid
}
const resultObj = await requestFun(url, paramObj) //去公众号请求数据
if (resultObj.count === 0) {
return "无需要获取的新用户"
}
const openidArray = resultObj.data.openid
let num = 0
if (openidArray.length > 1000) { //如果大于1000条就只更新1000条
num = 1000
} else {
num = openidArray.length
}
for (let i = 0; i < num; i++) {
const nowTime = new Date().getTime()
const addObj = {
openid: openidArray[i],
isGet: false,
createTime: nowTime,
updateTime: nowTime,
deleteTime: null
}
await addOpenid(addObj) //插入到到publicUserList(关众号关注用户)数据库
}
/**
* 发起网络请求
* @param {object} paramObj 请求的参数对象 // paramObj:accessToken openid
*/
const requestFun = (url, paramObj) => {
// 请求数据
const opt = {
timeout: 5000, // 设置超时
method: 'GET', //请求方式
url: url,
qs: paramObj
}
// 发起请求
return new Promise((resolve, reject) => { //返回查询公众号关注用户的数据
request(opt, (error, response, data) => { //error response 请求失败的响应报文
resolve(JSON.parse(data))
})
})
}
/**
* 将获取到的服务号openid数据插入数据库
*/
const addOpenid = async (addObj) => {
await db.collection("publicUserList").add({
data: addObj
})
}
return {
nextOpenid: openidArray[num - 1],
resultObj: resultObj
}
}
到此已经获取到公众号关注用户的openid了, 因为要拿到公众号关注用户的unionid需要拿access_token 和 openid去换 ,具体请看这里微信开放文档。
3.用openid和accessToken去获取公众号关注用户的基本信息(主要是拿到unionid)
const requestFun = (url, qs) => {
// 请求数据
const opt = {
timeout: 5000, // 设置超时
method: 'GET', //请求方式
url:'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN',//批量获取,也可单条获取,具体看文档
qs: {access_token,openid}//这里填获取到最新的token和所有openid(建议直接传对象进来)
}
// 发起请求
return new Promise((resolve, reject) => {
request(opt, (error, response, data) => {
resolve(JSON.parse(data))
})
})
}
到这return回来就可以得到unionid了,然后把unionid插进你的公众号关注用户数据库
5.查找存储公众号用户信息的数据库
如果你的小程序和公众号已经绑定在同一开放平台,那么就可以通过云函数直接获取小程序端的unionid了
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: '填你的env'
})
// 云函数入口函数
exports.main = async () => {
const wxContext = cloud.getWXContext()
return {
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID, //这里是unionid
}
}
调用上面这个云函数即可获取unionid
5.查找存储公众号用户信息的数据库
/**
* 判断用户是否关注了公众号
* @param {string} unionid 用户的uniodid
*/
const checkAboutPublic = async (unionid) => {
const aboutTotalObj = await dbUtils.count("publicUserList", {
unionid,
subscribe: 1 //subscribe 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。
})
return aboutTotalObj.total >= 1 //会返回一个类型为number的total,如果值大于0代表用户关注了公众号
}
调用这个函数,传小程序获取到的unionid进来和携带一个subscribec参数到publicUserList数据库(因为我把公众号关注用户和公众号获取的unionid放在这个表)
6.如果total的值大于0,代表用户已经关注公众号
|