背景
最近開發了一個Bot Framework的小工具,能夠通過Luis分析出用戶輸入的文本,對文本中的StyleNo/FabricNo/TrimNo提取出來,並傳入另一個小系統進行查詢出結果,包括文本與圖片,用戶可以通過skype/teams/wechat……gi還有微信,可以與Bot進行交互(現時只是查詢)
關於Bot Framework的開發,開始的時候已經開發了一個C#版本,后來因項目都需要改成Nodejs,我就借這個小項目來熟悉一下Nodejs的開發
關於微信Nodejs開發,前人還是提代了很豐富的NPM庫的,推薦兩個庫wechat(https://www.npmjs.com/package/wechat)和wechat-api(https://www.npmjs.com/package/wechat-api),這兩個庫的配合,能夠幫助我們完成絕大部分的開發要求,
架構
開發
在完成了Bot Framework的開發后,現時的功能能夠使用skype/teams/郵件進行交互,因為現時公司就是使用Office365來辦公的,那么使用skype也是相當方便,這里提一點,skype business這個版本暫時還不支持加入Bot的功能,還需要等待一陣才有可能使用到Bot功能。
因為微信的普及,我們也希望加入微信來對功能進行拓展,所以才有了現在這個微信的開發,現時只是對Bot的功能進行延展,只要求微信能夠使用到這個功能就可以了
微信
var wechat = require('wechat'); var wechatAPI = require('wechat-api'); //wechat config var config = { token: 'weixin', appid: 'wx1434eed5268660c4', encodingAESKey: 'ZEtViedarf49EUOCDeu45pqhkZhKPFBjSHI2DynP4vq', checkSignature: true // 可選,默認為true。由於微信公眾平台接口調試工具在明文模式下不發送簽名,所以如要使用該測試工具,請將其設置為false }; var api = new wechatAPI(config.appid, '30a5f51682755652e6e02879757a0fb1'); app.use('/wechat', wechat(config, wechat.text(function (message, req, res, next) { //------------------------------------------------------------------------ //get message from wechat client var message = req.weixin; logger.log("2.1:get message from wechat client", message); //========================================================================================================= var touserid = message.FromUserName; //send message entity var messageBody = { "type": "message", "from": { "id": message.FromUserName, "FromUserName": 'WeChatUser' }, "text": message.Content }; //send message to botframework sendMessageToBotframework(_tokenObject, messageBody, touserid); //response for wechat client res.reply('message send successfully, waiting for response'); //========================================================================================================= }).image(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); }).voice(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); }).video(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); }).location(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); }).link(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); }).event(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('感謝你的關注,你也可以在github中查看,https://github.com/ChenWes/esquel-LPD-Bot-Node-WeChat'); }).device_text(function (message, req, res, next) { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); }).device_event(function (message, req, res, next) { if (message.Event === 'subscribe' || message.Event === 'unsubscribe') { var message = req.weixin; logger.log("info", message); res.reply("功能開發中"); } else { var message = req.weixin; logger.log("info", message); res.reply('功能開發中'); } })));
Bot framework Direct line
var client = require('./directline-api-v3'); var secret = 'JmQLHOoxqeg.cwA.UqE.ZeXqmfJ5ncjzD9ZcoOe4tvOW7VDhVHZCMjfEEyZsNDo'; var _tokenObject; var _conversationWss; var _watermark = 0; client.getTokenObject(secret).subscribe( (tokenObject) => { _tokenObject = tokenObject; logger.log('1.1:get token', _tokenObject); client.initConversationStream(_tokenObject).subscribe( (message) => { _conversationWss = message; logger.log('1.2:info', _conversationWss); }, (err) => console.log(err), () => console.log("1.2:get conversation successfully") ) //maybe need refresh token here setTimeout(function () { refreshToken() }, (_tokenObject.expires_in - 30) * 1000); }, (err) => console.log(err), () => console.log('1.1:get token successfully') ) //========================================================================================================= function refreshToken() { console.log('------------------------refreshToken-----------------------------') client.refTokenObject(secret).subscribe( (tokenObject) => { _tokenObject = tokenObject; logger.log('1.3:refresh token', _tokenObject); }, (err) => console.log(err), () => console.log('1.3:refresh token successfully') ) } //send message to bot framework function sendMessageToBotframework(_tokenObject, messageBody, touserid) { client.sendMessage(_tokenObject, messageBody).subscribe( (data) => { var sendMessageid = data.id; //time out function get message from botframework setTimeout(function () { getmessagefrombotframework(touserid, _tokenObject, sendMessageid, _watermark) }, 10000); }, (err) => { logger.log('2.2:send message to BotFramework error', err); }, () => { console.log("2.2:send message to bot botframework successfully"); } ); } //get message from bot framework function function getmessagefrombotframework(senduserid, tokenobject, sendmsgid, sendwatermark) { client.getMessage(tokenobject, sendwatermark).subscribe( (result) => { _watermark = result.watermark; //filter activities var getResponseMessages = _.where(result.activities, { replyToId: sendmsgid }); //send message to wechat client sendMessageToClient(senduserid, getResponseMessages); }, (err) => { logger.log('3.1:get message from botframework error', err); }, () => console.log("3.1:get message from botframework successfully") ) } //send to message to wechat client function sendMessageToClient(senduserid, getResponseMessages) { if (getResponseMessages) { //forEach message getResponseMessages.forEach(function (getResponseMessageItem) { //process message from botframework api.sendText(senduserid, getResponseMessageItem.text, function (err, result) { if (err) { logger.log('3.2:reply wechat client (' + senduserid + ') message error', err); } }); //process attachment if (getResponseMessageItem.attachments) { getResponseMessageItem.attachments.forEach(function (getResponseMessageAttachmentItem) { if (getResponseMessageAttachmentItem.contentType == 'application/vnd.microsoft.card.thumbnail' || getResponseMessageAttachmentItem.contentType == 'application/vnd.microsoft.card.hero') //-------------upload media api.uploadMedia(getResponseMessageAttachmentItem.content.images[0].url, 'image', function (err, result) { // console.log('start upload image' + result); if (err) { logger.log('3.4:upload image error', err); } else { //-------------send image api.sendImage(senduserid, result.media_id, function (err, result) { if (err) { logger.log('3.5:send image wechat client (' + senduserid + ') attachment error', err); } }); //------------- } }); //------------- api.sendText(senduserid, getResponseMessageAttachmentItem.content.title + '\r' + getResponseMessageAttachmentItem.content.subtitle + '\r' + getResponseMessageAttachmentItem.content.text, function (err, result) { if (err) { logger.log('3.3:reply wechat client (' + senduserid + ') attachment error', err); } }); }); } }); } }
最后公開一下github代碼:https://github.com/ChenWes/esquel-LPD-Bot-Node-WeChat/tree/dev