蜜桃无码视频,欧美日韩一=三道夲,国产精品午夜AV电影网免费看,aaa.www

歡迎來(lái)到 常識(shí)詞典網(wǎng) , 一個(gè)專業(yè)的常識(shí)知識(shí)學(xué)習(xí)網(wǎng)站!

[ Ctrl + D 鍵 ]收藏本站

您所在的位置:首頁(yè) > 教育學(xué)習(xí) > 問(wèn)答

問(wèn)答

小程序客服怎么設(shè)置自動(dòng)回復(fù),小程序自動(dòng)回復(fù)功能設(shè)置教程

分類(lèi): 問(wèn)答 常識(shí)詞典 編輯 : 常識(shí) 發(fā)布 : 04-15

閱讀 :221

小程序在線客服自動(dòng)回復(fù)功能(node版) 前言 我們知道H5頁(yè)面經(jīng)常需要將用戶導(dǎo)流到APP,通過(guò)下載安裝包或者跳轉(zhuǎn)至應(yīng)用寶市場(chǎng)/Appstore等方式進(jìn)行導(dǎo)流。但是由于小程序嵌套webview時(shí)需要校驗(yàn)域名,因此跳轉(zhuǎn)到第三方應(yīng)用市場(chǎng)和Appstroe無(wú)法實(shí)現(xiàn)導(dǎo)流。那怎么辦呢? 只能說(shuō)道高一尺魔高一丈,看看微博小程序是怎么導(dǎo)流的: 曲線救國(guó)的方式,利用小程序的在線功能可以打開(kāi)H5的方式,去進(jìn)行下載引導(dǎo)。 于是,就引出了這次文檔的主題,小程序在線客服自動(dòng)回復(fù)功能。 閱讀本文檔之前,最好已經(jīng)了解過(guò)小程序客服信息官方的相關(guān)文檔: 1.客服消息使用指南 2.小程序客服消息服務(wù)端接口 3.客服消息開(kāi)發(fā)文檔 這次開(kāi)發(fā)做在線客服功能也踩了不少坑,網(wǎng)上也查閱不少資料,但大部分的后臺(tái)都是基于php或者python,java開(kāi)發(fā),node.js開(kāi)發(fā)的較少,因此將這次開(kāi)發(fā)的流程記錄一下,供大家參考,避免大家踩坑??赡軙?huì)有一些錯(cuò)誤地方歡迎指正交流。 另外,我們用的node框架是基于koa自行封裝的,在一些細(xì)節(jié)實(shí)現(xiàn)上和其他框架會(huì)有區(qū)別,不必糾結(jié)。 需求描述 小程序中點(diǎn)按鈕跳轉(zhuǎn)在線客服界面,根據(jù)關(guān)鍵詞自動(dòng)回復(fù) 客服回復(fù)判斷條件,支持cms配置key,及 respond respond 支持配置以下類(lèi)型,及回復(fù)內(nèi)容: type內(nèi)容texttext=文本回復(fù)內(nèi)容linktitle=標(biāo)題 description=描述 url=跳轉(zhuǎn)鏈接 thumb_url=圖片地址imageimageurl=圖片地址 配置后用戶需要精準(zhǔn)匹配回復(fù)條件才可收到自動(dòng)回復(fù) 可支持配置多個(gè)key,及對(duì)應(yīng)respond 除了配置的key以外的回復(fù),可配置默認(rèn)的自動(dòng)回復(fù) 開(kāi)發(fā)流程 寫(xiě)個(gè)跳轉(zhuǎn)客服的按鈕吧 .wxml <button open-type="contact">轉(zhuǎn)在線客服</button>復(fù)制代碼 后臺(tái)配置 登錄小程序后臺(tái)后,在「開(kāi)發(fā)」-「開(kāi)發(fā)設(shè)置」-「消息推送」中,管理員掃碼啟用消息服務(wù),填寫(xiě)服務(wù)器地址(URL)、令牌(Token) 和 消息加密密鑰(EncodingAESKey)等信息。 URL服務(wù)器地址 URL: 開(kāi)發(fā)者用來(lái)接收微信消息和事件的接口 URL。開(kāi)發(fā)者所填寫(xiě)的URL 必須以 http:// 或 https:// 開(kāi)頭,分別支持 80 端口和 443 端口。 務(wù)必要記住,服務(wù)器地址必須是線上地址,因?yàn)樾枰⑿欧?wù)器去訪問(wèn)。localhost,IP,內(nèi)網(wǎng)地址都不行的。 不然會(huì)提示 ‘解析失敗,請(qǐng)檢查信息是否填寫(xiě)正確’。 那么問(wèn)題來(lái)了,不同的公司都有一套上線流程,總不能為了調(diào)試URL是否可用要上到線上去測(cè)試,成本太大,也不方便。 這就要引出內(nèi)網(wǎng)穿透了,簡(jiǎn)單來(lái)說(shuō)就是配置一個(gè)線上域名,但是這個(gè)域名可以穿透到你配置的本地開(kāi)發(fā)地址上,這樣可以方便你去調(diào)試看日志。 推薦一個(gè)可以實(shí)現(xiàn)內(nèi)網(wǎng)穿透的工具。(非廣告 ) NATAPP 具體不詳細(xì)介紹,免得廣告嫌疑。 簡(jiǎn)單說(shuō),NATAPP有免費(fèi)和付費(fèi)兩種模式,免費(fèi)的是域名不定時(shí)更換,對(duì)于微信的推送消息配置一個(gè)月只有3次更改機(jī)會(huì)來(lái)說(shuō),有點(diǎn)奢侈。不定什么時(shí)候配置的域名就不能訪問(wèn),得重新配置。而付費(fèi)的則是固定域名,映射的內(nèi)網(wǎng)地址也可以隨時(shí)更改。樓主從免費(fèi)切到付費(fèi)模式,一個(gè)月的VIP使用大概十幾塊錢(qián)吧。 2.Token Token自己隨便寫(xiě)就行了,但是要記住它,因?yàn)槟阍诮涌谥幸玫摹?3.EncodingAESKey 隨機(jī)生成即可。 4.加密方式和數(shù)據(jù)格式 根據(jù)自己喜歡選擇,樓主選擇的安全模式和JSON格式。 不同的模式和數(shù)據(jù)格式,在開(kāi)發(fā)上會(huì)有不同,自己衡量。 既然這些配置都清楚,那開(kāi)始碼代碼。 驗(yàn)證消息的確來(lái)自微信服務(wù)器 配置提交前,需要把驗(yàn)證消息來(lái)自微信服務(wù)器的接口寫(xiě)好。 server.js const crypto = require('crypto'); async wxCallbackAction(){ const ctx = this.ctx; const method = ctx.method; //微信服務(wù)器簽名驗(yàn)證,確認(rèn)請(qǐng)求來(lái)自微信 if(method === 'GET') { // 1.獲取微信服務(wù)器Get請(qǐng)求的參數(shù) signature、timestamp、nonce、echostr const { signature, timestamp, nonce, echostr } = ctx.query; // 2.將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典序排序 let array = ['yourToken', timestamp, nonce]; array.sort(); // 3.將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密 const tempStr = array.join(''); const hashCode = crypto.createHash('sha1'); //創(chuàng)建加密類(lèi)型 const resultCode = hashCode.update(tempStr, 'utf8').digest('hex'); // 4.開(kāi)發(fā)者獲得加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來(lái)源于微信 if (resultCode === signature) { console.log('驗(yàn)證成功,消息是從微信服務(wù)器轉(zhuǎn)發(fā)過(guò)來(lái)'); return this.json(echostr); }else { console.log('驗(yàn)證失?。。?!'); return this.json({ status: -1, message: "驗(yàn)證失敗" }); } } }復(fù)制代碼 驗(yàn)證接口開(kāi)發(fā)完畢,后臺(tái)配置可以去點(diǎn)提交了。配置成功會(huì)提示如下: 接收消息和推送消息 當(dāng)用戶在客服會(huì)話發(fā)送消息、或由某些特定的用戶操作引發(fā)事件推送時(shí),微信服務(wù)器會(huì)將消息或事件的數(shù)據(jù)包發(fā)送到開(kāi)發(fā)者填寫(xiě)的 URL。開(kāi)發(fā)者收到請(qǐng)求后可以使用 發(fā)送客服消息 接口進(jìn)行異步回復(fù)。 本文以接收文本消息為例開(kāi)發(fā): server.js const WXDecryptContact = require('./WXDecryptContact'); async wxCallbackAction(){ const ctx = this.ctx; const method = ctx.method; //接收信息時(shí)為POST請(qǐng)求;(完整代碼自行與上面驗(yàn)證時(shí)的合并即可) if(method === 'POST'){ const { Encrypt } = ctx.request.body; //配置時(shí)選的安全模式 因此需要解密 if(!Encrypt){ return this.json('success'); } const decryptData = WXDecryptContact(Encrypt); await this._handleWxMsg(decryptData); return this.json('success'); } } //處理微信回調(diào)消息的總?cè)肟?(只處理了文本類(lèi)型,其他類(lèi)型自行添加) async _handleWxMsg(msgJson){ if(!msgJson){ return ; } const { MsgType } = msgJson; if(MsgType === 'text'){ await this._sendTextMessage(msgJson); } } //微信文本信息關(guān)鍵字自動(dòng)回復(fù) async _sendTextMessage(msgJson){ //獲取CMS客服關(guān)鍵詞回復(fù)配置 const result = await this.callService('cms.getDataByName', 'wxApplet.contact'); let keyWordObj = result.data || {}; //默認(rèn)回復(fù)default let options = keyWordObj.default; for(let key in keyWordObj){ //查看是否命中配置的關(guān)鍵詞 if(msgJson.Content === key){ //CMS配置項(xiàng) options = keyWordObj[key]; } } } //獲取access_token const accessToken = await this._getAccessToken(); let media_id = ''; if(options.type === 'image'){ //獲取圖片地址(相對(duì)路徑) let url = options.url; const file = fs.createReadStream(url); //調(diào)用微信 uploadTempMedia接口 具體實(shí)現(xiàn)見(jiàn) 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獲取失敗 則按默認(rèn)處理 options = keyWordObj.default; } } //回復(fù)信息給用戶 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 } } ); }復(fù)制代碼 service.js const request = require('request');async contact(){return {data: {"1": { "type": "link", "title": "點(diǎn)擊下載[****]APP", "description": "注冊(cè)領(lǐng)取領(lǐng)***元注冊(cè)紅包禮", "url": "https://m.renrendai/motest.png" }, "2": { "url": "http://m.renrendai/cmstest.jpg", "type": "image" }, "3": { "url": "/cmstest02.png", "type": "image" }, "default": { "type": "text", "description": "再見(jiàn)" }}}} async uploadTempMedia(data,formData){ const url = `https://api.weixin.qq/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 }); } }); } } async sendMessageToCustomer(data){ const url = `https://api.weixin.qq/cgi-bin/message/custom/send?access_token=${data.access_token}`; return new Promise((resolve, reject) => { request.post({url, data}, (err, response, body) => { ... }); } } 復(fù)制代碼 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);};// 微信轉(zhuǎn)發(fā)客服消息解密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;};// 解密微信返回給配置的消息服務(wù)器的信息const decryptWXContact = (wechatData) => { if(!wechatData){ wechatData = ''; } //EncodingAESKey 為后臺(tái)配置時(shí)隨機(jī)生成的 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;復(fù)制代碼 總結(jié) 開(kāi)發(fā)并不是一帆風(fēng)順的,也遇到了一些值得留意的坑,強(qiáng)調(diào)一下: 后臺(tái)配置URL地址一定外網(wǎng)可訪問(wèn)(可以通過(guò)內(nèi)網(wǎng)穿透解決) 文件上傳接口uploadTempMedia media參數(shù)要用 FormData數(shù)據(jù)格式 (用node的request庫(kù)很容易實(shí)現(xiàn)。urllib這個(gè)庫(kù)有坑有坑 都是淚T_T) 切記接收消息不論成功失敗都要返回success,不然即使成功接收返回消息,日志沒(méi)有報(bào)錯(cuò)的情況下,還是出現(xiàn)IOS提示該小程序提供的服務(wù)出現(xiàn)故障 請(qǐng)稍后再試。

下一篇:人人貸是什么平臺(tái),人人貸公司簡(jiǎn)介 下一篇 【方向鍵 ( → )下一篇】

上一篇:erp軟件是什么意思,erp軟件系統(tǒng)的特點(diǎn)及作用 上一篇 【方向鍵 ( ← )上一篇】

国产午夜福利精品一区二区三区| 欧美精品午夜| 欧美熟妇成人| 亚洲熟妇色XXXXX亚洲| 成人一级| 久久三级电影免费| 日本视频网站一区二区www| 黑人大屌亚洲女人| 亚洲国产高潮高清一区| 久久成人亚洲欧美电影| 成人av网址观看| 日韩精品乱| 农村老熟妇乱子伦视频| 欧洲AⅤ亚洲AV综合AV日韩A...| 亚洲区在线| 五月丁香激情四月| 久久久久亚洲AV无码去区首| 亚洲无码黄色网址| 五月丁香亚洲激情| 7777精品久久久大香线蕉 | 国产精品无码一本二本三本色| 99只有精品| 亚洲一码和欧洲二码黑人| 国产成人无码AV片在线观看不卡| 久久久久无码国产精品一区肉丝| 人妻侵犯欧美| 国产高清无码在线观看| 日韩精品一区二区二三区色欲a| 国产精品国产三级国产aⅴ原创 | 国产精品性爱| 一级红色毛片| 瑟婷婷| Av中文字幕乱码免费看| 亚洲精品欧美精品午夜精品| 色偷偷蜜臀| 久久久一本精品99久久精品66| 丝瓜视频黄色| 色五月开心网| 365你懂的| 中文国产成人精品久久水| 人体国模无码|