我就是个搬用工—来源:https://www.jianshu.com/p/87a75ec2fd53

小程序分享群及信息追踪

需求

  1. 页面分享

​ 小程序页面分享链接增加source参数,值为用户ID加密,分享出去的链接类似/pages/live/live?id=10109&source=1ada812s

​ 分享时自定义分享文案、链接、封面图

​ 分享完成后获取分享信息,能获取到群ID算成功,做一次上报,记录该用户分享的信息

  1. 追踪

​ 群用户打开分享的卡片后,获取链接中的source参数做一次上报,记录哪些用户打开小程序

​ 用户在此页面观看30s之后再做一次上报

实现

页面分布:

  • live.js 小程序某页面
  • app.js 小程序首页

代码分析:

由于代码中有很多不相关的部分,所以分析的过程中,尽可能的省略掉不相关的代码部分,以求更清晰的了解整个分享过程。

第一次上报

整个需求开发中,出现三次需要上报情况,可以将上报定义为同一个函数,根据不同的入参,做不同的事。live.js中上报函数代码如下:

upload_share_Result(res, type, uid) {
let share_event = apiUrl.share_event // 获取接口
let token = Store.getState().updateToken // 获取登录用户token
let params = {
token, // 登录用户的token
//转发群事件 :type=1; 进入直播间事件 :type=2; 进入直播间30s事件 :type=3
type,
uid, // 记录来源,如果在小程序打开,来源为空;如果从别人分享的打开,来源别人的uid
encryptedData: res ? res.encryptedData : '', // 分享到群的群消息
iv: res ? res.iv : '' // 分享到群的群消息
}
Request(share_event, params, 'post').then((res) => {
//...
}).catch((res) => {
//...
})
},

首先我们需要了解小程序转发的API,包括是否带有群标识、以及如何获取群标识、如何解密群信息等。接下来我们会一点点分析。

live.js中实现转发分享思路和代码如下:

首先保证live页面显示分享按钮,且能够带有ShareTicket的转发

/*
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 显示当前页面的转发按钮
wx.showShareMenu({
// 是否使用带 shareTicket 的转发
withShareTicket: true
})
}

然后在live.js中调用onShareAppMessage,来实现自定义转发的信息。然后再通过getShareInfo来获取需要的群信息。具体API可见官网onShareAppMessage & getShareInfo

/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
let _this = this
let uid = Store.getState().updateUid // 获取redux中的用户uid
return {
title: this.data.title,
// 分享路径,房间名+用户uid
path: `/pages/live/live?id=${this.data.roomid}&source=${uid}`,
imageUrl: this.data.shareImage,
// 转发成功的回调函数
success: function (res) {
// 分享给个人:{errMsg: 'shareAppMessage:ok'}
// 分享给群:{errMsg: 'shareAppMessage:ok', shareTickets: Array(1)}
/* shareTicket 数组
* 每一项是一个 shareTicket(是获取转发目标群信息的票据) ,对应一个转发对象
*/
var shareTicket = (res.shareTickets && res.shareTickets[0]) || ''
/* 官网的Tip: 由于策略变动,小程序群相关能力进行调整,
* 开发者可先使用wx.getShareInfo接口中的群ID进行功能开发。
*/
wx.getShareInfo({
// 把票据带上
shareTicket: shareTicket,
success: function (res) {
// 如果从小程序分享没有source,如果从别人分享的再二次分享带有source
// 后续会讲_this.data.source的来源
let source = _this.data.source ? _this.data.source : '';
// 上报给后台,把群信息带给后台,后台会去解密得到需要的信息
_this.upload_share_Result(res, '1', source)
}
})
},
fail: function (res) {
}
}
}

以上部分已经可以实现基本的分享到群,然后获取群信息,并且完成第一次上报。

后续上报

接下来说一下,当一个用户打开别人分享的小程序,并接受授权或者已有授权的情况下,如何完成第二次、第三次上报,代码依旧在live.js中。

onLoad: function (options) {
let _this = this;
this.setData({
// 获取小程序url中的source,记录此小程序是谁分享的;也可能不存在source
roomid: options.id,
source: options.source
}, function () {
//...
}) // 给全局添加回调函数,当用户没有已授权的状态,需要点击·授权·按钮后,此时执行回调函数
app.getInfoCb = function () {
if (options.source) {
// 第二次上报,如果有options.source,则记录谁分享的
_this.share_event_req(null, '2', options.source)
// 第三次上报,如果有options.source,则记录谁分享的
setTimeout(() => {
_this.share_event_req(null, '3', options.source)
}, 30 * 1000)
}
}
// 如果用户已授权状态,未删除小程序,直接执行
if (Store.getState().updateUid) {
app.getInfoCb()
}
}

那么点击授权按钮后,执行回调函数又如何操作呢?此时移步至app.js

App({
postLogin(cdoe, iv, encryptedData) {
let params = {
code : cdoe,
iv: iv,
encryptedData: encryptedData
}
let _this = this; // this指向App对象
Request(apiUrl.postLogin, params, 'post').then(
(res) => {
wx.hideLoading()
if(res.code === 1){
// ...
// 如果存在全局getInfoCb,则执行
_this.getInfoCb && _this.getInfoCb()
}
}
)
}
})

仔细的看上面的代码会发现,全局回调中执行的方法share_event_req并不是我们最初定义的公共的upload_share_Result。如果直接调用upload_share_Result方法就可以直接上报了,那为什么还需要调用share_event_req呢?这个share_event_req方法中有做了什么处理呢?我们接着分析,代码在live.js中:

share_event_req(res, type, uid) {
let _this = this;
// 如果全局存在shareTicket票据的话,重新执行getShareInfo获取票据中带有的群信息
// 并且上报给后台,让后台去解析群信息
// 官网:当用户将小程序转发到任一群聊之后,可以获取到此次转发的 shareTicket,此转发卡片在群聊中被其他用户打开时,可以在 App.onLaunch() 或 App.onShow 获取到另一个 shareTicket。这两步获取到的 shareTicket 均可通过 wx.getShareInfo() 接口可以获取到【相同】的转发信息。
// 也就是说,A转发到某群,只有B从此群中打开才能算是A的二次上报;但是B再次转发到此群,C从此群打开上报,则不算B上报成功了。这样防止用户群中互相刷。
if (app.globalData.shareTicket) {
wx.getShareInfo({
shareTicket: app.globalData.shareTicket,
success: function (res) {
_this.upload_share_Result(res, type, uid);
}
})
} else {
// 如果全局不存在shareTicket的话,直接调用upload_share_Result上报
self.upload_share_Result(null, type, uid);
}
}

那么按照官网说的,全局的shareTicket是在App.onLaunch() 或 App.onShow() 中获取的。

App({
onShow: function (options) {
// this指向App对象
this.globalData.shareTicket = options.shareTicket
}
})

总结

  • 用户A从小程序第一次分享到群,把分享的群信息和空的source传给后台上报。 ✅
  • 用户A从小程序第一次分享到个人,获取不到shareTicket,不会上报。
  • 用户B从此群打开小程序获取到全局shareTicket。
    • 如果已有授权执行全局回调,把此shareTicket信息和source=A上报给后台 ✅
    • 如果没有授权,点击授权执行全局回调,把此shareTicket信息和source=A上报给后台 ✅
  • 当用户B在此小程序停留30s,把此shareTicket信息和source=A上报给后台 ✅
  • 用户B再次分享到此群,把分享的群信息和source=A传给后台上报,群信息相同。❎
  • 用户C打开用户B分享的小程序获取到全局shareTicket。
    • 如果已有授权执行全局回调,把此shareTicket信息和source=B上报给后台。 ❎
    • 如果没有授权,点击授权执行全局回调,把此shareTicket信息和source=B上报给后台 ❎

微信小程序分享及信息追踪的更多相关文章

  1. golang-vue实现微信小程序分享到朋友圈

    最近涉及到微信小程序分享到朋友圈,不知道微信为什么不直接接口分享,咱也不敢佛,咱也不敢问,只能百度问度娘,看官方文档,网上的一些分享五花八门,每一个重点的,所以整理了一下到底怎样生成二维码分享图片才是 ...

  2. 微信小程序分享至朋友圈的方法

    最近研究怎么实现微信小程序分享至朋友圈,对就是朋友圈. 微信小程序目前没有直接提供方法来将小程序分享至朋友圈,不过可以采用曲线救国的方式来达到目的. 方法分两步: 1.通过浏览器将希望分享的东西风向至 ...

  3. 图解微信小程序---获取电影信息

    图解微信小程序---获取电影信息 代码笔记 第一步:编写js文件,调用api获取相对应电影详情信息(注意带入的参数是id不在是榜单的type,电影api的movie后面又斜杠,别忘了,对应的绑定数据的 ...

  4. 关于微信小程序分享/转发功能的实现方法

    实现微信小程序分享,可以有两个入口: 1. 小程序右上角菜单自带的分享 这个入口是默认关闭的,需要在当前页面中调用showShareMenu方法,开启分享 onLoad: function () { ...

  5. 微信小程序 获取用户信息并保存登录状态

    微信小程序 获取用户信息并保存登录状态:http://www.360doc.com/content/18/0124/11/9200790_724662071.shtml

  6. (八)微信小程序---获取定位信息chooseLocation

    微信小程序---获取定位信息  chooseLocation wxml <view bindtap="getlocalPath">{{localPath}}</v ...

  7. Laravel wxxcx 微信小程序获取用户信息

    wxxcx 是Laravel5微信小程序登录获取用户信息扩展 部署 12345678 # 安装$ composer require iwanli/wxxcx# 注册服务# 在 /config/app. ...

  8. 微信小程序分享转发用法大全——自定义分享、全局分享、组合分享

    官方提供的自定义分享 使用隐式页面配置函数实现的全局分享-推荐 使用隐式路由实现的全局分享-不推荐,仅供了解隐式路由 前言: 目前微信小程序只开放了页面自定义分享的API,为了能够更灵活的进行分享配置 ...

  9. 微信小程序--分享功能

    微信小程序--分享功能 微信小程序前段时间开放了小程序右上角的分享功能, 可以分享任意一个页面到好友或者群聊, 但是不能分享到朋友圈 这里有微信开发文档链接:点击跳转到微信分享功能API 入口方法: ...

随机推荐

  1. 解决c# progressBar更新出现界面假死

    最近一个项目需求中的一个功能是需要用progressBar反映处理文件的进度. 研究了Invoke和BeginInvoke方法. Control.Invoke 方法 (Delegate) :在拥有此控 ...

  2. sql where 里面判定要加 ' '

    WHERE year>=2010 and year<=2017 and indicator_code = 'SE.XPD.TOTL.GD.ZS'

  3. nginx 环境不支持thinkPHP

    在linux+Nginx+mysql+PHP 新装的服务器下,不支持重写pathinfo功能 . 需要加入这个代码 让Nginx 支持重写功能 location / { if (!-e $reques ...

  4. nginx运用

    1.nginx的 命令 start nginx 这样,nginx 服务就启动了.打开任务管理器,查看 nginx.exe 进程,有二个进程会显示,占用系统资源,那是相当的少.然后再打开浏览器,输入 h ...

  5. MongoDB --- 02. 基本操作,增删改查,数据类型,比较符,高级用法,pymongo

    一.基本操作 . mongod 启动服务端 2. mongo 启动客户端 3. show databses 查看本地磁盘的数据库 4. use 库名 切换到要使用的数据库 5. db 查看当前使用的数 ...

  6. HDFS配置参数及优化之实战经验(Linux hdfs)

    HDFS优化之实战经验 Linux系统优化 一.禁止文件系统记录时间 Linux文件系统会记录文件创建.修改和访问操作的时间信息,这在读写操作频繁的应用中将带来不小的性能损失.在挂载文件系统时设置no ...

  7. Star in Parentheses

    问题 A: Star in Parentheses 时间限制: 1 Sec  内存限制: 128 MB 题目描述 You are given a string S, which is balanced ...

  8. Linux (麒麟)系统 重启后无法登陆进图形界面

    登录图形化界面的时候,会显示GNOME电源管理器没启动等提示信息,会一直卡在登录界面 在启动的时候按ESC或者在登录界面crtl+alt +f3 进入字符终端界面 查看物理存储空间占用信息,可能会有一 ...

  9. 洛谷 P3376 【【模板】网络最大流】

    题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui. ...

  10. CentOS设置服务开机启动的两种方法

    一.通过服务的方式设置自启动 1.  在/etc/init.d 下建立相关程序的启动脚本 2.  chkconfig --add mysqld(添加服务到chkconfig列表中) chkconfig ...