阅读 425

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

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

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

引言

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

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

云开发是什么

Serverless 这个词这两年非常火,不了解的赶紧点击这里。我的理解 Serverless 是一种架构,云开发属于它的一种实现。

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

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

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

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

上面是官方介绍,总之确定你开启云开发功能。

云函数客服消息推送

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

云调用会用到2个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小时左右时间,相比于传统开发模式,云开发给我了我足够的信心,让我专注于业务的开发,接下来我会把更多实际功能转移到云开发上面来(继续搬砖)。

关注下面的标签,发现更多相似文章
评论