From f4e5c895bee63f539696c1518e2a80124cbcdeaf Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:25:27 +0530 Subject: [PATCH 01/26] fix: broken import --- server/src/workflow-management/scheduler/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index d7a481bf..898eaea9 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -7,7 +7,6 @@ import { createRemoteBrowserForRun, destroyRemoteBrowser } from '../../browser-m import logger from '../../logger'; import { browserPool } from "../../server"; import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "../integrations/gsheet"; -import { getRecordingByFileName } from "../../routes/storage"; import Robot from "../../models/Robot"; import Run from "../../models/Run"; import { getDecryptedProxyConfig } from "../../routes/proxy"; From 757e71680f586a014230c77ede2a816678bcc2fc Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:25:49 +0530 Subject: [PATCH 02/26] chore: remove unused imports --- server/src/workflow-management/scheduler/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index 898eaea9..d8f8dcb0 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -1,8 +1,6 @@ -import fs from "fs"; import { uuid } from "uuidv4"; import { chromium } from "playwright"; import { io, Socket } from "socket.io-client"; -import { readFile, saveFile } from "../storage"; import { createRemoteBrowserForRun, destroyRemoteBrowser } from '../../browser-management/controller'; import logger from '../../logger'; import { browserPool } from "../../server"; From fd3243233415999f2ea8826a45a5247378d51469 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:44:22 +0530 Subject: [PATCH 03/26] refactor: rename runWorkflow to createWorkflowAndStoreMetadata --- server/src/workflow-management/scheduler/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index d8f8dcb0..4741a9ec 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -9,7 +9,7 @@ import Robot from "../../models/Robot"; import Run from "../../models/Run"; import { getDecryptedProxyConfig } from "../../routes/proxy"; -async function runWorkflow(id: string, userId: string) { +async function createWorkflowAndStoreMetadata(id: string, userId: string) { if (!id) { id = uuid(); } @@ -171,7 +171,7 @@ function resetRecordingState(browserId: string, id: string) { export async function handleRunRecording(id: string, userId: string) { try { - const result = await runWorkflow(id, userId); + const result = await createWorkflowAndStoreMetadata(id, userId); const { browserId, runId: newRunId } = result; if (!browserId || !newRunId || !userId) { @@ -201,4 +201,4 @@ function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { logger.log('info', `Cleaned up listeners for browserId: ${browserId}, runId: ${id}`); } -export { runWorkflow }; \ No newline at end of file +export { createWorkflowAndStoreMetadata }; \ No newline at end of file From 821104b4c3d2e58460304ed6f2453e23d4ac5223 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:48:41 +0530 Subject: [PATCH 04/26] feat: createWorkflowAndStoreMetadata for robot access via api --- server/src/api/record.ts | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 9d8dfa29..d5876a11 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -1,9 +1,14 @@ import { readFile, readFiles } from "../workflow-management/storage"; import { Router, Request, Response } from 'express'; +import { chromium } from "playwright"; import { requireAPIKey } from "../middlewares/api"; import Robot from "../models/Robot"; import Run from "../models/Run"; const router = Router(); +import { getDecryptedProxyConfig } from "../routes/proxy"; +import { uuid } from "uuidv4"; +import { createRemoteBrowserForRun, destroyRemoteBrowser } from "../browser-management/controller"; +import logger from "../logger"; const formatRecording = (recordingData: any) => { const recordingMeta = recordingData.recording_meta; @@ -164,4 +169,100 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R } }); +async function createWorkflowAndStoreMetadata(id: string, userId: string) { + if (!id) { + id = uuid(); + } + + const recording = await Robot.findOne({ + where: { + 'recording_meta.id': id + }, + raw: true + }); + + if (!recording || !recording.recording_meta || !recording.recording_meta.id) { + return { + success: false, + error: 'Recording not found' + }; + } + + const proxyConfig = await getDecryptedProxyConfig(userId); + let proxyOptions: any = {}; + + if (proxyConfig.proxy_url) { + proxyOptions = { + server: proxyConfig.proxy_url, + ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { + username: proxyConfig.proxy_username, + password: proxyConfig.proxy_password, + }), + }; + } + + try { + const browserId = createRemoteBrowserForRun({ + browser: chromium, + launchOptions: { + headless: true, + proxy: proxyOptions.server ? proxyOptions : undefined, + } + }); + + const run = await Run.create({ + status: 'Running', + name: recording.recording_meta.name, + robotId: recording.id, + robotMetaId: recording.recording_meta.id, + startedAt: new Date().toLocaleString(), + finishedAt: '', + browserId: id, + interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, + log: '', + runId: id, + serializableOutput: {}, + binaryOutput: {}, + }); + + const plainRun = run.toJSON(); + + return { + browserId, + runId: plainRun.runId, + } + + } catch (e) { + const { message } = e as Error; + logger.log('info', `Error while scheduling a run with id: ${id}`); + console.log(message); + return { + success: false, + error: message, + }; + } + } + + +router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { + try { + + + const response = { + statusCode: 200, + messageCode: "success", + run: '', + }; + + res.status(200).json(response); + } catch (error) { + console.error("Error running robot:", error); + res.status(500).json({ + statusCode: 500, + messageCode: "error", + message: "Failed to run robot", + }); + } +}); + export default router; \ No newline at end of file From 60d948732f03b721bbd8d14050398010cc576605 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:50:32 +0530 Subject: [PATCH 05/26] feat: execute run for robot access via api --- server/src/api/record.ts | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index d5876a11..1a3ab994 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -169,6 +169,60 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R } }); +async function executeRun(id: string) { + try { + const run = await Run.findOne({ where: { runId: id } }); + if (!run) { + return { + success: false, + error: 'Run not found' + } + } + + const plainRun = run.toJSON(); + + const recording = await Robot.findOne({ where: { 'recording_meta.id': plainRun.robotMetaId }, raw: true }); + if (!recording) { + return { + success: false, + error: 'Recording not found' + } + } + + plainRun.status = 'running'; + + const browser = browserPool.getRemoteBrowser(plainRun.browserId); + if (!browser) { + throw new Error('Could not access browser'); + } + + const currentPage = await browser.getCurrentPage(); + if (!currentPage) { + throw new Error('Could not create a new page'); + } + + const interpretationInfo = await browser.interpreter.InterpretRecording( + recording.recording, currentPage, plainRun.interpreterSettings); + + await destroyRemoteBrowser(plainRun.browserId); + + await run.update({ + ...run, + status: 'success', + finishedAt: new Date().toLocaleString(), + browserId: plainRun.browserId, + log: interpretationInfo.log.join('\n'), + serializableOutput: interpretationInfo.serializableOutput, + binaryOutput: interpretationInfo.binaryOutput, + }); + return true; + } catch (error: any) { + logger.log('info', `Error while running a recording with id: ${id} - ${error.message}`); + console.log(error.message); + return false; + } + } + async function createWorkflowAndStoreMetadata(id: string, userId: string) { if (!id) { id = uuid(); From 4c688fd8fb7172b98e386428d56a9b260b9461a5 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:51:03 +0530 Subject: [PATCH 06/26] fix: missing import for browerPool --- server/src/api/record.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 1a3ab994..ac3c06e1 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -9,6 +9,7 @@ import { getDecryptedProxyConfig } from "../routes/proxy"; import { uuid } from "uuidv4"; import { createRemoteBrowserForRun, destroyRemoteBrowser } from "../browser-management/controller"; import logger from "../logger"; +import { browserPool } from "../server"; const formatRecording = (recordingData: any) => { const recordingMeta = recordingData.recording_meta; From 08139606ccf2326d8b78530d66a6c381d18c0355 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:52:26 +0530 Subject: [PATCH 07/26] fix: create a run handler --- server/src/api/record.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index ac3c06e1..192041db 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -170,6 +170,25 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R } }); +async function readyForRunHandler(browserId: string, id: string) { + try { + const interpretation = await executeRun(id); + + if (interpretation) { + logger.log('info', `Interpretation of ${id} succeeded`); + } else { + logger.log('error', `Interpretation of ${id} failed`); + await destroyRemoteBrowser(browserId); + } + + resetRecordingState(browserId, id); + + } catch (error: any) { + logger.error(`Error during readyForRunHandler: ${error.message}`); + await destroyRemoteBrowser(browserId); + } + } + async function executeRun(id: string) { try { const run = await Run.findOne({ where: { runId: id } }); From 30b53aeaba7ecd740b31e08568e5574cfff0af77 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:53:13 +0530 Subject: [PATCH 08/26] feat: reset recording state --- server/src/api/record.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 192041db..23882140 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -189,6 +189,11 @@ async function readyForRunHandler(browserId: string, id: string) { } } + function resetRecordingState(browserId: string, id: string) { + browserId = ''; + id = ''; + } + async function executeRun(id: string) { try { const run = await Run.findOne({ where: { runId: id } }); From b98c6eae2904e5d94b911a438322ad634cf6dfff Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:54:14 +0530 Subject: [PATCH 09/26] feat: handle run recording --- server/src/api/record.ts | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 23882140..485e02b2 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -322,6 +322,38 @@ async function createWorkflowAndStoreMetadata(id: string, userId: string) { } } + export async function handleRunRecording(id: string, userId: string) { + try { + const result = await createWorkflowAndStoreMetadata(id, userId); + const { browserId, runId: newRunId } = result; + + if (!browserId || !newRunId || !userId) { + throw new Error('browserId or runId or userId is undefined'); + } + + const socket = io(`http://localhost:8080/${browserId}`, { + transports: ['websocket'], + rejectUnauthorized: false + }); + + socket.on('ready-for-run', () => readyForRunHandler(browserId, newRunId)); + + logger.log('info', `Running recording: ${id}`); + + socket.on('disconnect', () => { + cleanupSocketListeners(socket, browserId, newRunId); + }); + + } catch (error: any) { + logger.error('Error running recording:', error); + } + } + + function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { + socket.off('ready-for-run', () => readyForRunHandler(browserId, id)); + logger.log('info', `Cleaned up listeners for browserId: ${browserId}, runId: ${id}`); + } + router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { From 4981a515a71b29ba288ec89f1839660298b10079 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:55:00 +0530 Subject: [PATCH 10/26] fix: missing imports for socket --- server/src/api/record.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 485e02b2..1516e7ec 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -10,6 +10,7 @@ import { uuid } from "uuidv4"; import { createRemoteBrowserForRun, destroyRemoteBrowser } from "../browser-management/controller"; import logger from "../logger"; import { browserPool } from "../server"; +import { io, Socket } from "socket.io-client"; const formatRecording = (recordingData: any) => { const recordingMeta = recordingData.recording_meta; From 41947b8542f1e4f5e8a9d012b319ab7827c10116 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 15:55:43 +0530 Subject: [PATCH 11/26] chore: lint --- server/src/api/record.ts | 318 +++++++++++++++++++-------------------- 1 file changed, 159 insertions(+), 159 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 1516e7ec..11ff0417 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -153,7 +153,7 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R }, raw: true }); - + const response = { statusCode: 200, messageCode: "success", @@ -173,192 +173,192 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R async function readyForRunHandler(browserId: string, id: string) { try { - const interpretation = await executeRun(id); - - if (interpretation) { - logger.log('info', `Interpretation of ${id} succeeded`); - } else { - logger.log('error', `Interpretation of ${id} failed`); - await destroyRemoteBrowser(browserId); - } - - resetRecordingState(browserId, id); - - } catch (error: any) { - logger.error(`Error during readyForRunHandler: ${error.message}`); - await destroyRemoteBrowser(browserId); - } - } + const interpretation = await executeRun(id); - function resetRecordingState(browserId: string, id: string) { + if (interpretation) { + logger.log('info', `Interpretation of ${id} succeeded`); + } else { + logger.log('error', `Interpretation of ${id} failed`); + await destroyRemoteBrowser(browserId); + } + + resetRecordingState(browserId, id); + + } catch (error: any) { + logger.error(`Error during readyForRunHandler: ${error.message}`); + await destroyRemoteBrowser(browserId); + } +} + +function resetRecordingState(browserId: string, id: string) { browserId = ''; id = ''; - } +} async function executeRun(id: string) { try { - const run = await Run.findOne({ where: { runId: id } }); - if (!run) { - return { - success: false, - error: 'Run not found' + const run = await Run.findOne({ where: { runId: id } }); + if (!run) { + return { + success: false, + error: 'Run not found' + } } - } - - const plainRun = run.toJSON(); - - const recording = await Robot.findOne({ where: { 'recording_meta.id': plainRun.robotMetaId }, raw: true }); - if (!recording) { - return { - success: false, - error: 'Recording not found' + + const plainRun = run.toJSON(); + + const recording = await Robot.findOne({ where: { 'recording_meta.id': plainRun.robotMetaId }, raw: true }); + if (!recording) { + return { + success: false, + error: 'Recording not found' + } } - } - - plainRun.status = 'running'; - - const browser = browserPool.getRemoteBrowser(plainRun.browserId); - if (!browser) { - throw new Error('Could not access browser'); - } - - const currentPage = await browser.getCurrentPage(); - if (!currentPage) { - throw new Error('Could not create a new page'); - } - - const interpretationInfo = await browser.interpreter.InterpretRecording( - recording.recording, currentPage, plainRun.interpreterSettings); - - await destroyRemoteBrowser(plainRun.browserId); - - await run.update({ - ...run, - status: 'success', - finishedAt: new Date().toLocaleString(), - browserId: plainRun.browserId, - log: interpretationInfo.log.join('\n'), - serializableOutput: interpretationInfo.serializableOutput, - binaryOutput: interpretationInfo.binaryOutput, - }); - return true; + + plainRun.status = 'running'; + + const browser = browserPool.getRemoteBrowser(plainRun.browserId); + if (!browser) { + throw new Error('Could not access browser'); + } + + const currentPage = await browser.getCurrentPage(); + if (!currentPage) { + throw new Error('Could not create a new page'); + } + + const interpretationInfo = await browser.interpreter.InterpretRecording( + recording.recording, currentPage, plainRun.interpreterSettings); + + await destroyRemoteBrowser(plainRun.browserId); + + await run.update({ + ...run, + status: 'success', + finishedAt: new Date().toLocaleString(), + browserId: plainRun.browserId, + log: interpretationInfo.log.join('\n'), + serializableOutput: interpretationInfo.serializableOutput, + binaryOutput: interpretationInfo.binaryOutput, + }); + return true; } catch (error: any) { - logger.log('info', `Error while running a recording with id: ${id} - ${error.message}`); - console.log(error.message); - return false; + logger.log('info', `Error while running a recording with id: ${id} - ${error.message}`); + console.log(error.message); + return false; } - } +} async function createWorkflowAndStoreMetadata(id: string, userId: string) { if (!id) { - id = uuid(); + id = uuid(); } - + const recording = await Robot.findOne({ - where: { - 'recording_meta.id': id - }, - raw: true + where: { + 'recording_meta.id': id + }, + raw: true }); - + if (!recording || !recording.recording_meta || !recording.recording_meta.id) { - return { - success: false, - error: 'Recording not found' - }; + return { + success: false, + error: 'Recording not found' + }; } - + const proxyConfig = await getDecryptedProxyConfig(userId); let proxyOptions: any = {}; - - if (proxyConfig.proxy_url) { - proxyOptions = { - server: proxyConfig.proxy_url, - ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { - username: proxyConfig.proxy_username, - password: proxyConfig.proxy_password, - }), - }; - } - - try { - const browserId = createRemoteBrowserForRun({ - browser: chromium, - launchOptions: { - headless: true, - proxy: proxyOptions.server ? proxyOptions : undefined, - } - }); - - const run = await Run.create({ - status: 'Running', - name: recording.recording_meta.name, - robotId: recording.id, - robotMetaId: recording.recording_meta.id, - startedAt: new Date().toLocaleString(), - finishedAt: '', - browserId: id, - interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, - log: '', - runId: id, - serializableOutput: {}, - binaryOutput: {}, - }); - - const plainRun = run.toJSON(); - - return { - browserId, - runId: plainRun.runId, - } - - } catch (e) { - const { message } = e as Error; - logger.log('info', `Error while scheduling a run with id: ${id}`); - console.log(message); - return { - success: false, - error: message, - }; - } - } - export async function handleRunRecording(id: string, userId: string) { - try { - const result = await createWorkflowAndStoreMetadata(id, userId); - const { browserId, runId: newRunId } = result; - - if (!browserId || !newRunId || !userId) { - throw new Error('browserId or runId or userId is undefined'); - } - - const socket = io(`http://localhost:8080/${browserId}`, { - transports: ['websocket'], - rejectUnauthorized: false - }); - - socket.on('ready-for-run', () => readyForRunHandler(browserId, newRunId)); - - logger.log('info', `Running recording: ${id}`); - - socket.on('disconnect', () => { - cleanupSocketListeners(socket, browserId, newRunId); - }); - - } catch (error: any) { - logger.error('Error running recording:', error); + if (proxyConfig.proxy_url) { + proxyOptions = { + server: proxyConfig.proxy_url, + ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { + username: proxyConfig.proxy_username, + password: proxyConfig.proxy_password, + }), + }; } - } - - function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { + + try { + const browserId = createRemoteBrowserForRun({ + browser: chromium, + launchOptions: { + headless: true, + proxy: proxyOptions.server ? proxyOptions : undefined, + } + }); + + const run = await Run.create({ + status: 'Running', + name: recording.recording_meta.name, + robotId: recording.id, + robotMetaId: recording.recording_meta.id, + startedAt: new Date().toLocaleString(), + finishedAt: '', + browserId: id, + interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, + log: '', + runId: id, + serializableOutput: {}, + binaryOutput: {}, + }); + + const plainRun = run.toJSON(); + + return { + browserId, + runId: plainRun.runId, + } + + } catch (e) { + const { message } = e as Error; + logger.log('info', `Error while scheduling a run with id: ${id}`); + console.log(message); + return { + success: false, + error: message, + }; + } +} + +export async function handleRunRecording(id: string, userId: string) { + try { + const result = await createWorkflowAndStoreMetadata(id, userId); + const { browserId, runId: newRunId } = result; + + if (!browserId || !newRunId || !userId) { + throw new Error('browserId or runId or userId is undefined'); + } + + const socket = io(`http://localhost:8080/${browserId}`, { + transports: ['websocket'], + rejectUnauthorized: false + }); + + socket.on('ready-for-run', () => readyForRunHandler(browserId, newRunId)); + + logger.log('info', `Running recording: ${id}`); + + socket.on('disconnect', () => { + cleanupSocketListeners(socket, browserId, newRunId); + }); + + } catch (error: any) { + logger.error('Error running recording:', error); + } +} + +function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { socket.off('ready-for-run', () => readyForRunHandler(browserId, id)); logger.log('info', `Cleaned up listeners for browserId: ${browserId}, runId: ${id}`); - } +} router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { - + const response = { statusCode: 200, From 66add9c0c1c46199e333a09d943caa253befcedd Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 16:33:04 +0530 Subject: [PATCH 12/26] feat: send run --- server/src/api/record.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 11ff0417..065a7128 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -358,12 +358,12 @@ function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { - + const result = await handleRunRecording(req.params.id, req.body.userId); const response = { statusCode: 200, messageCode: "success", - run: '', + run: result, }; res.status(200).json(response); From f01117471a807e32c1f7f52ddadf82da5121fbf7 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 16:33:47 +0530 Subject: [PATCH 13/26] fix: get user id from req.user.id --- server/src/api/record.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 065a7128..a9241361 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -358,7 +358,7 @@ function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { - const result = await handleRunRecording(req.params.id, req.body.userId); + const result = await handleRunRecording(req.params.id, req.user.id); const response = { statusCode: 200, From c080ee7786c197b726453b57a98a36626483f166 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 21:09:07 +0530 Subject: [PATCH 14/26] feat: use req.user.dataValues.id to get current user --- server/src/api/record.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index a9241361..b32b8415 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -358,7 +358,8 @@ function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { - const result = await handleRunRecording(req.params.id, req.user.id); + const result = await handleRunRecording(req.params.id, req.user.dataValues.id); + console.log(`Result`, result); const response = { statusCode: 200, From 53b687b22cbff6cacefcc3d2f004a36ac3f89115 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 21:12:35 +0530 Subject: [PATCH 15/26] refactor: rearrange fxns --- server/src/api/record.ts | 148 +++++++++++++++++++-------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index b32b8415..b4df4bf2 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -171,6 +171,80 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R } }); +async function createWorkflowAndStoreMetadata(id: string, userId: string) { + if (!id) { + id = uuid(); + } + + const recording = await Robot.findOne({ + where: { + 'recording_meta.id': id + }, + raw: true + }); + + if (!recording || !recording.recording_meta || !recording.recording_meta.id) { + return { + success: false, + error: 'Recording not found' + }; + } + + const proxyConfig = await getDecryptedProxyConfig(userId); + let proxyOptions: any = {}; + + if (proxyConfig.proxy_url) { + proxyOptions = { + server: proxyConfig.proxy_url, + ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { + username: proxyConfig.proxy_username, + password: proxyConfig.proxy_password, + }), + }; + } + + try { + const browserId = createRemoteBrowserForRun({ + browser: chromium, + launchOptions: { + headless: true, + proxy: proxyOptions.server ? proxyOptions : undefined, + } + }); + + const run = await Run.create({ + status: 'Running', + name: recording.recording_meta.name, + robotId: recording.id, + robotMetaId: recording.recording_meta.id, + startedAt: new Date().toLocaleString(), + finishedAt: '', + browserId: id, + interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, + log: '', + runId: id, + serializableOutput: {}, + binaryOutput: {}, + }); + + const plainRun = run.toJSON(); + + return { + browserId, + runId: plainRun.runId, + } + + } catch (e) { + const { message } = e as Error; + logger.log('info', `Error while scheduling a run with id: ${id}`); + console.log(message); + return { + success: false, + error: message, + }; + } +} + async function readyForRunHandler(browserId: string, id: string) { try { const interpretation = await executeRun(id); @@ -249,80 +323,6 @@ async function executeRun(id: string) { } } -async function createWorkflowAndStoreMetadata(id: string, userId: string) { - if (!id) { - id = uuid(); - } - - const recording = await Robot.findOne({ - where: { - 'recording_meta.id': id - }, - raw: true - }); - - if (!recording || !recording.recording_meta || !recording.recording_meta.id) { - return { - success: false, - error: 'Recording not found' - }; - } - - const proxyConfig = await getDecryptedProxyConfig(userId); - let proxyOptions: any = {}; - - if (proxyConfig.proxy_url) { - proxyOptions = { - server: proxyConfig.proxy_url, - ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { - username: proxyConfig.proxy_username, - password: proxyConfig.proxy_password, - }), - }; - } - - try { - const browserId = createRemoteBrowserForRun({ - browser: chromium, - launchOptions: { - headless: true, - proxy: proxyOptions.server ? proxyOptions : undefined, - } - }); - - const run = await Run.create({ - status: 'Running', - name: recording.recording_meta.name, - robotId: recording.id, - robotMetaId: recording.recording_meta.id, - startedAt: new Date().toLocaleString(), - finishedAt: '', - browserId: id, - interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, - log: '', - runId: id, - serializableOutput: {}, - binaryOutput: {}, - }); - - const plainRun = run.toJSON(); - - return { - browserId, - runId: plainRun.runId, - } - - } catch (e) { - const { message } = e as Error; - logger.log('info', `Error while scheduling a run with id: ${id}`); - console.log(message); - return { - success: false, - error: message, - }; - } -} - export async function handleRunRecording(id: string, userId: string) { try { const result = await createWorkflowAndStoreMetadata(id, userId); From 669a12bf50e6c9b492448627cf718aac4e3112f4 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 21:38:50 +0530 Subject: [PATCH 16/26] fix: create runId --- server/src/api/record.ts | 146 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 74 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index b4df4bf2..a463ca31 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -171,80 +171,6 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R } }); -async function createWorkflowAndStoreMetadata(id: string, userId: string) { - if (!id) { - id = uuid(); - } - - const recording = await Robot.findOne({ - where: { - 'recording_meta.id': id - }, - raw: true - }); - - if (!recording || !recording.recording_meta || !recording.recording_meta.id) { - return { - success: false, - error: 'Recording not found' - }; - } - - const proxyConfig = await getDecryptedProxyConfig(userId); - let proxyOptions: any = {}; - - if (proxyConfig.proxy_url) { - proxyOptions = { - server: proxyConfig.proxy_url, - ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { - username: proxyConfig.proxy_username, - password: proxyConfig.proxy_password, - }), - }; - } - - try { - const browserId = createRemoteBrowserForRun({ - browser: chromium, - launchOptions: { - headless: true, - proxy: proxyOptions.server ? proxyOptions : undefined, - } - }); - - const run = await Run.create({ - status: 'Running', - name: recording.recording_meta.name, - robotId: recording.id, - robotMetaId: recording.recording_meta.id, - startedAt: new Date().toLocaleString(), - finishedAt: '', - browserId: id, - interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, - log: '', - runId: id, - serializableOutput: {}, - binaryOutput: {}, - }); - - const plainRun = run.toJSON(); - - return { - browserId, - runId: plainRun.runId, - } - - } catch (e) { - const { message } = e as Error; - logger.log('info', `Error while scheduling a run with id: ${id}`); - console.log(message); - return { - success: false, - error: message, - }; - } -} - async function readyForRunHandler(browserId: string, id: string) { try { const interpretation = await executeRun(id); @@ -323,6 +249,78 @@ async function executeRun(id: string) { } } +async function createWorkflowAndStoreMetadata(id: string, userId: string) { + const recording = await Robot.findOne({ + where: { + 'recording_meta.id': id + }, + raw: true + }); + + if (!recording || !recording.recording_meta || !recording.recording_meta.id) { + return { + success: false, + error: 'Recording not found' + }; + } + + const proxyConfig = await getDecryptedProxyConfig(userId); + let proxyOptions: any = {}; + + if (proxyConfig.proxy_url) { + proxyOptions = { + server: proxyConfig.proxy_url, + ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { + username: proxyConfig.proxy_username, + password: proxyConfig.proxy_password, + }), + }; + } + + try { + const browserId = createRemoteBrowserForRun({ + browser: chromium, + launchOptions: { + headless: true, + proxy: proxyOptions.server ? proxyOptions : undefined, + } + }); + + const runId = uuid(); + + const run = await Run.create({ + status: 'Running', + name: recording.recording_meta.name, + robotId: recording.id, + robotMetaId: recording.recording_meta.id, + startedAt: new Date().toLocaleString(), + finishedAt: '', + browserId: id, + interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, + log: '', + runId, + serializableOutput: {}, + binaryOutput: {}, + }); + + const plainRun = run.toJSON(); + + return { + browserId, + runId: plainRun.runId, + } + + } catch (e) { + const { message } = e as Error; + logger.log('info', `Error while scheduling a run with id: ${id}`); + console.log(message); + return { + success: false, + error: message, + }; + } +} + export async function handleRunRecording(id: string, userId: string) { try { const result = await createWorkflowAndStoreMetadata(id, userId); From a1119769597a50315657437677e636adcc0376b7 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 21:55:46 +0530 Subject: [PATCH 17/26] feat: pass browserId, remove try catch block --- server/src/api/record.ts | 144 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index a463ca31..e1c2dcc1 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -171,6 +171,78 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R } }); +async function createWorkflowAndStoreMetadata(id: string, userId: string) { + try { + const recording = await Robot.findOne({ + where: { + 'recording_meta.id': id + }, + raw: true + }); + + if (!recording || !recording.recording_meta || !recording.recording_meta.id) { + return { + success: false, + error: 'Recording not found' + }; + } + + const proxyConfig = await getDecryptedProxyConfig(userId); + let proxyOptions: any = {}; + + if (proxyConfig.proxy_url) { + proxyOptions = { + server: proxyConfig.proxy_url, + ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { + username: proxyConfig.proxy_username, + password: proxyConfig.proxy_password, + }), + }; + } + + const browserId = createRemoteBrowserForRun({ + browser: chromium, + launchOptions: { + headless: true, + proxy: proxyOptions.server ? proxyOptions : undefined, + } + }); + + const runId = uuid(); + + const run = await Run.create({ + status: 'Running', + name: recording.recording_meta.name, + robotId: recording.id, + robotMetaId: recording.recording_meta.id, + startedAt: new Date().toLocaleString(), + finishedAt: '', + browserId, + interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, + log: '', + runId, + serializableOutput: {}, + binaryOutput: {}, + }); + + const plainRun = run.toJSON(); + + return { + browserId, + runId: plainRun.runId, + } + + } catch (e) { + const { message } = e as Error; + logger.log('info', `Error while scheduling a run with id: ${id}`); + console.log(message); + return { + success: false, + error: message, + }; + } +} + async function readyForRunHandler(browserId: string, id: string) { try { const interpretation = await executeRun(id); @@ -249,78 +321,6 @@ async function executeRun(id: string) { } } -async function createWorkflowAndStoreMetadata(id: string, userId: string) { - const recording = await Robot.findOne({ - where: { - 'recording_meta.id': id - }, - raw: true - }); - - if (!recording || !recording.recording_meta || !recording.recording_meta.id) { - return { - success: false, - error: 'Recording not found' - }; - } - - const proxyConfig = await getDecryptedProxyConfig(userId); - let proxyOptions: any = {}; - - if (proxyConfig.proxy_url) { - proxyOptions = { - server: proxyConfig.proxy_url, - ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { - username: proxyConfig.proxy_username, - password: proxyConfig.proxy_password, - }), - }; - } - - try { - const browserId = createRemoteBrowserForRun({ - browser: chromium, - launchOptions: { - headless: true, - proxy: proxyOptions.server ? proxyOptions : undefined, - } - }); - - const runId = uuid(); - - const run = await Run.create({ - status: 'Running', - name: recording.recording_meta.name, - robotId: recording.id, - robotMetaId: recording.recording_meta.id, - startedAt: new Date().toLocaleString(), - finishedAt: '', - browserId: id, - interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, - log: '', - runId, - serializableOutput: {}, - binaryOutput: {}, - }); - - const plainRun = run.toJSON(); - - return { - browserId, - runId: plainRun.runId, - } - - } catch (e) { - const { message } = e as Error; - logger.log('info', `Error while scheduling a run with id: ${id}`); - console.log(message); - return { - success: false, - error: message, - }; - } -} - export async function handleRunRecording(id: string, userId: string) { try { const result = await createWorkflowAndStoreMetadata(id, userId); From 88d9a927b6d0b823db24d9c1403aa642f3c32367 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:11:02 +0530 Subject: [PATCH 18/26] feat: return interpretationInfo from executeResult --- server/src/api/record.ts | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index e1c2dcc1..578760a6 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -274,7 +274,7 @@ async function executeRun(id: string) { return { success: false, error: 'Run not found' - } + }; } const plainRun = run.toJSON(); @@ -284,7 +284,7 @@ async function executeRun(id: string) { return { success: false, error: 'Recording not found' - } + }; } plainRun.status = 'running'; @@ -300,7 +300,8 @@ async function executeRun(id: string) { } const interpretationInfo = await browser.interpreter.InterpretRecording( - recording.recording, currentPage, plainRun.interpreterSettings); + recording.recording, currentPage, plainRun.interpreterSettings + ); await destroyRemoteBrowser(plainRun.browserId); @@ -313,11 +314,18 @@ async function executeRun(id: string) { serializableOutput: interpretationInfo.serializableOutput, binaryOutput: interpretationInfo.binaryOutput, }); - return true; + + return { + success: true, + interpretationInfo, + }; + } catch (error: any) { logger.log('info', `Error while running a recording with id: ${id} - ${error.message}`); - console.log(error.message); - return false; + return { + success: false, + error: error.message, + }; } } From 940d04e5b2eb59ced937e6bc6a4fb204a9f86267 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:12:15 +0530 Subject: [PATCH 19/26] feat: return result.interpretationInfo from executeRun --- server/src/api/record.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 578760a6..4fd4f2bd 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -245,23 +245,25 @@ async function createWorkflowAndStoreMetadata(id: string, userId: string) { async function readyForRunHandler(browserId: string, id: string) { try { - const interpretation = await executeRun(id); + const result = await executeRun(id); - if (interpretation) { + if (result && result.success) { logger.log('info', `Interpretation of ${id} succeeded`); + return result.interpretationInfo; } else { logger.log('error', `Interpretation of ${id} failed`); await destroyRemoteBrowser(browserId); + return null; } - resetRecordingState(browserId, id); - } catch (error: any) { logger.error(`Error during readyForRunHandler: ${error.message}`); await destroyRemoteBrowser(browserId); + return null; } } + function resetRecordingState(browserId: string, id: string) { browserId = ''; id = ''; From 46ce8645b9025a03303faf1eabd7ab6703084b3a Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:14:33 +0530 Subject: [PATCH 20/26] feat: get result --- server/src/api/record.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 4fd4f2bd..aaa34afa 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -366,13 +366,13 @@ function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { - const result = await handleRunRecording(req.params.id, req.user.dataValues.id); - console.log(`Result`, result); + const interpretationInfo = await handleRunRecording(req.params.id, req.user.dataValues.id); + console.log(`Result`, interpretationInfo); const response = { statusCode: 200, messageCode: "success", - run: result, + run: interpretationInfo, }; res.status(200).json(response); @@ -386,4 +386,5 @@ router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Respons } }); + export default router; \ No newline at end of file From 1f36dec81a3bc70a1da6ffc1c96daf4423fbab1a Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:16:23 +0530 Subject: [PATCH 21/26] feat: send entire run --- server/src/api/record.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index aaa34afa..c38c8ae4 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -307,7 +307,7 @@ async function executeRun(id: string) { await destroyRemoteBrowser(plainRun.browserId); - await run.update({ + const updatedRun = await run.update({ ...run, status: 'success', finishedAt: new Date().toLocaleString(), @@ -319,7 +319,7 @@ async function executeRun(id: string) { return { success: true, - interpretationInfo, + interpretationInfo: updatedRun.toJSON() }; } catch (error: any) { From 363a396c86acd72b6179b155cac6bc74ecf99c09 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:18:29 +0530 Subject: [PATCH 22/26] feat: reset recording state --- server/src/api/record.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index c38c8ae4..9db77a8c 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -256,6 +256,8 @@ async function readyForRunHandler(browserId: string, id: string) { return null; } + resetRecordingState(browserId, id); + } catch (error: any) { logger.error(`Error during readyForRunHandler: ${error.message}`); await destroyRemoteBrowser(browserId); From deaaa7d85cc48fdd76b6c377050de45cdb2f342b Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:19:38 +0530 Subject: [PATCH 23/26] feat: reset recording state --- server/src/api/record.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 9db77a8c..b260d042 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -249,15 +249,15 @@ async function readyForRunHandler(browserId: string, id: string) { if (result && result.success) { logger.log('info', `Interpretation of ${id} succeeded`); + resetRecordingState(browserId, id); return result.interpretationInfo; } else { logger.log('error', `Interpretation of ${id} failed`); await destroyRemoteBrowser(browserId); + resetRecordingState(browserId, id); return null; } - resetRecordingState(browserId, id); - } catch (error: any) { logger.error(`Error during readyForRunHandler: ${error.message}`); await destroyRemoteBrowser(browserId); From fe0c3a678aa98a101257da80c8e8f191d61ef461 Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:20:06 +0530 Subject: [PATCH 24/26] chore: lint --- server/src/api/record.ts | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index b260d042..a86a3e83 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -173,32 +173,32 @@ router.get("/robots/:id/runs/:runId", requireAPIKey, async (req: Request, res: R async function createWorkflowAndStoreMetadata(id: string, userId: string) { try { - const recording = await Robot.findOne({ - where: { - 'recording_meta.id': id - }, - raw: true - }); + const recording = await Robot.findOne({ + where: { + 'recording_meta.id': id + }, + raw: true + }); - if (!recording || !recording.recording_meta || !recording.recording_meta.id) { - return { - success: false, - error: 'Recording not found' - }; - } + if (!recording || !recording.recording_meta || !recording.recording_meta.id) { + return { + success: false, + error: 'Recording not found' + }; + } - const proxyConfig = await getDecryptedProxyConfig(userId); - let proxyOptions: any = {}; + const proxyConfig = await getDecryptedProxyConfig(userId); + let proxyOptions: any = {}; - if (proxyConfig.proxy_url) { - proxyOptions = { - server: proxyConfig.proxy_url, - ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { - username: proxyConfig.proxy_username, - password: proxyConfig.proxy_password, - }), - }; - } + if (proxyConfig.proxy_url) { + proxyOptions = { + server: proxyConfig.proxy_url, + ...(proxyConfig.proxy_username && proxyConfig.proxy_password && { + username: proxyConfig.proxy_username, + password: proxyConfig.proxy_password, + }), + }; + } const browserId = createRemoteBrowserForRun({ browser: chromium, @@ -374,7 +374,7 @@ router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Respons const response = { statusCode: 200, messageCode: "success", - run: interpretationInfo, + run: interpretationInfo, }; res.status(200).json(response); From fe918625c024b200cc1013ef8789ebde3429265b Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:43:10 +0530 Subject: [PATCH 25/26] feat: poll only if status success --- server/src/api/record.ts | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index a86a3e83..cd1ad805 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -355,6 +355,9 @@ export async function handleRunRecording(id: string, userId: string) { cleanupSocketListeners(socket, browserId, newRunId); }); + // Return the runId immediately, so the client knows the run is started + return newRunId; + } catch (error: any) { logger.error('Error running recording:', error); } @@ -365,16 +368,39 @@ function cleanupSocketListeners(socket: Socket, browserId: string, id: string) { logger.log('info', `Cleaned up listeners for browserId: ${browserId}, runId: ${id}`); } +async function waitForRunCompletion(runId: string, interval: number = 2000) { + while (true) { + const run = await Run.findOne({ where: { runId }, raw: true }); + if (!run) throw new Error('Run not found'); + + if (run.status === 'success') { + return run; + } else if (run.status === 'error') { + throw new Error('Run failed'); + } + + // Wait for the next polling interval + await new Promise(resolve => setTimeout(resolve, interval)); + } +} + + + router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { - const interpretationInfo = await handleRunRecording(req.params.id, req.user.dataValues.id); - console.log(`Result`, interpretationInfo); + const runId = await handleRunRecording(req.params.id, req.user.dataValues.id); + console.log(`Result`, runId); + + if (!runId) { + throw new Error('Run ID is undefined'); + } + const completedRun = await waitForRunCompletion(runId); const response = { statusCode: 200, messageCode: "success", - run: interpretationInfo, + run: completedRun, }; res.status(200).json(response); From 946c237755e8929b63143d2d217604e100b75bcd Mon Sep 17 00:00:00 2001 From: karishmas6 Date: Sat, 12 Oct 2024 22:43:43 +0530 Subject: [PATCH 26/26] chore: prettier --- server/src/api/record.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/src/api/record.ts b/server/src/api/record.ts index cd1ad805..5b2e8451 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -384,9 +384,6 @@ async function waitForRunCompletion(runId: string, interval: number = 2000) { } } - - - router.post("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { const runId = await handleRunRecording(req.params.id, req.user.dataValues.id);