UNPKG

recime-bot-runtime

Version:

This runtime is intended to run inside a micro-service container with platform specific integration and module interpreter.

333 lines (309 loc) 14.3 kB
// Copyright 2017 The Recime Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. 'use strict'; const fs = require("fs"); const path = require("path");`` const query = require("querystring"); const HandleBars = require("handlebars"); const DB = require("recime-keyvalue-store").default; const Dialog = require("./dist/dialog").Dialog; const Script = require("./dist/chat-engine/script").Script;`` const BotFramework = require("./dist/bot-framework").BotFramework; const Facebook = require("./dist/facebook").Facebook; const Slack = require("./dist/slack").Slack; const SendBird = require("./dist/sendbird").SendBird; const Telegram = require("./dist/telegram").Telegram; const Twilio = require("./dist/twilio").Twilio; const WeChat = require("./dist/wechat").WeChat; const Viber = require("./dist/viber").Viber; const XML = require('./dist/xml').XML; const SchemaValidator = require('./dist/schema-validator').SchemaValidator; const MsgObject = require("./dist/msg-object").MsgObject; const MessageProcessor = require("./dist/message-processor").MessageProcessor; const WebLogger = require("./dist/logger").WebLogger; const BotModel = require("./dist/bot-model").BotModel; const Broadcast = require('./dist/broadcast').Broadcast; const Message = require('./dist/message').Message; module.exports = (dir)=> { var env = process.env; var host = ""; const handler = function(bot, data, platform, success, error){ const script = new Script(bot); const converter = new MessageProcessor(bot.id, platform); var options = { homedir : dir, uid : bot.id, data : converter.convert(data), env: env, platform : platform, host : host }; script.execute(options).then(success).catch(error); }; const res = (code, body, contentType)=>{ return { "statusCode" : code || 200, "headers": { "Content-Type" : contentType || "application/json", "Access-Control-Allow-Origin": "*" }, "body": body || JSON.stringify({ result: 'alive', timestamp: new Date() }) } }; const html = (body)=>{ return res(200, body, "text/html"); }; const bind = (event, context, callback) => { if (event.httpMethod === 'GET' && (event.path || '').endsWith('/ping')) { return callback(void 0, res()); } const body = MsgObject.parse(event.body || ''); const query = event.queryStringParameters || {}; host = event.host; const platform = 'web'; var params = { uid: (() => { console.log("PATH:", event.path); const parts = event.path.split('/'); for (let i = 1; i < parts.length; i++) { if (parts[i].length === 32) { return parts[i]; } } return void 0; })() || context.functionName, homedir : dir }; if (event.path.match(/\/v1\/broadcast/)) { const model = new BotModel(params.uid); return model.get().then(bot => { const broadcast = new Broadcast(bot); broadcast.send(body).then(result=>{ return callback(void 0, res(200, JSON.stringify(result))); }).catch(err => { console.log(err); callback(void 0, res(200, JSON.stringify(err))); }); }).catch(err =>{ console.log(err); callback(void 0, res(err.code, JSON.stringify(err))); }); } if (event.path.match(/\/v1\/send/)){ const model = new BotModel(params.uid); return model.get().then(bot => { switch(body.platform){ case 'facebook':{ const facebook = new Facebook(bot); return facebook.send({ sender : body.sender, messages : [new Message(body.platform).eval(body.message)], tag : body.tag }); } case 'viber' : { const viber = new Viber(bot); return viber.send({ sender : body.sender, messages : [new Message(body.platform).eval(body.message)] }); } } }).then (()=>{ return callback(void 0, res(200, JSON.stringify({ success : true}))); }) .catch(err =>{ console.log(err); callback(void 0, res(err.code, JSON.stringify(err))); }); } if (event.httpMethod === 'GET') { if (query['hub.mode'] && query['hub.mode'].match(/subscribe/ig)){ const model = new BotModel(params.uid); return model.get().then(bot=>{ const facebook = new Facebook(bot); facebook.verifyToken(query).then((result) => { context.succeed(res(200, result, "text/plain")); }, (err) => { context.succeed(res(403, "")); }); }); } else if (query['signature'] && query['timestamp'] && query['nonce']){ const model = new BotModel(params.uid); return model.get().then(bot => { const wechat = new WeChat(bot); if (wechat.verify(query)){ context.succeed(res(200, query['echostr'], "text/plain")); } else { context.succeed(res(403, "Invalid access token")); } }); }else { if (query["ref"]){ return handler(context.functionName, { sender : query["ref"] }, "web", (result)=>{ return context.succeed(html(result)); }, (err)=>{ return context.succeed(res(500, JSON.stringify(err))); }); } else { // warm up DB.init(params.uid).set('timestamp', Date.now()); Dialog.html({ id: params.uid, dir : __dirname }).then ((result)=>{ context.succeed(html(result)); }, (err)=>{ console.log(err); context.succeed(res(500, "Invalid bot.")); }); } } } else { const model = new BotModel(params.uid); model.get().then ((bot)=>{ // convert xml to json if necessary. XML.ifConvert(body).then((body) => { SchemaValidator.findOne(body).then((platform) => { switch (platform) { case "bot-framework": { const botFramework = new BotFramework(bot); botFramework.execute(body, query, handler).then(body=>{ context.succeed(res(200, JSON.stringify(body))); }, (err)=>{ console.error(err); context.fail(err); }); break; } case "facebook": { const facebook = new Facebook(bot); facebook.execute(body, query, handler).then((body) => { context.succeed(res(200, JSON.stringify(body))); }, (err) => { console.error(err); context.fail(err); }); break; } case "telegram": { const telegram = new Telegram(bot); telegram.execute(body, query, handler).then((body) => { context.succeed(res(200, JSON.stringify(body))); }, (err) => { console.error(err); context.fail(err); }); break; } case "slack": { const slack = new Slack(bot); slack.verifyToken(body).then((result) => { context.succeed(res(200, body.challenge, "text/plain")); }, (err) => { context.succeed(res(403, "")); }); break; } case "slack-command": { context.succeed(res(200, "")); break; } case "slack-event": { const slack = new Slack(bot); slack.execute(body, query, handler).then((body) => { context.succeed(res(200, JSON.stringify(body))); }, (err) => { console.error(err); context.fail(err); }); break; } case "sendbird": { const sendbird = new SendBird(bot); sendbird.execute(body, query, handler).then((body) => { context.succeed(res(200, JSON.stringify(body))); }, (err) => { console.error(err); context.fail(err); }); break; } case "twilio": { const twilio = new Twilio(bot); twilio.execute(body, query, handler).then((body) => { context.succeed(res(200, "<Response/>", "application/xml")); }, (err) => { console.error(err); context.fail(err); }); break; } case "wechat": { const wechat = new WeChat(bot); wechat.execute(body, query, handler).then((body) => { context.succeed(res(200, "", "text/plain")); }, (err) => { console.error(err); context.succeed(res(200, "", "text/plain")); }); // context.succeed(""); break; } case "viber": { if (body.event === "message" || body.event === "conversation_started") { const viber = new Viber(bot); viber.execute(body, query, handler).then((body) => { context.succeed(res(200, JSON.stringify(body))); }, (err) => { context.succeed(res(200, err.message)); }); } else { context.succeed(res(200, JSON.stringify({ success: true }))); } break; } default: { const log = new WebLogger(bot); return handler(bot, body, platform, (result) => { log.outgoing(body, result); return context.succeed(res(200, JSON.stringify(result))); }, (err) => { return context.succeed(res(200, JSON.stringify(err))) }); } } }).catch((err) => { console.error(err); context.fail(err); }); }); }).catch((err)=>{ console.error(err); context.fail(err); }) // bot } }; return { bind : bind }; };