您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關微信小程序如何實現在線客服自動回復功能,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
效果圖
曲線救國的方式,利用小程序的在線功能可以打開H5的方式,去進行下載引導。
于是,就引出了這次文檔的主題,小程序在線客服自動回復功能。
閱讀本文檔之前,最好已經了解過小程序客服信息官方的相關文檔:
客服消息使用指南
小程序客服消息服務端接口
客服消息開發文檔
這次開發做在線客服功能也踩了不少坑,網上也查閱不少資料,但大部分的后臺都是基于php或者python,java開發,node.js開發的較少,因此將這次開發的流程記錄一下,供大家參考,避免大家踩坑。可能會有一些錯誤地方歡迎指正交流。
另外,我們用的node框架是基于koa自行封裝的,在一些細節實現上和其他框架會有區別,不必糾結。
需求描述
小程序中點按鈕跳轉在線客服界面,根據關鍵詞自動回復
客服回復判斷條件,支持cms配置key,及 respond
respond 支持配置以下類型,及回復內容:
type | 內容 |
---|---|
text | text=文本回復內容 |
link | title=標題 description=描述 url=跳轉鏈接 thumb_url=圖片地址 |
image | imageurl=圖片地址 |
配置后用戶需要精準匹配回復條件才可收到自動回復
可支持配置多個key,及對應respond
除了配置的key以外的回復,可配置默認的自動回復
開發流程
寫個跳轉客服的按鈕吧
index.wxml
<button open-type="contact">轉在線客服</button>
后臺配置
登錄小程序后臺后,在「開發」-「開發設置」-「消息推送」中,管理員掃碼啟用消息服務,填寫服務器地址(URL)、令牌(Token) 和 消息加密密鑰(EncodingAESKey)等信息。
1.URL服務器地址
URL: 開發者用來接收微信消息和事件的接口 URL。開發者所填寫的URL 必須以 http:// 或 https:// 開頭,分別支持 80 端口和 443 端口。
務必要記住,服務器地址必須是線上地址,因為需要微信服務器去訪問。localhost,IP,內網地址都不行的。
不然會提示 '解析失敗,請檢查信息是否填寫正確'。
那么問題來了,不同的公司都有一套上線流程,總不能為了調試URL是否可用要上到線上去測試,成本太大,也不方便。
這就要引出內網穿透了,簡單來說就是配置一個線上域名,但是這個域名可以穿透到你配置的本地開發地址上,這樣可以方便你去調試看日志。
推薦一個可以實現內網穿透的工具。(非廣告)
NATAPP 具體不詳細介紹,免得廣告嫌疑。
簡單說,NATAPP有免費和付費兩種模式,免費的是域名不定時更換,對于微信的推送消息配置一個月只有3次更改機會來說,有點奢侈。不定什么時候配置的域名就不能訪問,得重新配置。而付費的則是固定域名,映射的內網地址也可以隨時更改。樓主從免費切到付費模式,一個月的VIP使用大概十幾塊錢吧。
2.Token
Token自己隨便寫就行了,但是要記住它,因為你在接口中要用的。
3.EncodingAESKey
隨機生成即可。
4.加密方式和數據格式
根據自己喜歡選擇,樓主選擇的安全模式和JSON格式。
不同的模式和數據格式,在開發上會有不同,自己衡量。
既然這些配置都清楚,那開始碼代碼。
驗證消息的確來自微信服務器
配置提交前,需要把驗證消息來自微信服務器的接口寫好。
server.js
/* * https://developers.weixin.qq.com/miniprogram/dev/framework/server-ability/message-push.html * 驗證消息的確來自微信服務器 * 開發者通過檢驗 signature 對請求進行校驗(下面有校驗方式)。 * 若確認此次 GET 請求來自微信服務器,請原樣返回 echostr 參數內容, * 則接入生效,成為開發者成功,否則接入失敗。加密/校驗流程如下: * 將token、timestamp、nonce三個參數進行字典序排序 * 將三個參數字符串拼接成一個字符串進行sha1加密 * 開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信 */ const crypto = require('crypto'); async wxCallbackAction(){ const ctx = this.ctx; const method = ctx.method; //微信服務器簽名驗證,確認請求來自微信 if(method === 'GET') { // 1.獲取微信服務器Get請求的參數 signature、timestamp、nonce、echostr const { signature, timestamp, nonce, echostr } = ctx.query; // 2.將token、timestamp、nonce三個參數進行字典序排序 let array = ['yourToken', timestamp, nonce]; array.sort(); // 3.將三個參數字符串拼接成一個字符串進行sha1加密 const tempStr = array.join(''); const hashCode = crypto.createHash('sha1'); //創建加密類型 const resultCode = hashCode.update(tempStr, 'utf8').digest('hex'); // 4.開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信 if (resultCode === signature) { console.log('驗證成功,消息是從微信服務器轉發過來'); return this.json(echostr); }else { console.log('驗證失敗!!!'); return this.json({ status: -1, message: "驗證失敗" }); } } }
驗證接口開發完畢,后臺配置可以去點提交了。配置成功會提示如下:
接收消息和推送消息
當用戶在客服會話發送消息、或由某些特定的用戶操作引發事件推送時,微信服務器會將消息或事件的數據包發送到開發者填寫的 URL。開發者收到請求后可以使用 發送客服消息 接口進行異步回復。
本文以接收文本消息為例開發:
server.js
const WXDecryptContact = require('./WXDecryptContact'); async wxCallbackAction(){ const ctx = this.ctx; const method = ctx.method; //接收信息時 為POST請求;(完整代碼自行與上面驗證時的合并即可) if(method === 'POST'){ const { Encrypt } = ctx.request.body; //配置時選的安全模式 因此需要解密 if(!Encrypt){ return this.json('success'); } const decryptData = WXDecryptContact(Encrypt); await this._handleWxMsg(decryptData); return this.json('success'); }else{ return this.json('success'); } } //處理微信回調消息的總入口 (只處理了文本類型,其他類型自行添加) async _handleWxMsg(msgJson){ if(!msgJson){ return this.json('success'); } const { MsgType } = msgJson; if(MsgType === 'text'){ await this._sendTextMessage(msgJson); } } //微信文本信息關鍵字自動回復 async _sendTextMessage(msgJson){ //獲取CMS客服關鍵詞回復配置 const result = await this.callService('cms.getDataByName', 'wxApplet.contact'); let keyWordObj = result.data || {}; //默認回復default let options = keyWordObj.default; for(let key in keyWordObj){ //查看是否命中配置的關鍵詞 if(msgJson.Content === key){ //CMS配置項 options = keyWordObj[key]; } } } //獲取access_token const accessToken = await this._getAccessToken(); /* * 先判斷配置回復的消息類型是不是image類型 * 如果是 則需要先通過 新增素材接口 上傳圖片文件獲得 media_id */ let media_id = ''; if(options.type === 'image'){ //獲取圖片地址(相對路徑) let url = options.url; const file = fs.createReadStream(url); //調用微信 uploadTempMedia接口 具體實現見 service.js const mediaResult = await this.callService('wxApplet.uploadTempMedia', { access_token: accessToken, type: 'image' }, { media: file } ); if(mediaResult.status === 0){ media_id = mediaResult.data.media_id; }else { //如果圖片id獲取失敗 則按默認處理 options = keyWordObj.default; } } //回復信息給用戶 const sendMsgResult = await this.callService('wxApplet.sendMessageToCustomer', { access_token: accessToken, touser: msgJson.FromUserName, msgtype: options.type || 'text', text: { content: options.description || '', }, link: options.type === "link" ? { title: options.title, description: options.description, url: options.url, thumb_url: options.thumb_url } : {}, image: { media_id } } ); }
service.js
const request = require('request'); /* * 獲取CMS客服關鍵詞回復配置 * 這個接口只是為了回去CMS配置的字段回復關鍵字配置 返回的data數據結構如下 */ async contact(){ return { data: { "1": { "type": "link", "title": "點擊下載[****]APP", "description": "注冊領取領***元注冊紅包禮", "url": "https://m.renrendai.com/mo/***.html", "thumb_url": "https://m.we.com/***/test.png" }, "2": { "url": "http://m.renrendai.com/cms/****/test.jpg", "type": "image" }, "3": { "url": "/cms/***/test02.png", "type": "image" }, "default": { "type": "text", "description": "再見" } } } } /* * 把媒體文件上傳到微信服務器。目前僅支持圖片。用于發送客服消息或被動回復用戶消息。 * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.uploadTempMedia.html */ async uploadTempMedia(data,formData){ const url = `https://api.weixin.qq.com/cgi-bin/media/upload?access_token=${data.access_token}&type=${data.type}`; return new Promise((resolve, reject) => { request.post({url, formData: formData}, (err, response, body) => { try{ const out = JSON.parse(body); let result = { data: out, status: 0, message: "ok" } return resolve(result); }catch(err){ return reject({ status: -1, message: err.message }); } }); } } /* * 發送客服消息給用戶 * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/customer-message/customerServiceMessage.send.html */ async sendMessageToCustomer(data){ const url = `https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=${data.access_token}`; return new Promise((resolve, reject) => { request.post({url, data}, (err, response, body) => { ... }); } }
WXDecryptContact.js
消息加密解密文檔
const crypto = require('crypto'); // 加密模塊 const decodePKCS7 = function (buff) { let pad = buff[buff.length - 1]; if (pad < 1 || pad > 32) { pad = 0; } return buff.slice(0, buff.length - pad); }; // 微信轉發客服消息解密 const decryptContact = (key, iv, crypted) => { const aesCipher = crypto.createDecipheriv('aes-256-cbc', key, iv); aesCipher.setAutoPadding(false); let decipheredBuff = Buffer.concat([aesCipher.update(crypted, 'base64'), aesCipher.final()]); decipheredBuff = decodePKCS7(decipheredBuff); const lenNetOrderCorpid = decipheredBuff.slice(16); const msgLen = lenNetOrderCorpid.slice(0, 4).readUInt32BE(0); const result = lenNetOrderCorpid.slice(4, msgLen + 4).toString(); return result; }; // 解密微信返回給配置的消息服務器的信息 const decryptWXContact = (wechatData) => { if(!wechatData){ wechatData = ''; } //EncodingAESKey 為后臺配置時隨機生成的 const key = Buffer.from(EncodingAESKey + '=', 'base64'); const iv = key.slice(0, 16); const result = decryptContact(key, iv, wechatData); const decryptedResult = JSON.parse(result); console.log(decryptedResult); return decryptedResult; }; module.exports = decryptWXContact;
呼~ 代碼終于碼完,來看看效果:
總結
開發并不是一帆風順的,也遇到了一些值得留意的坑,強調一下:
后臺配置URL地址一定外網可訪問(可以通過內網穿透解決)
文件上傳接口uploadTempMedia media參數要用 FormData數據格式 (用node的request庫很容易實現。urllib這個庫有坑有坑 都是淚T_T)
切記接收消息不論成功失敗都要返回success,不然即使成功接收返回消息,日志沒有報錯的情況下,還是出現IOS提示該小程序提供的服務出現故障 請稍后再試。
關于“微信小程序如何實現在線客服自動回復功能”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。