微信公众号推广码实现并统计人数 Node配Koa2也不错哦~~

304 阅读6分钟

需求:

公司最近需要一个功能,生成公众号推广码,让人去推广,最后计算每个推广人拉取的粉丝人数给对应的报酬。

解决办法:微信公众号使用access_token换取带参的二维码图片,然后使用这个二维码去推广让大家关注公众号,最后根据这个带参的二维码统计关注的人数和对应推广宣传的每个人拉取了多少个关注者!

一:准备工作

微信公众号需要可以使用推广支持接口权限,和获取access_token接口权限,还有自定义菜单的接口权限。一般有这个权限认证主体需要是公司,个人认证的是没有接口权限的。 image.png

二:配置工具

第一次掘金发布文章,格式这些可能不太好看,不太熟悉,大家见笑了。这里我使用的是NodeJS的koa2框架配置的微信公众号服务器,然后把消息处理都放到服务器上(配置了自定义菜单和自定义回复信息),Koa2属于NodeJS的一个框架方便开发,感兴趣的小伙伴可以自己了解了解,这里说一下配置过程和实现的原理。

步骤:

  1. 登陆微信公众号平台,开发——基本配置--记录下公众号开发信息的AppID和AppSecret
  2. 开启服务器配置(注意:如果开启了服务器配置,之前公众号配置的自定义菜单和,配置的回复消息都会暂时失效,都有配置的服务器接管了)
  • URL:服务器配置(接口路由的地址)【例如:我后端网址xxx.com配置了一个api路由为http:xxx.com/wechat 来处理微信这边的请求响应,因此我这里的URL填的是http:xxx.com/wechat 这个是根据自己的配置来的】
  • Token:自定义就可以保证服务端和这里一样。
  • EncodingAESKey: 随机生成既可。
  • 消息加密这里:我选的明文模式

image.png

三:Koa2框架 服务端代码逻辑处理

// 验证消息的确来自微信服务器  引用了config.js文件 sha1 npm安装既可
router.get('/wechat', async (ctx, next) => {
	// console.log(config.wechat.token)
	const { signature, timestamp, nonce,echostr } = ctx.query
	const token = config.wechat.token
	console.log(token)
	let hash = crypto.createHash('sha1')
	const arr = [token, timestamp, nonce].sort()
	hash.update(arr.join(''))
	const shasum = hash.digest('hex')
	if (shasum === signature) {
		return ctx.body = echostr
	}
	ctx.status = 401
	ctx.body = 'Invalid signature'
	// ctx.body = {code: 200}
})
// 公众号参数 config 文件
const wechat = {
    appID: '公众号AppID',
    appsecret: '公众号appsecret',
    token: 'lovehehe', //服务器配置哪里填的token 
} 

代码整体框架图我放这里,还不清楚的小伙伴可以私聊我

image.png

四:自定义菜单和设置自定义回复

关于自定义菜单,我也是迷迷糊糊的,我改变的方法是通过微信公众号的在线接口调试发送了一个json过去在我开启了服务器后就设置了

image.png

image.png

image.png

然后点击检查问题注意看下面返回的状态码!这里我设置的是小程序的跳转和点击的url跳转,文本信息我设置失败了,如果设置成功的小伙伴可以告诉我一下

服务端主要逻辑代码:关注公众号的自动回复和后台回复事件在开启服务器配置后都统一到后台处理,包括扫码了带参的二维码,这里的POST请求都会响应,

// 这里的请求是POST 跟之前验证服务器的get请求不一样,这个是监听关注了公众号的粉丝发送的事件和消息的

router.post('/wechat', async (ctx, next) => {
	const xml = ctx.request.body;  // 获取数据 这里小伙伴们可以打印出来查看
	const createTime = Date.parse(new Date());
	const msgType = xml.xml.MsgType[0];
	const toUserName = xml.xml.ToUserName[0];
	const toFromName = xml.xml.FromUserName[0];
	const event = xml.xml.Event ? xml.xml.Event[0] : 'null';
	const eventKey = xml.xml.EventKey ? xml.xml.EventKey[0] : '-1'
        
        // 如何判断是扫码进入的还是自己关注的 xml里面的 MsgType 里面的状态可以判断,非常建议小伙伴们把获取的xml打印出来,然后调试看一看,就明白了。
        
        // 如果是扫描了生成的带参的二维码会进入这个路由
        //关注后   
	if (msgType == 'event' && event == 'subscribe') {
	   let time = format(new Date(createTime), 'yyyy-MM-dd HH:mm:ss')
		let item = await register({  // 我这里把这些我需要的数据存入数据库方便统计
		openid: toFromName,  // 邀请用户的openid 根据这个值可以获取用户信息和关注途径
		~~qrscene_id~~: eventKey, // 推广人的 ID  对应下文的:scene_id
		state: event    //  邀请的状态, 
		})
		console.log(item)
		ctx.body = `<xml>
		 <ToUserName><![CDATA[${toFromName}]]></ToUserName>
		 <FromUserName><![CDATA[${toUserName}]]></FromUserName>
		 <CreateTime>${createTime}</CreateTime>
		 <MsgType><![CDATA[text]]></MsgType>
		 <Content><![CDATA[你好呀😊,感谢关注下单校园~ 😍这里是关注回复内容]></Content>
		 </xml>`;
	  } else if (msgType == 'event' && event == 'SCAN') {
		// 关注了 又扫码进入了
		 ctx.body = `<xml>
		 <ToUserName><![CDATA[${toFromName}]]></ToUserName>
		 <FromUserName><![CDATA[${toUserName}]]></FromUserName>
		 <CreateTime>${createTime}</CreateTime>
		 <MsgType><![CDATA[text]]></MsgType>
		 <Content><![CDATA[你好呀😊,感谢关注下单校园😘😘]]></Content>
		 </xml>`;
	} else { 
                //其他情况  取消关注或者是发送其他消息触发
		console.log(event)
		ctx.body = `<xml>
		 <ToUserName><![CDATA[${toFromName}]]></ToUserName>
		 <FromUserName><![CDATA[${toUserName}]]></FromUserName>
		 <CreateTime>${createTime}</CreateTime>
		 <MsgType><![CDATA[text]]></MsgType>
		 <Content><![CDATA[不好意思,客服暂时走开一下,如有问题请联系客服:19180956229(周一~周五,09:00~17:30),
vx:xdxy6661314~]]></Content>
		 </xml>`;
	}
});

五:带参二维码生成

具体参数配置公众号文档里面有介绍: 参数配置详细说明

  1. 首先获取access_token(坑: 如果获取显示IP地址什么的,应该是没有设置你的IP地址为白名单,需要设置才可以访问接口获取到)

https请求方式: GET api.weixin.qq.com/cgi-bin/tok… params: { grant_type: "client_credential", appid: 公众号appid, secret:公众号的secret }

  1. 获取tikcet 目前有临时二维码和永久二维码 具体区可以去文档看看,这里演示获取永久带参二维码的请求

http请求方式: POST URL: api.weixin.qq.com/cgi-bin/qrc…

POST数据格式:json

POST数据例子:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}} "scene_id"的值就是推广人的ID值,这里目前只想到了使用ID的值,有其他想法或者更好的值的小伙伴可以评论告知,然后字符串的我没有获取到。这里的scene_id 对应上面服务端存储的 qrscene_id

获取的数据格式是 data: { ticket: "gQHa8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycjBOWFFETkdkMEcxMDAwMDAwMzEAAgSi_VJgAwQAAAAA" url: "weixin.qq.com/q/02r0NXQDN…" }

这里二维码图片地址我直接使用的: mp.weixin.qq.com/cgi-bin/sho… 去拼接获取的data.ticket直接就显示了一个又参数ID的统广二维码。 比如:mp.weixin.qq.com/cgi-bin/sho… 就好像已经生成了带参的二维码,扫描我服务器后端也成功接受到了扫码提示,获取到了扫码人的openid和推广人的ID号(自己设置的),订阅状态。

这里我有几个疑问,希望知道的小伙伴大佬们可以告知!

  1. 这个URL作用是什么?
  2. Ticket 记得UrlEncode的意义?
  3. 是还需要进行一次GET请求才可以获取到图片嘛??

image.png

六:2021-3-21更新

获取了用户的Openid就可以再使用微信的接口获取用户信息,返回的信息里面就包括了用户关注途径,和一些我们需要的信息

image.png

前面的方法有点不可取。

七:总结

我之前搜索过看见很多都是插件或者是推荐第三方服务的文档类型,还有就是小程序二维码带参跳指定页面的,真没怎么看见公众号带参推广码的这种,(也有可能是没搜索到,哈哈)不过这一次花费了几天时间去研究出来还是很高兴的,这也是第一次在掘金上发文章,记录吧,技术还是太菜了,需要不断学习。推广码生成的这个页面和服务端代码准备过几天放源代码出来,有需要的小伙伴也可以私聊我,我发给你。技术栈NodeJS——Koa2框架+vue2.5+Element-ui

看完还不清楚的小伙伴急需完成这种功能的可以联系我的微信号A1783331467!