标签归档:小程序

微信小程序之分享功能

微信小程序之分享功能

小程序风口正盛,将小程序作为获客的来源之一实在合适不过,想要让小程序的获客产生裂变,那么从将小程序的数据发送出去势在必行,本文提供以下几种方案作为数据出口,达到老拉新/口碑传播的效果。

本文中所介绍的东西并没有高深的技术含量,都是一些很简单的技巧而已。

一、分享:

让用户使用小程序之后,再将它分享给好友,或者发送到朋友圈,实在太合适不过了。

1.转发给好友/群:

在小程序开发API中,发送给好友/群,可以有两种实现方式:

1)入口

a.小程序右上角自带的分享功能(…):

如果在当前页面调用wx.hideShareMenu()方法,那么右上角的分享功能将被隐藏,当然,隐藏方法与现实方法是承兑出现的,调用wx.showShareMenu()方法,可以显示该功能。

b.自定义分享按钮:<butto n open-type=’share’>分享</butto n>

以上两种方式均可实现分享功能

2)分享数据类型

不管采用以上何种方法,转发给好友的数据总归有它的数据模型,该数据模型是通过onShareAppMessage(options)返回的,也就是return一个object即可。其中,options.from可以用来判断是从自定义button打开的转发页面,还是从右上角的打开的转发页面。

以下是该object的数据模型:

如上所示,如果开发人员在onShareAppMessage(options)不进行任何处理,那么微信将会有一个默认的数据转发出去,title为当前小程序名称,path为当前页面的路径,imageUrl为当前页面的截图。根据imageUrl的定义,开发人员可以上传自定义图片,那么这个口子给了运营人员一定的发挥空间,这个问题,文章的后边会详细提及。

2.分享至朋友圈:

微信小程序目前没有直接提供方法来将小程序分享至朋友圈,不过可以采用曲线救国的方式来达到目的。

曲线救国的方式分为两步:

1.通过浏览器将希望分享的东西分享至朋友圈:

微信小程序自身没有任何入口可以进入到微信的浏览器中,那么就更加不可能让用户进入到自身操作系统中的浏览器进行分享了。

那么能否有其他的途径可以达到此目的呢?

答案是客服消息。

微信小程序本身提供客服消息是用来更好的为客户服务

小程序提供了入口,允许用户给客服发送消息,同时,也允许小程序的客服主动给用户发送消息,其中,可以发送图文链接

开发者可以在用户打开该聊天对话框时,主动给用户发送图文链接,用户点击该链接之后,将会跳转到微信的浏览器(H5)页面,该页面不同于小程序内打开的H5页面,如下图

开发者和用户对于这种样式的页面应该相当熟悉了,至此,从小程序进行分享至朋友圈的第一步完成了。

2.用户分享至朋友圈后,用户的好友通过该链接进入朋友圈

众所周知,微信目前还并未提供入口,将微信小程序直接在朋友圈进行展示,但是同样的,微信也没有禁止在朋友圈内展示小程序码,而我们通过小程序进行分享的是图文链接,那么图片自然就可以是需要分享的微信小程序码,至于文字,还可以作为运营人员的推广。

以上,就完成了从微信小程序分享至好友/好友群/朋友圈的路径。

注:小程序的二维码分两种,一种是常规的二维码,还有一种是小程序码,我们这里进行分享的是小程序码。

二、数据追踪

运营人员经常会期望知道哪些用户是自然量,哪些用户是推广量,不仅如此,他们常常期望给那些乐于分享的用户一些奖励。

那么,奖励的标准是什么?无外乎谁拉来的人多,谁就可以获得更多的奖励。开发人员需要满足运营的需求,所以需要记录每个用户通过分享获客的数量等等。

如何进行记录呢,还是老生常谈,无外乎以下几种方式:

1.简单粗暴型:

比如Uber和滴滴的获客方式,通过邀请码来进行获客。这种通过现金奖励的土豪方式不适合绝大多数的推广,而且简单粗暴,本文不再赘述。

2.数据匹配型:

现有的一些第三方推广渠道的合作方式常常都是如此,比如iOS通过用户的IDFA来进行标记用户,用户通过第三方app打开第三方渠道的短链时,由app将IDFA传给短链进行记录,当用户注册账号时,app端通过获取IDFA来和第三方渠道进行比对,如果一致,则认为是通过第三方渠道推广而来的量,最后进行结算。

微信小程序也可以模仿该方式进行记录。

上文提供了三种分享的方式,分享给好友/好友群/朋友圈,它们需要使用不同的方式来进行记录。

1)朋友圈:

分享至朋友圈是通过分享小程序码来达到分享功能的,那么想要进行数据匹配,肯定是通过小程序码来做文章了。

通过调用微信的不同的接口,可以生成类型不同的小程序码,我们调用接口:https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN,具体参数如下:

关注参数scene和page即可,我们可以将用户的userid或者唯一标识放入其中,这样在其他被拉进小程序的用户打开page页面时,我们可以通过以下方式获取到分享发起者的用户唯一标识:

此时,便可以根据此唯一标识来给对应的用户发放奖励了。

2)分享至好友/群:

分享至好友/群和分享至朋友圈的内容并不一致,后者是分享图文链接,而分享至好友群的往往是小程序本身,群中的用户通过该分享可以直接进入小程序,那么如何进行数据匹配呢?

其实方法大同小异,通过查看微信小程序的api,如下:

此处的path中可以加入用户的唯一标识,接下来的流程和分享至朋友圈便是一样了。

部分运营人员期望能知道分享的群的一些信息,可以参考此文:http://news.ifeng.com/a/20170510/51071063_0.shtml

本文参考微信小程序开发文档:

1.转发:https://mp.weixin.qq.com/debug/wxadoc/dev/api/share.html

2.客服消息:https://mp.weixin.qq.com/debug/wxadoc/dev/api/custommsg/conversation.html

3.获取二维码:https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html

原文:https://www.jianshu.com/p/c100d21bcc9c

小程序上传图片or文件到阿里云OSS

搞了大半天,累死了,原本在阿里云官网通过后台取签上传的方式,前端会用到lib,例子下载后无法加入到小程序中使用,后来在CSDN的一篇博文里找到了解决方案

后端get.php,callback.php从阿里云例子中取,直接用

get.php代码

<?php
    function gmt_iso8601($time) {
        $dtStr = date("c", $time);
        $mydatetime = new DateTime($dtStr);
        $expiration = $mydatetime->format(DateTime::ISO8601);
        $pos = strpos($expiration, '+');
        $expiration = substr($expiration, 0, $pos);
        return $expiration."Z";
    }

    $id= 'xxxxxxxx';          // 请填写您的AccessKeyId。
    $key= 'xxxxxxxx';     // 请填写您的AccessKeySecret。
    // $host的格式为 bucketname.endpoint,请替换为您的真实信息。
    $host = 'https://bucket名称.oss-cn-地域.aliyuncs.com/';  
    // $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。
    $callbackUrl = 'callback.php的网络路径';
    $dir = '文件保存路径';          // 用户上传文件时指定的前缀。
	
    $callback_param = array('callbackUrl'=>$callbackUrl, 
                 'callbackBody'=>'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}', 
                 'callbackBodyType'=>"application/x-www-form-urlencoded");
    $callback_string = json_encode($callback_param);

    $base64_callback_body = base64_encode($callback_string);
    $now = time();
    $expire = 30;  //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。
    $end = $now + $expire;
    $expiration = gmt_iso8601($end);


    //最大文件大小.用户可以自己设置
    $condition = array(0=>'content-length-range', 1=>0, 2=>1048576000);
    $conditions[] = $condition; 

    // 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
    $start = array(0=>'starts-with', 1=>'$key', 2=>$dir);
    $conditions[] = $start; 


    $arr = array('expiration'=>$expiration,'conditions'=>$conditions);
    $policy = json_encode($arr);
    $base64_policy = base64_encode($policy);
    $string_to_sign = $base64_policy;
    $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));

    $response = array();
    $response['accessid'] = $id;
    $response['host'] = $host;
    $response['policy'] = $base64_policy;
    $response['signature'] = $signature;
    $response['expire'] = $end;
    $response['callback'] = $base64_callback_body;
    $response['dir'] = $dir;  // 这个参数是设置用户上传文件时指定的前缀。
    echo json_encode($response);
?>

callback.php不用改

小程序前端:

uploadAliyun(str){   //str是wx.chooseImage返回的res.tempFilePaths[0]
  var that = this;
  wx.uploadFile({
    url: 'xxxx/get.php', //你的服务器地址
    filePath: str, //要上传文件资源的路径
    name: 'headimg', //文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容
    formData: {
	adminid: app.globalData.adminid  //HTTP 请求中其他额外的参数比如 用户id
    },
    success(res) {
        console.log(res)
        if(res.statusCode == 200){
          var info = JSON.parse(res.data);
          //  随机生成文件名称
          var fileRandName = Date.now() + "" + parseInt(Math.random() * 1000)
          var fileName = fileRandName + '.' + that.get_suffix(str)
          wx.uploadFile({
            url: 'https://bucket名称.oss-cn-地域.aliyuncs.com', 
            filePath: str,
            name: 'file',
            formData: {
              name: str,
              key: info.dir + fileName,
              policy: info.policy,
              signature: info.signature,
              expire : info.expire,
              success_action_status: "200",
              host: info.host,
              OSSAccessKeyId : info.accessid
            },
            success: function (res) {
              var data = res.data
              console.log(res)
              if(res.statusCode == 200){ }
            }
          })
        }
    }
   })
  },

补充get_suffix功能函数

get_suffix: function(filename) {
    var pos = filename.lastIndexOf('.')
    var suffix = ''
    if (pos != -1) {
        suffix = filename.substring(pos)
    }
    return suffix;
  },