leoo's notebooks

  • worktalk - /leoo/worktalk2.runkit.sh
    Last edited 6 years ago
    module.exports.endpoint = function(req, res) { var unirest = require('unirest'); var express = require('express'); var bodyParser = require('body-parser'); var app = express(); app.use(bodyParser.json()); var cookieJar = unirest.jar(); // First, we set up the information we need for the API. // NOTE: to test staging, change API_BASE to 'api.yadkrow.com' const API_BASE = 'api.workday.com'; const TALK_API_BASE = `https://${API_BASE}/tlkw/rest/`; // TODO: updated tenant alias, client ID and secret from octopaas const TENANT_ALIAS = 'devsuvgms31'; const CLIENT_ID = 'ODNhZmVmMTAtOTU5Yi00ZmMyLTgwYmEtOTg0NTcxNTA2MDQ0'; const CLIENT_SECRET = 'exft8x3stl5vbtvvrfmug4t446652xbxqq847qpk6178d9zs598kjn1g3z35kdh4rnmkwjir47hgrvtz212fnstrzgaeocunfqc'; // Pull the tenant out of the command line arguments const args = process.argv.slice(2); const tenant = args[0]; // Wire up the webhook callback through Express.js // This sets up a listener that will respond any time a POST request is made to /conversations/[id] app.post('/conversations/:conversationId', async function(req, res) { console.log('Got a POST request for conversation ' + req.params.conversationId); console.dir(req.body); try { const jwt = await getAuthJwt(TENANT_ALIAS, CLIENT_ID, CLIENT_SECRET); const response = await postMessage(jwt, req.params.conversationId, nextMessageForConversation(req.params.conversationId)); res.send(null); } catch (e) { res.status(500).send('Error sending chat message: ' + e); } }); app.listen(3000, function() { console.log('Worktalk bot listening on port 3000!'); }); // API related methods: // this method authenticates with the api. It uses the client ID and secret to obtain // a jwt token that can be used with the talk API async function getAuthJwt(tenantAlias, clientId, clientSecret) { // Construct the credentials needed to authenticate with the API. const base64Auth = new Buffer(`${clientId}:${clientSecret}`).toString('base64'); const headers = { Authorization: `Basic ${base64Auth}`, 'Content-Type': 'application/x-www-form-urlencoded' }; return new Promise((resolve, reject) => { unirest .post(`https://auth.${API_BASE}/v1/token`) .headers(headers) .send(`tenant_alias=${tenantAlias}`) .send(`grant_type=client_credentials`) .end(function(response) { if (response.statusCode == 200 && response.body.hasOwnProperty('access_token')) { resolve(response.body.access_token); } else { reject('Unable to validate JWT: ' + JSON.stringify(response.statusCode) + ' ' + JSON.stringify(response.body)); } }); }); } // This method posts a message to the Talk server. It takes a conversationId and a message (reply) body, // and uses the credentials we set up above in 'headers' to POST the message function postMessage(jwt, conversationId, replyBody) { // Construct the credentials needed to interact with the API. // These are passed as HTTP headers. const headers = { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' }; const postPath = `${TALK_API_BASE}conversations/${tenant}/${conversationId}/chatMessages`; const postBody = { text: replyBody }; console.log('Posting message to:', postPath); return new Promise((resolve, reject) => { unirest .post(postPath) .jar(cookieJar) .headers(headers) .send(postBody) .end(function(response) { if (response.clientError || response.serverError) { console.log('Could not create Bot response! ' + JSON.stringify(response.raw_body)); reject( 'Error posting messages, clientError: ' + JSON.stringify(response.clientError) + ' ServerError:' + JSON.stringify(response.raw_body) ); } else { console.log('Chat message successfully posted to conversation'); resolve(); } }); }); } // Message related methods: // Set up a Map to store which message index we need to send next in a given conversation. var conversationMessageIndexes = new Map(); // Try to Load the conversation messages from the 'messages.json' file. If the file can't be // found, use a default value var conversationMessages = ['static', 'data', 'from', 'code']; try { conversationMessages = require('./messages.json'); } catch (e) { console.log('Unable to read messages.json, using default values'); } // This method takes a conversationId and returns the next message for that conversation. // It checks what message we're at in the conversation, then pulls the correct message out of conversationMessages and returns it. function nextMessageForConversation(conversationId) { let currentIndex = conversationMessageIndexes.get(conversationId) || 0; const currentMessage = conversationMessages[currentIndex]; currentIndex = (currentIndex + 1) % conversationMessages.length; conversationMessageIndexes.set(conversationId, currentIndex); return currentMessage; } }