Nodejs微信与Bot framework通过Direct Line连接

背景

最近开发了一个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

posted @ 2017-03-03 10:41  WesChan  阅读(2030)  评论(7编辑  收藏  举报