frontend9 / fe9-library

九部知识库
1.94k stars 138 forks source link

微信&钉钉二次分享SDK #22

Open liyouu opened 6 years ago

liyouu commented 6 years ago

在做H5活动页面的时候,

PD大人可能会说:哎呀,这个页面要分享到微信和钉钉里去的,做的时候注意一下~

当时你一想这有啥好注意的,直接上呗,拍拍胸脯就保证会分享得美美哒~

然后页面上线后,PD一分享就成了酱紫:

微信分享

钉钉分享

PD大人瞬间抓狂,你是在逗我吗!!!

So,接下来就要告诉你如何优雅的操作,秒秒钟满足PD大人的需求!!

在传播过程中,美美哒的页面可以分享成酱紫~

PD大人可以配置标题、文案、和小图片~

钉钉分享

微信分享


那么,重点来啦!臣妾该怎么实现呢?

第一步:接入钉钉sdk 查看钉钉开发文档

① 引入钉钉sdk:https://g.alicdn.com/ilw/ding/0.9.9/scripts/dingtalk.js

② 引入之后将得到全局变量dd

③ 像写jquery一样,待环境准备就绪之后再执行任务

dd.ready(function(){
    ; // 执行任务
});

④ 配置分享options

dd.biz.util.share({
    type: 0, //分享类型,0:全部组件 默认; 1:只能分享到钉钉;2:不能分享,只有刷新按钮
    url: 'https://taobao.com',
    title: '页面标题',
    content: '页面内容简介',
    image: '100*100px的正方形小图片',
    onSuccess : function() {
        // onSuccess将在分享完成之后回调
        // 比如分享之后积分+10这种操作就可以放在这个回调里面
    },
    onFail : function(err) {
        // onFail将在分享完成之后回调
    }
});

第二步:接入微信sdk 查看微信开发文档

① 接入微信sdk:https://res.wx.qq.com/open/js/jweixin-1.2.0.js

② 引入之后将得到全局变量wx

通过config接口注入权限校验配置

wx.config({
    debug: true,
    appId: '', // 必填,企业号的唯一标识,此处填写企业号corpid
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名,见附录1
    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
// 这些配置项都需要从企业号获取的,可以

④ 因此你得需要一个企业号或者说是公众号,在设置 > 公众号设置 >js接口安全域名,在域名中添加分享要用到的域名,例如share.com,只有这样才能通过权限校验,还需要开发提供一个获取微信获取jssdk签名的接口

http://thyrsi.com/t6/360/1534836300x-1404755516.png

http://thyrsi.com/t6/360/1534836340x-1404755516.png

⑤ 通过ready接口处理成功验证

wx.ready(() => {
    wx.onMenuShareTimeline({
      title: '',
      desc: '',
      link: '',
      imgUrl: '',
      success: function() {},
      cancel: function() {}
    });
    wx.onMenuShareAppMessage({
      title: '',
      desc: '',
      link: '',
      imgUrl: '',
      success: function() {},
      cancel: function() {}
    });
    wx.onMenuShareQQ({
      title: '',
      desc: '',
      link: '',
      imgUrl: '',
      success: function() {},
      cancel: function() {}
    });
    wx.xxxxx({}) // 详见分享接口
});
liyouu commented 6 years ago

第三步:整合两家提供通用sdk

这是我之前做sdk的一点心得,因为要脱敏的原因,不能直接将sdk开源,但是这个sdk做起来是相当简单的哟~

① 实现思路

http://thyrsi.com/t6/360/1534836364x-1404755516.png

② 部分实现逻辑

// 定义全局变量
const shareTwice = {
  config(shareConfig) {
    // 默认先从meta标签中获取配置项,约定好类似这样的meta源标签<meta name="shareTitle" value="分享名称" />
    const defaultConfig = {};
    const titleDom = document.getElementsByTagName('meta').shareTitle || document.getElementsByTagName('title')[0];      
    const descDom = document.getElementsByTagName('meta').shareDesc;
    const linkDom = document.getElementsByTagName('meta').shareLink; 
    const imageDom = document.getElementsByTagName('meta').shareImage;
    defaultConfig.title = titleDom.getAttribute('content') || titleDom.innerText;
    defaultConfig.desc = descDom ? descDom.getAttribute('content') : '';  
    defaultConfig.link = linkDom ? linkDom.getAttribute('content') : document.location.href;  
    defaultConfig.image = imageDom ? imageDom.getAttribute('content') : 'https://gw.alipayobjects.com/zos/rmsportal/PbxcajsXkcfiWIYdRxaw.jpg'; 
    defaultConfig.successFun = function() {}
    defaultConfig.failFun = function(err) {}

    // 或者使用config({})传入的配置项
    this.shareConfig = Object.assign(defaultConfig, shareConfig || {});

    // 判断是否为钉钉环境  
    this.isDing();
    // 判断是否为微信环境,按需加载sdk
    this.isWechat();
  },
  isWechat() {
    const me = this;
    const isWechat = ~window.navigator.userAgent.indexOf('MicroMessenger');
    if (isWechat) {
      const me = this;
      if (typeof window.wx === 'undefined') {
        me._loadScript('//res.wx.qq.com/open/js/jweixin-1.2.0.js', function() {
          me._shareInWechat();            
        })
      } else {
        me._shareInWechat();
      }  
    } 
  },
  isDing() {
    const me = this;
    const isDing = ~window.navigator.userAgent.indexOf('DingTalk');
    if (isDing) {
      if (typeof window.dd === 'undefined') {
        me._loadScript('//g.alicdn.com/ilw/ding/0.9.9/scripts/dingtalk.js', function () {
          me._shareInDing();          
        })
      } else {
        me._shareInDing();        
      }
    }
  },
  // 配置在钉钉环境下分享时的配置项
  _shareInDing() {
    const me = this;
    dd.ready(function(){
      dd.biz.navigation.setRight({
        show: true,
        control: true,
        text: '',
        onSuccess : function(result) {
          dd.biz.util.share({
            type: 0,
            url: me.shareConfig.link,
            title: me.shareConfig.title,
            content: me.shareConfig.desc,
            image: me.shareConfig.image,
            onSuccess : me.shareConfig.successFun,
            onFail : me.shareConfig.failFun,
          });
        },
        onFail : function(err) {}
      });
    });
  },
  // 配置在微信环境下分享时的配置项
  _shareInWechat() {
    const me = this;
    me._getConfigs(function( data ){
      data.link = data.url;
      delete data.url;
      // 需要后端提供的接口返回appId、timestamp、nonceStr、signature
      me.shareConfig = Object.assign(me.shareConfig, data);
      wx.config({
        debug: me.shareConfig.debug, 
        appId: me.shareConfig.appId, 
        timestamp: me.shareConfig.timestamp,
        nonceStr: me.shareConfig.nonceStr, 
        signature: me.shareConfig.signature,
        jsApiList: [
          'openEnterpriseChat',
          'openEnterpriseContact',
          'onMenuShareTimeline',
          'onMenuShareAppMessage',
          'onMenuShareQQ',
          'onMenuShareWeibo',
          'onMenuShareQZone'
        ]
      });
      wx.ready(() => {
        wx.onMenuShareTimeline({
          title: me.shareConfig.title,
          desc: me.shareConfig.desc,
          link: me.shareConfig.link,
          imgUrl: me.shareConfig.image,
          success: me.shareConfig.successFun,
          cancel: me.shareConfig.failFun
        });
        wx.onMenuShareAppMessage({
          title: me.shareConfig.title,
          desc: me.shareConfig.desc,
          link: me.shareConfig.link,
          imgUrl: me.shareConfig.image,
          success: me.shareConfig.successFun,
          cancel: me.shareConfig.failFun
        });
      })
    });
  },
  // 需要服务端提供一个 微信获取jssdk签名的接口,具体要看接口怎么实现
  _getConfigs(callback) {
     $.ajax({
          method: "POST",
          url: "some.php",
          data: {
              url: document.location.href.split('#')[0]
          }
     })
     .done(function( msg ) {
          callback();
     });
  },
  _loadScript(src, callback) {
    let script = document.createElement('script');
    script.setAttribute('async', 'async');
    script.setAttribute('src', src);
    script.setAttribute('charset', 'utf-8');
    script.onload = () => {
      callback();
    };
    document.getElementsByTagName('head')[0].appendChild(script);
  }
};

③ 在页面中引用

通过<script charset="utf-8" src="./share-twice.js"></script>引入

④ 在页面中进行配置

方式一(简洁方式):通过标签注入

<meta name="shareTitle" content="需要分享的Title">
<meta name="shareDesc" content="需要分享的描述内容">
<meta name="shareLink" content="https://newconnection.cainiao.com/cn/test/liyoutest.html">
<meta name="shareImage" content="https://gw.alicdn.com/tfs/TB1UlBCNXXXXXXCXXXXXXXXXXXX-97-97.png">
<meta name="shareAuto" content="true">

方式二(支持分享后的回调):通过ShareTiwce.config()进行配置

<script>
    shareTwice.config({
      title: '需要分享的Title',
      desc: '需要分享的描述内容',
      link: 'https://newconnection.cainiao.com/cn/test/liyoutest.html',
      image: 'https://gw.alicdn.com/tfs/TB1864sQpXXXXaaXpXXXXXXXXXX-35-40.png',
      successFun: function() {
        // 分享成功后的回调函数
        alert("share-twice: success");
      },
      failFun: function() {
        // 分享取消或失败后的回调函数
        alert("share-twice: cancel");
      }
    });
</script>

⑤ 注意事项

  1. shareTwice.config中的配置高于<meta>标签中的配置项
  2. shareTitle默认为<title>标签中的值
  3. shareLink默认为document.location.href
  4. shareImage默认值为https://gw.alipayobjects.com/zos/rmsportal/PbxcajsXkcfiWIYdRxaw.jpg
  5. shareAuto默认值为false 若不设置为true需要调用shareTwice.config({})进行初始化
laoya commented 6 years ago

正犹豫要不要自己写一个 刚好需要 拿走 谢啦

dumuchenglin123 commented 5 years ago

厉害厉害,问下,你这是在公司电脑上写的还是自己电脑上写的?公司里可以发布留言吗?