zoukankan      html  css  js  c++  java
  • 微信小程序分享及信息追踪

    我就是个搬用工—来源: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上报给后台 ❎
  • 相关阅读:
    C++中的名字重整技术
    Linux下C++开发常用命令
    《Effective C++(第三版)》 的55条建议
    我也介绍下sizeof与strlen的区别
    POJ
    HDU
    HDU-1754-I Hate It(单点更新+区间查询)
    HDU多校1003-Divide the Stones(构造)
    Just an Old Puzzle(2019多校1007)
    Idiomatic Phrases Game(最短路+注意坑点)
  • 原文地址:https://www.cnblogs.com/LChenglong/p/9685616.html
Copyright © 2011-2022 走看看