亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 課堂 > 小程序 > 正文

微信小程序在線客服自動回復功能(基于node)

2020-03-21 15:52:48
字體:
來源:轉載
供稿:網友

前言

我們知道H5頁面經常需要將用戶導流到APP,通過下載安裝包或者跳轉至應用寶市場/Appstore等方式進行導流。但是由于小程序嵌套webview時需要校驗域名,因此跳轉到第三方應用市場和Appstroe無法實現導流。那怎么辦呢?

只能說道高一尺魔高一丈,看看微博小程序是怎么導流的:

微信小程序,在線客服,自動回復

曲線救國的方式,利用小程序的在線功能可以打開H5的方式,去進行下載引導。

于是,就引出了這次文檔的主題,小程序在線客服自動回復功能。

閱讀本文檔之前,最好已經了解過小程序客服信息官方的相關文檔:

這次開發做在線客服功能也踩了不少坑,網上也查閱不少資料,但大部分的后臺都是基于php或者python,java開發,node.js開發的較少,因此將這次開發的流程記錄一下,供大家參考,避免大家踩坑??赡軙幸恍╁e誤地方歡迎指正交流。

另外,我們用的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提示該小程序提供的服務出現故障 請稍后再試。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品日韩欧美大师| 日本精品免费一区二区三区| 国产精品丝袜视频| 2023亚洲男人天堂| 久久成人这里只有精品| www.欧美免费| 亚洲最大福利视频网站| 国产美女精品视频免费观看| 国产精品福利在线观看网址| 久久久久久久久久久免费精品| 中国日韩欧美久久久久久久久| 亚洲精品中文字幕av| 日本久久久a级免费| 亚洲自拍小视频免费观看| 在线观看精品国产视频| 久久精品亚洲94久久精品| 亚洲欧美日韩高清| 亚洲欧美国产另类| 最近2019年日本中文免费字幕| 91日韩在线视频| 久久亚洲综合国产精品99麻豆精品福利| 日韩欧美国产一区二区| 亚洲丝袜av一区| 欧美亚洲第一页| 国产极品jizzhd欧美| 久久精品视频在线播放| 成人综合网网址| 欧洲精品毛片网站| 日韩中文字幕在线视频播放| 亚洲男人天堂视频| 久久免费国产视频| 日韩影视在线观看| 日韩在线视频观看正片免费网站| 少妇av一区二区三区| 欧美日韩国产成人高清视频| 欧美成人精品不卡视频在线观看| 精品国产乱码久久久久久虫虫漫画| 国产成人一区二区| 国产一区av在线| 少妇高潮久久77777| 国产成人一区二区在线| 久久99久久亚洲国产| 最近的2019中文字幕免费一页| 永久555www成人免费| 亚洲精品v天堂中文字幕| 亚洲精品久久久久久久久久久久| 国产精品久久久久久久久久久久久| 国产在线观看91精品一区| 国模视频一区二区| 午夜精品久久久久久久99热浪潮| 国产亚洲欧美日韩精品| 亚洲男人天堂手机在线| 一区国产精品视频| 日韩成人中文电影| 国产精品国产福利国产秒拍| 成人高清视频观看www| 久久激情五月丁香伊人| 91精品国产高清久久久久久| 91精品久久久久久久久| 亚洲欧美999| 久久久久久久久久久久久久久久久久av| 中文字幕成人精品久久不卡| 国产亚洲精品久久久久久| 国产欧美一区二区三区视频| 91亚洲精品在线| 97香蕉超级碰碰久久免费的优势| 成人网在线视频| 亚洲国产精久久久久久久| 国产亚洲精品一区二区| 欧美日韩在线免费观看| 日韩网站免费观看高清| 最近更新的2019中文字幕| 亚洲变态欧美另类捆绑| 日韩女在线观看| 国产精品亚洲美女av网站| 欧美日韩高清区| 456亚洲影院| 狠狠躁夜夜躁人人爽天天天天97| 亚洲欧美另类自拍| 亚洲成人久久久久| 欧美裸体xxxx极品少妇| 国产欧美日韩中文字幕在线| 亚洲人成五月天| 国产精品视频区1| 欧美性猛交xxxx乱大交| 亚洲欧美成人精品| 日本一区二三区好的精华液| 久久成人av网站| 欧美日韩精品国产| 日韩精品视频在线免费观看| 国模精品视频一区二区| 久久五月天色综合| 国产精品亚洲视频在线观看| 日韩美女av在线| 日韩电影免费观看在线| 国产精品一区二区3区| 日本久久久久久久久久久| 欧美成人午夜激情视频| 国产精品亚洲аv天堂网| 日韩中文字幕免费| 中文字幕日韩精品在线| 亚洲精品成人网| 日韩中文在线不卡| 国产丝袜一区视频在线观看| 亚洲夜晚福利在线观看| 美女国内精品自产拍在线播放| 亚洲伊人成综合成人网| 国产精品九九久久久久久久| 97精品久久久中文字幕免费| 国产日韩av高清| 国产91|九色| 国产精品入口夜色视频大尺度| 午夜精品久久久久久久99黑人| 欧美孕妇孕交黑巨大网站| 国产综合在线视频| 国产精品香蕉在线观看| 亚洲色图狂野欧美| 欧美在线视频一区| 欧美亚洲激情在线| 激情成人在线视频| 久久成人在线视频| 国产精品入口夜色视频大尺度| 久久久精品视频成人| 欧美精品在线免费观看| 日本高清不卡的在线| 亚洲精品suv精品一区二区| 疯狂做受xxxx高潮欧美日本| 精品久久久久久久久久ntr影视| 91国语精品自产拍在线观看性色| 久久久久久欧美| 国产精品成人va在线观看| 久久久久久欧美| 亚洲精品国产拍免费91在线| 欧美日韩在线视频一区二区| 欧美成人国产va精品日本一级| 欧美野外wwwxxx| 一区二区福利视频| 亚洲第一二三四五区| 国产精品国产三级国产aⅴ9色| 亚洲人午夜精品免费| 欧美色视频日本版| 国产精品亚洲第一区| 国产精品丝袜久久久久久不卡| 亚洲精品91美女久久久久久久| 狠狠久久亚洲欧美专区| 欧美高清在线视频观看不卡| 少妇av一区二区三区| 国产欧美日韩专区发布| 国产精品免费一区二区三区都可以| 久久久精品在线观看| 国产精品稀缺呦系列在线| 欧美精品videosex性欧美| 91黄色8090| 欧美性猛xxx| 国产成人精品久久久| 亚洲人成五月天| 爱福利视频一区| 日韩av三级在线观看| 91沈先生在线观看| 欧美伊久线香蕉线新在线| 91嫩草在线视频| 国产97色在线|日韩| 91亚洲午夜在线| 亚洲无线码在线一区观看|