当前位置 博文首页 > 纸飞机博客:全栈开发微信公众号

    纸飞机博客:全栈开发微信公众号

    作者:[db:作者] 时间:2021-08-16 16:04

    准备

    注册微信订阅号

    注册小程序测试号

    sunny-ngrok工具安装及注册账号

    注意:sunny-ngrok的原型是ngrok,不过是国外的,sunny-ngrok类似是国内的一个私服,速度更快了,主要作用是域名转发,模拟公网ip和端口,甚至可以配置了给客户在公网上展示项目。地址: http://www.ngrok.cc/ ,进去后注册开通隧道,有免费的。

    记住:一个微信号只能注册一种微信产品,但是可以管理多个。

    使用sunny-ngrok尝试一次转发

    下载工具,启动工具,输入隧道id,回车

    启动ngrok
    说明127.0.0.1:3000将被转发到~~~.com公网ip上

    建个weixin目录,npm初始化

    {
      "name": "weixin-lesson",
      "version": "1.0.0",
      "description": "微信开发课程备课资料 ====",
      "main": "index.js",
      "directories": {
        "doc": "doc"
      },
      "scripts": {
        "sunny": "./bin/sunny clientid 62d16df91a118fd3",
        "ngrok": "./bin/ngrok http 3000",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "repository": {
        "type": "git",
        "url": "git@gitlab.kaikeba.com:web_dev/weixin-lesson.git"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "axios": "^0.18.0",
        "co-wechat": "^2.3.0",
        "co-wechat-oauth": "^2.0.1",
        "crypto": "^1.0.1",
        "express": "^4.16.4",
        "jsonwebtoken": "^8.4.0",
        "koa": "^2.6.2",
        "koa-bodyparser": "^4.2.1",
        "koa-compress": "^3.0.0",
        "koa-jwt": "^3.5.1",
        "koa-route": "^3.2.0",
        "koa-router": "^7.4.0",
        "koa-socket": "^4.4.0",
        "koa-static": "^5.0.0",
        "koa-views": "^6.1.5",
        "koa-websocket": "^5.0.1",
        "koa-xml-body": "^2.1.0",
        "moment": "^2.23.0",
        "mongoose": "^5.4.4",
        "promise-redis": "0.0.5",
        "pug": "^2.0.3",
        "redis": "^2.8.0",
        "request": "^2.88.0",
        "request-promise": "^4.2.2",
        "socket.io": "^2.2.0",
        "watch": "^1.0.2",
        "wechat": "^2.1.0",
        "wechat-oauth": "^1.5.0",
        "xml2js": "^0.4.19"
      }
    }

    weixin目录下建立seed目录,seed目录下建立index.js和index.html

    const Koa = require('koa')
    const Router = require('koa-router')
    const static = require('koa-static')
    const bodyParser = require('koa-bodyparser');
    const app = new Koa()
    app.use(bodyParser())
    const router = new Router()
    app.use(static(__dirname + '/'))
    
    app.use(router.routes()); /*启动路由*/
    app.use(router.allowedMethods());
    app.listen(3000);
    <html>
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
        <script src="https://unpkg.com/vue@2.1.10/dist/vue.min.js"></script>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script src="https://unpkg.com/cube-ui/lib/cube.min.js"></script>
        <script src="https://cdn.bootcss.com/qs/6.6.0/qs.js"></script>
        <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
        <link rel="stylesheet" href="https://unpkg.com/cube-ui/lib/cube.min.css">
        <style>
            /* .cube-btn {
                margin: 10px 0;
            } */
        </style>
    </head>
    
    <body>
        <div id="app">
            <cube-input v-model="value"></cube-input>
            <cube-button @click='click'>Click</cube-button>
        </div>
        <script>
            var app = new Vue({
                el: '#app',
                data: {
                    value: 'input'
                },
    
                methods: {
                    click: function () {
                        console.log('click')
                    }
                },
                mounted: function () {
    
                },
            });
        </script>
    </body>
    
    </html>

    在seed目录打开终端,执行nodemon,300端口打开127.0.0.1

    3000端口

    在打开隧道赠送的域名

    隧道玉域名结果

    使用消息接口

    微信自带消息自动回复功能,可以在公众平台设置,但是很死板,无法动态回复消息

    进入微信开发者工具,申请公众平台测试账号

    有一些配置,填写转发的域名,token随意,要和服务器的用的一样

    token

    再就是在项目里配置,新建一个conf.js

    module.exports={
        appid: 'wx77f481fc8a9113a4',
        appsecret: '2b84470b9fb0f8166a8518c5b40edaf9',
        token: 'qweqwe'
    }

    在index.js里引入

    使用一个库co-wechat

    const Koa = require('koa')
    const Router = require('koa-router')
    const static = require('koa-static')
    const bodyParser = require('koa-bodyparser');
    const app = new Koa()
    const conf = require('./conf')//引入conf
    app.use(bodyParser())
    const router = new Router()
    app.use(static(__dirname + '/'))
    
    const wechat = require('co-wechat')//使用co-wechat库
    router.all('/wechat', wechat(conf).middleware(
        async message => {
            console.log('wechat:', message)
            return 'Hello World ' + message.Content
        }
    ))
    
    app.use(router.routes()); /*启动路由*/
    app.use(router.allowedMethods());
    app.listen(3000);

    知识点:co-开头的库是代表着满足异步要求的库

    再去提交接口配置信息(要多试试,才能提交成功)

    成功后,这个时候呢,可以关注下面的测试号二维码

    发送1,会回复Hello World 1(如果是设置的没有这中获取用户发送的信息的方法,所以有时候也需要api),如下图

    效果

    微信一些api的调用

    相关文档: https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html

    获取token

    const axios = require('axios')
    const tokenCache = {
        access_token:'',
        updateTime:Date.now(),
        expires_in:7200
    }
    
    router.get('/getTokens',async ctx => {//获取token
        const wxDomain =  `https://api.weixin.qq.com`
        const path = `/cgi-bin/token`
        const param = `?grant_type=client_credential&appid=${conf.appid}&secret=${conf.appsecret}`
        const url = wxDomain + path + param
        const res = await axios.get(url)
        Object.assign(tokenCache,res.data,{
            updateTime:Date.now()
        })
        ctx.body = res.data
    })

    获取用户信息

    router.get('/getFollowers',async ctx => {//获取用户信息
        const url = `https://api.weixin.qq.com/cgi-bin/user/get?access_token=${tokenCache.access_token}`
        const res = await axios.get(url)
        console.log('getFollowers:',res)
        ctx.body = res.data
    })

    上面都是原生的用法接下来我们使用co-wechat-api包来看看

    安装 co-wechat-api

    yarn add co-wechat-api 
    const WechatAPI = require('co-wechat-api')
    const api = new WechatAPI(
        conf.appid,
        conf.appsecret,
        // // 取Token
        // async () => await ServerToken.findOne(),
        // // 存Token
        // async token => await ServerToken.updateOne({}, token, { upsert: true })
    )
    router.get('/getFollowers', async ctx => {
        let res = await api.getFollowers()
        res = await api.batchGetUsers(res.data.openid, 'zh_CN')//加上后会返回详细信息
        ctx.body = res
    })
    用户详细信息

    全局票据

    全局票据需要基于mongodb或者redires,我们用mongodb

    新建个mongoose.js

    const mongoose = require('mongoose')
    const {
        Schema
    } = mongoose
    mongoose.connect('mongodb://localhost:27017/weixin', {
        useNewUrlParser: true
    }, () => {
        console.log('Mongodb connected..')
    })
    exports.ServerToken = mongoose.model('ServerToken', {
        accessToken: String
    });

    index.js里改造上面用co-wechat-api的

    const { ServerToken } = require('./mongoose')//全局票据来源
    const WechatAPI = require('co-wechat-api')
    const api = new WechatAPI(
        conf.appid,
        conf.appsecret,
        // 取Token
        async () => await ServerToken.findOne(),
        // 存Token
        async token => await ServerToken.updateOne({}, token, { upsert: true })
    )
    router.get('/getFollowers', async ctx => {
        let res = await api.getFollowers()
        res = await api.batchGetUsers(res.data.openid, 'zh_CN')
        ctx.body = res
    })

    消息推动

    就类似于这个,前台发送1,1,2

    后台会显示前台的推送,而且更新echart

    Oauth2认证流程

    首先三个端,浏览器,服务器,微信服务器

    auth2认证流程

    1.浏览器向服务器发送认证请求

    2.服务器让浏览器重定向微信认证界面

    3.浏览器向微信服务器请求第三方认证(微信认证)

    4.微信服务器毁掉给服务器一个认证code

    5.服务器用code向微信服务器申请认证令牌

    6.微信服务器返给服务器一个令牌

    最后当服务器得到令牌认证成功后,发给浏览器一个指令,刷新界面

    刷新后的认证

    刷新后就会有一个用户信息

    使用微信开发者工具,选择公众号网页,用来预览

    demo1 下载cs