7

微信小程序跳转H5、小程序、App

 1 year ago
source link: https://www.fly63.com/article/detial/12299
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在业务中接触了微信小程序,客户对引流用户非常在意,每次都会提该需求,经常做就存档一下。使用的小程序账户都是企业版非个人版本。

在微信公众平台-小程序后台配置业务域名,要将校验文件放置到域名根目录下,才可配置成功,通过 https://url/校验文件名.txt 可测试成功与否。

使用 web-view 配置路径

如需传参通过 ?key=value 形式一起传输,在另一端接收 URL 上的参数便可。

<web-view :src="`https://url/index.html#/?timestamp=${timestamp}`" />

跳转小程序

// 方式一:似乎不能用了,有哪位好心人能用的话求咨询
<button @click="goMiniapp">跳转下载</button>

Taro.navigateToMiniProgram({ // 我用的taro,原生用 wx.navigateToMiniProgram 就行
  appId: "appid",
  path: 'page/index/index',
  extraData: { // 传递给小程序的数据
    foo: 'bar'
  },
  envVersion: 'develop',
  success(res) {
    // 打开成功
  }
})

// 方式2:可用,可以回退到自己的小程序
<navigator target="miniProgram" open-type="navigate" 	app-id="appid" path="pages/index/index">跳转小程序</navigator>

跳转App

2021.5 月开始小程序不再支持跳转到 App,那要怎么跳转 App 呢,看了一下腾讯视频的小程序是利用客服消息发送 App 下载地址,感觉此方法体验甚好,就参考了很多文档实测了一下。源地址:关于不再提供“小程序打开App技术服务”的通知

消息推送配置

消息推送配置指南介绍的很清楚,也可以只看这个。
63b7c02a1fd60.jpg

首先要开始微信的消息推送功能,在微信公众平台-小程序后台-开发管理-消息推送,选择启用,这个部分需要管理员或开发者进行扫码确认。

确认成功会跳转到配置页面,按需求配置即可。我这里选择了安全模式,会对后续客服消息。

63b7c039ef923.jpg

Token验证

微信服务器将发送 GET 请求到填写的服务器地址 URL 上,进行 Token 验证,所以要先新建好服务器并上线。

该图是关于返回的参数 + 如何创建 GET 请求

63b7c04012d23.jpg

main.mjs 根据设定好的要求,按步骤创建get方法用于接收get请求。这里使用了ES6,需要对 package.json 增加 "type": "module"。


import express from "express";
import request from "request"
import cors from "cors";
import bodyparser from "body-parser";
import CryptoJS from "crypto-js";
var app = express();
app.use(cors({ origin: "*" }));
app.use(bodyparser.json());

var config = {
    token: 'sxRGsggaA7XaYlSKuKVJkThLs', // 和配置消息推送的token一致
    content: "下载腾讯视频App,享受更多播放特权,请戳→http://m.v.qq.com/activity/downapp_activity.html", // 借用腾讯下载app的链接,做的demo
    EncodingAESKey: "你的EncodingAESKey",
    APPID: "你的APPID",
    APPSECRET: "你的APPSECRET",
    access_token: ""
}


app.get("/url", (req, res) => {
    console.log(req.query);
    var signature = req.query.signature;
    var timestamp = req.query.timestamp;
    var nonce = req.query.nonce;
    var echostr = req.query.echostr;
    var ciphertext = CryptoJS.SHA1([config.token, timestamp, nonce].sort().join(''));
    if (signature == ciphertext.toString()) {
        res.send(echostr);
    } else {
        res.send({
            status: 400,
            data: "check msg error"
        });
    }
});
app.listen(process.env.PORT)

接下来就可以点提交键啦~~,成功配置后会跳转回到开发配置页面,此时你的相关配置就在这能查看到。

63b7c0467fb41.jpg

小程序跳转客服消息

参考微信组件 button

<button open-type="contact">前方客服会话获取下载链接</button>

配置AccessToken(非安全模式不需要这部)

参考微信接口 getAccessToken

main.mjs

function get_access_token() {
    return new Promise((resolve, reject) => {
        request(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${config.APPID}&secret=${config.APPSECRET}`, { json: true }, (err, res, body) => {
            if (err) {
                reject(err)
            } else {
                resolve(body)
            }
        });
    })
}

var out_time = 7100 * 1000
var last_time = 0;

async function get_token() {
    if (Date.now() - out_time > last_time) {
        var cur = await get_access_token()
        config.access_token = cur.access_token;
        last_time = Date.now();

        console.log('当前token:', config.access_token)
        console.log('过期时间:', new Date(last_time + out_time).toString(), '+8小时'); // 在服务器部署的是UTC时间,和北京时间差8小时。。
    }
    return config.access_token;
}
setInterval(get_token, 5000)
get_token();

配置客服自动回复

如非安全模式,参考 消息推送回复 就行内部代码很详细。

配置选择安全模式的话,需要对接收信息进行解密。 以下为 wx-crypto.mjs 解密模块

import crypto from 'crypto'; // 加密模块

function decodePKCS7(buff) {
    let pad = buff[buff.length - 1];
    if (pad < 1 || pad > 32) {
        pad = 0;
    }
    return buff.slice(0, buff.length - pad);
};

// 微信转发客服消息解密
function decryptContact(key, iv, crypted) {
    const aesCipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
    aesCipher.setAutoPadding(false);
    let decipheredBuff = Buffer.concat([aesCipher.update(crypted, 'base64'), aesCipher.final()]);
    decipheredBuff = decodePKCS7(decipheredBuff);
    const lenNetOrderCorpid = decipheredBuff.slice(16);
    const msgLen = lenNetOrderCorpid.slice(0, 4).readUInt32BE(0);
    const result = lenNetOrderCorpid.slice(4, msgLen + 4).toString();
    return result;
};

// 解密微信返回给配置的消息服务器的信息
function decryptWXContact(wechatData, EncodingAESKey) {
    if (!wechatData) {
        wechatData = '';
    }
    //EncodingAESKey 为后台配置时随机生成的
    const key = Buffer.from(EncodingAESKey + '=', 'base64');
    const iv = key.slice(0, 16);
    const result = decryptContact(key, iv, wechatData);
    const decryptedResult = JSON.parse(result);
    console.log(decryptedResult);
    return decryptedResult;
};

export {decryptWXContact}

main.mjs post方法,接收信息解密 + 返回消息。

import { decryptWXContact } from "./wx-crypto.mjs"
app.post("/url", async (req, res) => {
    const { ToUserName, Encrypt } = req.body // ToUserName 推送接收的账号
    
    if (!Encrypt) return res.send('success'); //配置时选的安全模式 因此需要解密

    const decryptData = decryptWXContact(Encrypt, config.EncodingAESKey);
    if (!decryptData) return res.send('success');

    if (decryptData.MsgType == 'text') {
        await sendmess(config.access_token, {
            access_token: config.access_token,
            touser: decryptData.FromUserName,
            msgtype: 'text',
            text: {
                content: decryptData.Content == '下载' ? config.content || '' : '感谢您关注xxx小程序'
            },
            image: {},
            link: {},
            miniprogrampage: {}
        })
    }
    res.send('success') // 不进行任何回复,直接返回success,告知微信服务器已经正常收到。
});

function sendmess(access_token, mess) {
    return new Promise((resolve, reject) => {
        var options = {
            'method': 'POST',
            'url': `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${config.access_token}`,
            'headers': {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                "access_token": `${config.access_token}`,
                ...mess
            })
        }
        request(options, function (error, response) {
            if (error) reject(error);
            resolve(response.body)
        });
    })
}
作者:lulu__
来源:https://github.com/lulu-s/lulu-微信小程序跳转App、H5、小程序.md

链接: https://www.fly63.com/article/detial/12299


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK