小册 《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" |
这次只用到text
,image
两种,link
和miniprogrampage
暂时没用到。image
图片类型有个要求:传入media_id
参数,为发送的图片的媒体ID,需通过 新增素材接口(customerServiceMessage.uploadTempMedia) 上传图片文件获得。
customerServiceMessage.uploadTempMedia
把媒体文件上传到微信服务器。目前仅支持图片。用于发送客服消息或被动回复用户消息,放到下面功能实现介绍。
实现功能
先说下我们的需求:
用户点击弹窗的引导图,打开客服消息窗口,主动推送一条带提示操作的欢迎消息,当用户输入'1',会推送二维码图片。
由于我们的公司小程序比较早就存在了,结构已经不轻易调整,开始以为会比较难集成,没想到只需简单配置就可以,在根目录新增文件夹cloudfunctions
存放云函数,在根目录的 project.config.json 文件,新增 cloudfunctionRoot 字段,指定cloudfunctions
为云函数本地根目录,
{
"cloudfunctionRoot": "cloudfunctions/",
}
完成指定之后,云函数的根目录的图标会变成“云目录图标”,云函数根目录下的第一级目录(云函数目录)是与云函数名字相同的,如果对应的线上环境存在该云函数,则会用一个特殊的 “云图标” 标明:
接着,在云函数根目录上右键菜单中,选择创建一个新的 Node.js 云函数,我们将该云函数命名为 kefumsg
,在本地创建出云函数目录和入口index.js
文件,同时在线上环境中创建出对应的云函数。
一个目录代表一个云函数,一般是两个文件组成,index.js
,package.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()
的,这里会有点绕,跟着我来理解下:
- 首先二维码图片放在云存储,先要通过
cloud.downloadFile
下载找到对应的buffer
值, - 然后
openapi.customerServiceMessage.uploadTempMedia
的media
类型只接受Buffer
,上传成功返回mediaId
标识(媒体文件上传后,获取标识,3天内有效), - 传给
openapi.customerServiceMessage.send
的image
的media_id
属性,
这样才能成功返回图片类型消息。如果各位大佬有好的办法请告知我。
上传并部署
云函数编写完成,在kefumsg
云函数的目录右键,选择上传并部署:所有文件
,一键推送至云并且自动返回部署成功与否的消息。
接着,在开发工具云开发控制台
中选择设置
->全局设置
->添加消息推送
,添加一条配置,这里只选择text
类型:
确定保存
根据我们需求,用户点开客服,会自动推送一条消息,经过测试,配置text
类型才会主动推送,如配置多条,只能用户主动发送消息才能触发推送。
调用云函数
首先,在小程序app.js
头添加:
wx.cloud.init()
在页面.wxml
添加打开客服对话框:
对应的.js
添加:
wx.cloud.callFunction({
name: 'kefumsg' // 名字和云函数名字对应
}).then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})
打开微信开发工具预览
扫码,需真机调试才能看到效果,如无报错,点击按钮,会弹出“您好,很高兴为您服务。回复1,查看入群二维码”,回复1,会弹窗二维码图片:
云函数本地调试
每次开发完都要提交部署,一旦网速慢我很反感受不了。这时可以利用云函数本地调试
功能。在kefumsg
云函数的目录右键,选择开启云函数本地调试
,由于使用npm
包wx-server-sdk
(云函数的运行环境是 Node.js,因此在本地安装依赖时务必保证已安装 Node.js),需要在该目录执行终端命令安装依赖包yarn install
,否则会报错,安装完成会打开窗口:
勾选开启本地调试
,点击调用
按钮,可以看到执行:
如有报错也可以一目了然,待修改测试完成再推到云端即可。
45047 错误码,意思是微信客服消息在向客户推送时,可连续发送20条(也不一定),如果期间客户没有回复,或超过限额,会停止发送,除非客户回复一下。
参考资料
小结
之前我有基于leancloud
,知晓云
开发经验,他们给我体验都挺好,对于这类型的开发模式我还算熟悉,初步接入客服消息功能只花了1小时左右时间,相比于传统开发模式,云开发给我了我足够的信心,让我专注于业务的开发,接下来我会把更多实际功能转移到云开发上面来(继续搬砖)。