基于微信云开发的小程序客服消息推送

小册 《Uniapp 从入门到进阶》 - 从基础到实战,详细讲解跨平台应用开发的方方面面,包含 Uniapp 开发经常使用知识点,基础 api,前端交互、组件封装,后端 Nodejs 开发、先后端联调和调优部署,是一套很是全面的综合课程。

今年的早春非同寻常,病毒的肆虐,影响着各行各业,但愿早点过去,一切恢复正常。html

引言

最近在升级公司小程序,打算把一些前端可操做且相对独立(后端懒得改)的功能,逐步尝试转移为云开发实现,此次先谈谈客服消息推送,我"参考"了官方文档,感谢官方提高我多想多动手的能力,因而有了这篇文章,内容大概会分为如下几点:前端

  • 云开发是什么
  • 云函数客服消息推送
  • 实现功能
  • 参考资料

云开发是什么

Serverless 这个词这两年很是火,不了解的赶忙点击这里。个人理解 Serverless 是一种架构,云开发属于它的一种实现。node

云开发为开发者提供完整的原生云端支持和微信服务支持,弱化后端和运维概念,无需搭建服务器,接入sdk,即可使用平台提供的 API 进行核心业务开发,便可实现快速上线和迭代。数据库

云开发提供了几大基础能力支持:npm

能力 做用 说明
云函数 无需自建服务器 在云端运行的代码,微信私有协议自然鉴权,开发者只需编写自身业务逻辑代码
数据库 无需自建数据库 一个既可在小程序前端操做,也能在云函数中读写的 JSON 数据库
云存储 无需自建存储和 CDN 在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理
云调用 原生微信服务集成 基于云函数免鉴权使用小程序开放接口的能力,包括服务端调用、获取开放数据等能力

在开发者工具工具栏左侧,点击云开发按钮便可打开云控制台、根据提示开通云开发、建立云环境。默认配额下能够建立两个环境,各个环境相互隔离,每一个环境都包含独立的数据库实例、存储空间、云函数配置等资源。每一个环境都有惟一的环境 ID 标识,初始建立的环境自动成为默认环境。json

上面是官方介绍,总之肯定你开启云开发功能。小程序

云函数客服消息推送

开通了云开发的小程序可使用云函数接收消息推送,目前仅支持客服消息推送后端

云调用会用到2个API:api

  • customerServiceMessage.send
  • customerServiceMessage.uploadTempMedia

customerServiceMessage.send

能够推送四种类型消息服务器

| 属性 |说明|
| -------- | :-----: |
|text | 文本消息,msgtype="text" |
|image |图片消息,msgtype="image"
|link |图文连接,msgtype="link"
|miniprogrampage | 小程序卡片,msgtype="miniprogrampage" |

此次只用到textimage两种,linkminiprogrampage暂时没用到。image图片类型有个要求:传入media_id参数,为发送的图片的媒体ID,需经过 新增素材接口(customerServiceMessage.uploadTempMedia) 上传图片文件得到。

customerServiceMessage.uploadTempMedia

把媒体文件上传到微信服务器。目前仅支持图片。用于发送客服消息或被动回复用户消息,放到下面功能实现介绍。

实现功能

先说下咱们的需求:

用户点击弹窗的引导图,打开客服消息窗口,主动推送一条带提示操做的欢迎消息,当用户输入'1',会推送二维码图片。

因为咱们的公司小程序比较早就存在了,结构已经不轻易调整,开始觉得会比较难集成,没想到只需简单配置就能够,在根目录新增文件夹cloudfunctions存放云函数,在根目录的 project.config.json 文件,新增 cloudfunctionRoot 字段,指定cloudfunctions为云函数本地根目录,

{
   "cloudfunctionRoot": "cloudfunctions/",
}

完成指定以后,云函数的根目录的图标会变成“云目录图标”,云函数根目录下的第一级目录(云函数目录)是与云函数名字相同的,若是对应的线上环境存在该云函数,则会用一个特殊的 “云图标” 标明:

接着,在云函数根目录上右键菜单中,选择建立一个新的 Node.js 云函数,咱们将该云函数命名为 kefumsg,在本地建立出云函数目录和入口index.js文件,同时在线上环境中建立出对应的云函数。

一个目录表明一个云函数,通常是两个文件组成,index.jspackage.json,这里手动新增config.json文件,用于配置使用customerServiceMessage.send的权限:

{
    "permissions": {
        "openapi": [
            "customerServiceMessage.send",
            "customerServiceMessage.uploadTempMedia"
        ]
    }
}

如下是kefumsg云函数的目录:

node_modules是本地调试生成的,放后面说。先上传二维码图片到云存储,微信开发工具打开云开发->存储->上传文件

这里的File ID下面会用到。

编写云函数

打开kefumsg云函数的目录index.js文件,替换为如下代码:

const cloud = require('wx-server-sdk')
cloud.init()

<!--下载云存储图片-->
let downLoad = async(event, context) => {
    const res = await cloud.downloadFile({
        fileID: 'cloud://kefumsg-n350x.6769-kefumsg-n350x-1302104716/1588064201743.png', // 图片的File ID
    })
    const buffer = res.fileContent
    console.log(buffer)
    return buffer
}

<!--把媒体文件上传到微信服务器-->
let upload = async(Buffer) => {
    return await cloud.openapi.customerServiceMessage.uploadTempMedia({
        type: 'image',
        media: {
            contentType: 'image/png',
            value: Buffer
        }
    })
}


exports.main = async(event, context) => {
    const wxContext = cloud.getWXContext()

    if (event.Content == '1') {
        let Buffer = await downLoad()
        let meida = await upload(Buffer)
            // console.log(meida)
        try {
            <!--发送图片类型消息-->
            const result = await cloud.openapi.customerServiceMessage.send({
                touser: wxContext.OPENID,
                "msgtype": "image",
                "image": {
                    "media_id": meida.mediaId
                }
            })
            return result
        } catch (err) {
            return err
        }
    } else if (event.Title == '自定义标题') { 
    // 根据自定义卡片title触发
        let Buffer = await downLoad()
        let meida = await upload(Buffer)
        try {
            const result = await cloud.openapi.customerServiceMessage.send({
                touser: wxContext.OPENID,
                "msgtype": "image",
                "image": {
                    "media_id": meida.mediaId
                }
            })
            return result
        } catch (err) {
            return err
        }
    } else {
        try {
            await cloud.openapi.customerServiceMessage.send({
                touser: wxContext.OPENID,
                msgtype: 'text',
                text: {
                    content: '您好,很高兴为您服务。回复1,查看入群二维码'
                }
            });
            return 'success'
        } catch (err) {
            return err
        }
    }
}

你确定会好奇为何又是download(),又是upload()的,这里会有点绕,跟着我来理解下:

  1. 首先二维码图片放在云存储,先要经过cloud.downloadFile下载找到对应的buffer值,
  2. 而后openapi.customerServiceMessage.uploadTempMediamedia类型只接受Buffer,上传成功返回mediaId标识(媒体文件上传后,获取标识,3天内有效),
  3. 传给openapi.customerServiceMessage.sendimagemedia_id属性,

这样才能成功返回图片类型消息。若是各位大佬有好的办法请告知我。

上传并部署

云函数编写完成,在kefumsg云函数的目录右键,选择上传并部署:全部文件,一键推送至云而且自动返回部署成功与否的消息。

接着,在开发工具云开发控制台中选择设置->全局设置->添加消息推送,添加一条配置,这里只选择text类型:

肯定保存

根据咱们需求,用户点开客服,会自动推送一条消息,通过测试,配置text类型才会主动推送,如配置多条,只能用户主动发送消息才能触发推送。

调用云函数

首先,在小程序app.js头添加:

wx.cloud.init()

在页面.wxml添加打开客服对话框:

<!--发送卡片,title很重要,做为触发器关键-->
<button open-type="contact" bindcontact="handleContact" show-message-card="true" send-message-title="自定义标题" send-message-img="https://s3.pstatp.com/toutiao/static/img/logo.271e845.png"/>

对应的.js添加:

wx.cloud.callFunction({
    name: 'kefumsg'  // 名字和云函数名字对应
}).then(res => {
    console.log(res)
}).catch(err => {
    console.error(err)
})

打开微信开发工具预览扫码,需真机调试才能看到效果,如无报错,点击按钮,会弹出“您好,很高兴为您服务。回复1,查看入群二维码”,回复1,会弹窗二维码图片:

云函数本地调试

每次开发完都要提交部署,一旦网速慢我很反感觉不了。这时能够利用云函数本地调试功能。在kefumsg云函数的目录右键,选择开启云函数本地调试,因为使用npmwx-server-sdk(云函数的运行环境是 Node.js,所以在本地安装依赖时务必保证已安装 Node.js),须要在该目录执行终端命令安装依赖包yarn install,不然会报错,安装完成会打开窗口:

勾选开启本地调试,点击调用按钮,能够看到执行:

若有报错也能够一目了然,待修改测试完成再推到云端便可。

45047 错误码,意思是微信客服消息在向客户推送时,可连续发送20条(也不必定),若是期间客户没有回复,或超过限额,会中止发送,除非客户回复一下。

参考资料

小结

以前我有基于leancloud知晓云开发经验,他们给我体验都挺好,对于这类型的开发模式我还算熟悉,初步接入客服消息功能只花了1小时左右时间,相比于传统开发模式,云开发给我了我足够的信心,让我专一于业务的开发,接下来我会把更多实际功能转移到云开发上面来(继续搬砖)。

原文发于掘金:https://juejin.im/post/5eba49...

相关文章
相关标签/搜索