我就是個搬用工—來源:https://www.jianshu.com/p/87a75ec2fd53
小程序分享群及信息追蹤
需求
- 頁面分享
小程序頁面分享鏈接增加source參數,值為用戶ID加密,分享出去的鏈接類似/pages/live/live?id=10109&source=1ada812s
分享時自定義分享文案、鏈接、封面圖
分享完成后獲取分享信息,能獲取到群ID算成功,做一次上報,記錄該用戶分享的信息
- 追蹤
群用戶打開分享的卡片后,獲取鏈接中的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上報給后台 ❎
