console.log({ query: req.query, params: req.params, body: req.body }); const msgrSettings = settings_667ef98d3ee8930a5debcbdb; const paSettings = proactive_agent_settings; const studioToken = msgrSettings ? { Authorization: `Bearer ${msgrSettings.messenger.token}`, } : {}; let bot_user = { ...paSettings.user, }; const app = { routes: [], route: function (regexp, fn) { this.routes.push({ regexp: new RegExp(regexp), function: fn }); }, run: function (req, res) { const path = req.params[0].split( `/ProxyScript/run/${req.params.workspaceId}/${req.params.branch}/${req.params.route}` )[1] || "/"; for (var route of this.routes) { console.log(`Checking route: ${route.regexp}`); console.log(`Against path: ${path}`); if (route.regexp.test(path)) { console.log(`Matched route: ${route.regexp}`); route.function(req, res, route.regexp.exec(path)); return; } } // If no route matches, return a 404 status const status = { path: req.params[0], status: 404 }; res.status(404).send(status); }, }; const redisKey = (userId) => { return `user-map-${userId}`; }; const axioshelper = (message, config, callback, retries = 3, delay = 100) => { return new Promise(async (resolve, reject) => { for (let i = 0; i < retries; i++) { try { const response = await axios(config); console.log({ response: response }); if (response.status < 200 || response.status > 299) { if (callback) { await callback(); } else { throw new Error( `Axios Request failed! ${JSON.stringify(response)}` ); } } resolve(response); break; } catch (error) { if (error.response) { // The request was made and the server responded with a status code // that falls out of the range of 2xx console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { // The request was made but no response was received // `error.request` is an instance of XMLHttpRequest in the browser and an instance of // http.ClientRequest in node.js console.log(error.request); } else { // Something happened in setting up the request that triggered an Error console.log("Error", error.message); } console.log(error.config); if (i === retries - 1) { if (callback) { await callback(); } console.log({ retry: i + 1, error: "out of retries", message, url: config.url, }); reject(error); } else { console.log({ level: "warn", message: `Attempt ${i + 1} failed.`, url: config.url, }); await new Promise((resolve) => setTimeout(resolve, delay)); } } } }); }; app.route("^(?:/userId/([^/]+))(?:/$)?$", async (req, res, match) => { try { console.log(`Received request for userId: ${match[1]}`); const modelName = req.params?.modelName || proactive_agent_settings.modelName; if (match.length > 1) { const userId = match[1]; const smStr = redisKey(userId); const sessionMap = await redis.hGetAll(smStr); const metadata = { userId: bot_user.userId, }; const recognizedData = await axios .post( `${settings_667ef98d3ee8930a5debcbdb.nlu.apiBaseURL}Model/run/${req.params.workspaceId}/${req.params.branch}/${modelName}`, { input: req.body.input, conversationId: sessionMap.conversationId, settings: settings_667ef98d3ee8930a5debcbdb.nlu.settings, metadata: metadata, } ) .then((response) => { return response.data; }) .catch((error) => { //If we have error handling turned off, don't record the error if (settings_667ef98d3ee8930a5debcbdb.errorHandling === false) { throw error; } else { // Conversation ID is generated by the NLU // Must make sure Conversation ID is created properly for an error transaction // Get it from session map if it exists, or generate it if we got the error at the very first transaction. const conversationId = sessionMap.conversationId || uuidv4(); let errorPayload = { id: uuidv4(), workspaceId: req.params.workspaceId, errorInfo: { name: error.name, message: error.message, stack: error.stack, }, conversationId, input: req.body.input, answers: [settings_667ef98d3ee8930a5debcbdb.responses.modelError], req: { params: req.params, query: req.query, body: req.body, headers: req.headers, }, metadata, classificationResults: [ { label: "Model Error", value: 0.0, }, ], nerResults: { entities: [], sourceEntities: [], }, // Reporting tags to match GlobalSupport function reporting tag: "ERROR", reporting: { tag: "ERROR", modelResponse: "ERROR", }, }; // Add model name errorPayload.req.params.route = modelName; //add any other details you wish to see in transaction data return errorPayload; } }); // console.log(recognizedData); if (recognizedData.conversationId) { await redis.hSet( smStr, "conversationId", recognizedData.conversationId ); await redis.expire(smStr, 3600); if (sessionMap.conversationId) { } else { db.analytics.addConversation({ id: recognizedData.conversationId, }); } } recognizedData._id = ( await db.analytics.addTransaction(recognizedData) ).insertedId; // Send Answers to Messenger new Promise(async (resolve) => { for (const [index, answer] of recognizedData.answers.entries()) { try { await axios.post( `${settings_667ef98d3ee8930a5debcbdb.messenger.apiBaseURL}Event/create`, { conversationId: sessionMap.sessionId, metadata: { channel: "web", }, input: answer, sentBy: bot_user, ping: nanoid(), sentAt: Date.now(), options: recognizedData?.options, metadata: { outputs: recognizedData.answers.length == index + 1 ? recognizedData?.outputs : {}, transactionId: recognizedData._id, feedbackable: false, }, }, { headers: { Authorization: `Bearer ${settings_667ef98d3ee8930a5debcbdb.messenger.token}`, }, } ); } catch (e) {} } resolve(true); }); res.send(recognizedData); } else { res.status(400).send({ error: "Bad Request" }); } } catch (error) { console.error(error); return res.status(500).send({ status: 500, }); } }); app.route("/", async (req, res) => { const sessionId = req.body.event?.conversationId; const metadata = { ...req.body.event?.metadata, userId: req.body.event?.sentBy?.userId, }; try { if (sessionId && metadata.userId) { const umStr = redisKey(metadata.userId); await redis.hSet(umStr, "sessionId", sessionId); await redis.expire(umStr, 3600); await axioshelper("messenger join", { method: "post", url: `${msgrSettings.messenger.apiBaseURL}Conversation/join`, headers: studioToken, data: { _id: sessionId, participant: bot_user, }, }); res.send(); } else { res.send({ error: "sessionId or userId not found on event." }); } } catch (error) { console.log(error); res.send({ answers: ["Something went wrong. Please try again."], outputs: {}, }); } }); app.run(req, res);