- 云调用能力—客服消息
在前面的章节,我们已经在小程序端将 button 组件 open-type 的值设置为 contact ,点击 button 就可以进入客服消息。不过这个客服消息使用的是官方的后台,没法进行深度的定制,我们可以使用云开发作为后台来自定义客服消息来实现快捷回复、添加常用回答等功能。 如果是使用传统的开发方式,需要填写服务器地址(URL)、令牌(Token) 和 消息加密密钥(EncodingAESKey)等信息,然后结合将 token、timestamp、nonce 三个参数进行字典序排序、拼接、并进行 sha1 加密,然后将加密后的字符串与 signature 对比来验证消息的确来自微信服务器,之后再来进行接收消息和事件的处理,可谓十分繁琐,而使用云开发相对简单很多。 13.8.1 客服消息的配置与说明使用开发者工具新建一个云函数,比如 customer,在 config.json 里,设置以下权限后部署上传到服务端。 { "permissions": { "openapi": [ "customerServiceMessage.send", "customerServiceMessage.getTempMedia", "customerServiceMessage.setTyping", "customerServiceMessage.uploadTempMedia" ] } } 然后再打开云开发控制台,点击右上角的设置,选择全局设置,开启云函数接收消息推送,添加消息推送配置。为了学习方便我们将所有的消息类型都指定推送到 customer 云函数里。 text,文本消息image,图片消息miniprogram,小程序卡片event,事件类型 user_enter_tempsession,进入客服消息时就会触发以上有四种消息类型,但是发送客服消息的 customerServiceMessage.send 的 msgtype 属性的合法值有 text、image、link(图文链接消息)、miniprogrampage 四种,也就是我们还可以发图文链接消息。 13.8.2 自动回复文本消息和链接1、自动回复文本消息使用开发者工具新建一个页面,比如 customer,然后在 customer.wxml 里输入以下按钮, 进入客服button> 当用户通过 button 进入到客服消息之后,在聊天界面回复信息,就能触发设置好的 customer 云函数,比如下面的例子就是当用户发一条消息(包括表情)到客服消息会话界面,云函数就会给调用 customerServiceMessage.send 接口给用户回复两条文本消息(一次性可以回复多条),内容分别为[代码]等候您多时啦[代码]和[代码]欢迎关注云开发技术训练营[代码],一个云函数里也是可以多次调用接口的: const cloud = require("wx-server-sdk"); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }); exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); try { const result = await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: "text", text: { content: "等候您多时啦", }, }); const result2 = await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: "text", text: { content: "欢迎关注云开发技术训练营", }, }); return event; } catch (err) { console.log(err); return err; } }; 发送文本消息时,支持插入跳小程序的文字链接的,比如我们把上面的文本消息改为以下代码: content: '欢迎浏览点击跳小程序a>'; data-miniprogram-appid 项,填写小程序 appid,则表示该链接跳小程序;data-miniprogram-path 项,填写小程序路径,路径与 app.json 中保持一致,可带参数;对于不支持 data-miniprogram-appid 项的客户端版本,如果有 herf 项,则仍然保持跳 href 中的网页链接;data-miniprogram-appid 对应的小程序必须与公众号有绑定关系。 2、自动回复链接我们还可以给用户回复链接,我们可以把 customer 云函数修改为以下代码,当用户向微信聊天对话界面发送一条消息时,就会回复给用户一个链接,这个链接可以是外部链接哦。 const cloud = require("wx-server-sdk"); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }); exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); try { const result = await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: "link", link: { title: "快来加入云开发技术训练营", description: "零基础也能在10天内学会开发一个小程序", url: "https://cloud.tencent.com/", thumbUrl: "https://tcb-1251009918.cos.ap-guangzhou.myqcloud.com/love.png", }, }); return event; } catch (err) { console.log(err); return err; } }; 3、根据关键词来回复用户将上面的云函数部署之后,当用户向客服消息的聊天会话里输入内容时,不管用户发送的是什么内容,云函数都会回给用户相同的内容,这未免有点过于死板,客服消息能否根据用户发送的关键词回复用户不同的内容呢?要做到这一点我们需要能够获取到用户发送的内容。 我们可以留意云开发控制台云函数日志里看到,customer 云函数返回的 event 对象里的 Content 属性就会记录用户发到聊天会话里的内容: {"Content":"请问怎么加入云开发训练营", "CreateTime":1582877109, "FromUserName":"oUL-mu...XbuEDsn8", "MsgId":22661351901594052, "MsgType":"text", "ToUserName":"gh_b2bbe22535e4", "userInfo":{"appId":"wxda99ae4531b57046","openId":"oUL-m5FuRmuVmxvbYOGuXbuEDsn8"}} 由于 Content 是字符串,那这个关键词既可以是非常精准的,比如“训练营”,或“云开发训练营”,还可以是非常模糊的“请问怎么加入云开发训练营”,我们只需要对字符串进行正则匹配处理即可,比如当用户只要发的内容包含“训练营”,就会收到链接: const cloud = require("wx-server-sdk"); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }); exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); const keyword = event.Content; try { if (keyword.search(/训练营/i) != -1) { const result = await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: "link", link: { title: "快来加入云开发技术训练营", description: "零基础也能在10天内学会开发一个小程序", url: "https://cloud.tencent.com/", thumbUrl: "https://tcb-1251009918.cos.ap-guangzhou.myqcloud.com/love.png", }, }); } return event; } catch (err) { console.log(err); return err; } }; 在前面的案例里,我们都是使用[代码]touser: wxContext.OPENID,[代码], 13.8.2 自动触发 event 事件要触发 event 事件,我们可以将 customer.wxml 的按钮改为如下代码,这里的 session-from 是用户从该按钮进入客服消息会话界面时,开发者将收到带上本参数的事件推送,可用于区分用户进入客服会话的来源。 进入客服button> 由于我们开启了 event 类型的客服消息,事件类型的值为 user_enter_tempsession,当用户点击 button 进入客服时,就会触发云函数,不用用户发消息就能触发,同时我们返回 event 对象. const cloud = require("wx-server-sdk"); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }); exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); try { const result = await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: "text", text: { content: "欢迎来到等候您多时啦", }, }); return event; } catch (err) { console.log(err); return err; } }; 我们可以去云开发控制台查看返回的 event 对象 {"CreateTime":1582876587, "Event":"user_enter_tempsession", "FromUserName":"oUL-m5F...8", "MsgType":"event", "SessionFrom":"文章详情的客服按钮", "ToUserName":"gh_b2bbe22535e4", "userInfo":{"appId":"wxda9...57046", "openId":"oUL-m5FuRmuVmx...sn8"}} 在云函数端,我们是可以通过 event.SessionFrom 来获取到用户到底是点击了哪个按钮从而进入客服对话的,也可以根据用户进入客服会话的来源不同,给用户推送不同类型,比如我们可以给 session-from 的值设置为“训练营”,当用户进入客服消息会话就能推送相关的信息给到用户。 还有一点就是,bindcontact 是给客服按钮绑定了了一个事件处理函数,这里为 onCustomerServiceButtonClick,通过事件处理函数我们可以在小程序端做很多事情,比如记录用户点击了多少次带有标记(比如 session-from 的值设置为“训练营”)的客服消息的按钮等功能。 13.8.3 自动回复图片要在客服消息里给用户回复图片,这个图片的来源只能是来源于微信服务器,我们需要先使用 customerServiceMessage.uploadTempMedia,把图片文件上传到微信服务器,获取到 mediaId(有点类似于微信服务器的 fileID),然后才能在客服消息里使用。 在 customer 云函数的 index.js 里输入以下代码并部署上线,我们将获取到的 mediaId 使用 cloud.openapi.customerServiceMessage.send 发给用户: const cloud = require("wx-server-sdk"); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }); exports.main = async (event, context) => { const wxContext = cloud.getWXContext(); try { //我们通常会将云存储的图片作为客服消息媒体文件的素材 const fileID = "cloud://xly-xrlur.786c-xly-xrlur-1300446086/1572315793628-366.png"; //uploadTempMedia的图片类型为Buffer,而从存储下载的图片格式也是Buffer const res = await cloud.downloadFile({ fileID: fileID, }); const Buffer = res.fileContent; const result = await cloud.openapi.customerServiceMessage.uploadTempMedia({ type: "image", media: { contentType: "image/png", value: Buffer, }, }); console.log(result.mediaId); const mediaId = result.mediaId; const wxContext = cloud.getWXContext(); const result2 = await cloud.openapi.customerServiceMessage.send({ touser: wxContext.OPENID, msgtype: "image", image: { mediaId: mediaId, }, }); return event; } catch (err) { console.log(err); return err; } }; 客服消息还能给用户回复小程序消息卡片,以及客服当前的输入状态给用户(使用 customerServiceMessage.setTyping 接口)。
2021-09-10 - 小程序开发实战
高校大赛系列课程之“小程序开发实战”,是由清华大学和微信团队共制作的小程序学习教程。通过需求分析、原型设计、小程序前端实现、后台接口开发、小程序对接接口,逐步教大家如何“从无到有”完成小程序项目
2021-11-25