feat: add integrations, store multiple actions data
This commit is contained in:
@@ -17,6 +17,8 @@ import { AuthenticatedRequest } from "../routes/record"
|
|||||||
import {capture} from "../utils/analytics";
|
import {capture} from "../utils/analytics";
|
||||||
import { Page } from "playwright";
|
import { Page } from "playwright";
|
||||||
import { WorkflowFile } from "maxun-core";
|
import { WorkflowFile } from "maxun-core";
|
||||||
|
import { googleSheetUpdateTasks, processGoogleSheetUpdates } from "../workflow-management/integrations/gsheet";
|
||||||
|
import { airtableUpdateTasks, processAirtableUpdates } from "../workflow-management/integrations/airtable";
|
||||||
chromium.use(stealthPlugin());
|
chromium.use(stealthPlugin());
|
||||||
|
|
||||||
const formatRecording = (recordingData: any) => {
|
const formatRecording = (recordingData: any) => {
|
||||||
@@ -338,14 +340,29 @@ function formatRunResponse(run: any) {
|
|||||||
runByUserId: run.runByUserId,
|
runByUserId: run.runByUserId,
|
||||||
runByScheduleId: run.runByScheduleId,
|
runByScheduleId: run.runByScheduleId,
|
||||||
runByAPI: run.runByAPI,
|
runByAPI: run.runByAPI,
|
||||||
data: {},
|
data: {
|
||||||
screenshot: null,
|
textData: [],
|
||||||
|
listData: []
|
||||||
|
},
|
||||||
|
screenshots: [] as any[],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (run.serializableOutput && run.serializableOutput['item-0']) {
|
if (run.serializableOutput) {
|
||||||
formattedRun.data = run.serializableOutput['item-0'];
|
if (run.serializableOutput.scrapeSchema && run.serializableOutput.scrapeSchema.length > 0) {
|
||||||
} else if (run.binaryOutput && run.binaryOutput['item-0']) {
|
formattedRun.data.textData = run.serializableOutput.scrapeSchema;
|
||||||
formattedRun.screenshot = run.binaryOutput['item-0'];
|
}
|
||||||
|
|
||||||
|
if (run.serializableOutput.scrapeList && run.serializableOutput.scrapeList.length > 0) {
|
||||||
|
formattedRun.data.listData = run.serializableOutput.scrapeList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (run.binaryOutput) {
|
||||||
|
Object.keys(run.binaryOutput).forEach(key => {
|
||||||
|
if (run.binaryOutput[key]) {
|
||||||
|
formattedRun.screenshots.push(run.binaryOutput[key]);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return formattedRun;
|
return formattedRun;
|
||||||
@@ -568,7 +585,7 @@ async function executeRun(id: string, userId: string) {
|
|||||||
|
|
||||||
plainRun.status = 'running';
|
plainRun.status = 'running';
|
||||||
|
|
||||||
const browser = browserPool.getRemoteBrowser(userId);
|
const browser = browserPool.getRemoteBrowser(plainRun.browserId);
|
||||||
if (!browser) {
|
if (!browser) {
|
||||||
throw new Error('Could not access browser');
|
throw new Error('Could not access browser');
|
||||||
}
|
}
|
||||||
@@ -606,24 +623,36 @@ async function executeRun(id: string, userId: string) {
|
|||||||
binaryOutput: uploadedBinaryOutput,
|
binaryOutput: uploadedBinaryOutput,
|
||||||
});
|
});
|
||||||
|
|
||||||
let totalRowsExtracted = 0;
|
let totalSchemaItemsExtracted = 0;
|
||||||
|
let totalListItemsExtracted = 0;
|
||||||
let extractedScreenshotsCount = 0;
|
let extractedScreenshotsCount = 0;
|
||||||
let extractedItemsCount = 0;
|
|
||||||
|
if (categorizedOutput.scrapeSchema) {
|
||||||
if (updatedRun.dataValues.binaryOutput && updatedRun.dataValues.binaryOutput["item-0"]) {
|
Object.values(categorizedOutput.scrapeSchema).forEach((schemaResult: any) => {
|
||||||
extractedScreenshotsCount = 1;
|
if (Array.isArray(schemaResult)) {
|
||||||
|
totalSchemaItemsExtracted += schemaResult.length;
|
||||||
|
} else if (schemaResult && typeof schemaResult === 'object') {
|
||||||
|
totalSchemaItemsExtracted += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updatedRun.dataValues.serializableOutput && updatedRun.dataValues.serializableOutput["item-0"]) {
|
if (categorizedOutput.scrapeList) {
|
||||||
const itemsArray = run.dataValues.serializableOutput["item-0"];
|
Object.values(categorizedOutput.scrapeList).forEach((listResult: any) => {
|
||||||
extractedItemsCount = itemsArray.length;
|
if (Array.isArray(listResult)) {
|
||||||
|
totalListItemsExtracted += listResult.length;
|
||||||
totalRowsExtracted = itemsArray.reduce((total, item) => {
|
}
|
||||||
return total + Object.keys(item).length;
|
});
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Extracted Items Count: ${extractedItemsCount}`);
|
if (uploadedBinaryOutput) {
|
||||||
|
extractedScreenshotsCount = Object.keys(uploadedBinaryOutput).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalRowsExtracted = totalSchemaItemsExtracted + totalListItemsExtracted;
|
||||||
|
|
||||||
|
console.log(`Extracted Schema Items Count: ${totalSchemaItemsExtracted}`);
|
||||||
|
console.log(`Extracted List Items Count: ${totalListItemsExtracted}`);
|
||||||
console.log(`Extracted Screenshots Count: ${extractedScreenshotsCount}`);
|
console.log(`Extracted Screenshots Count: ${extractedScreenshotsCount}`);
|
||||||
console.log(`Total Rows Extracted: ${totalRowsExtracted}`);
|
console.log(`Total Rows Extracted: ${totalRowsExtracted}`);
|
||||||
|
|
||||||
@@ -631,12 +660,34 @@ async function executeRun(id: string, userId: string) {
|
|||||||
runId: id,
|
runId: id,
|
||||||
created_at: new Date().toISOString(),
|
created_at: new Date().toISOString(),
|
||||||
status: 'success',
|
status: 'success',
|
||||||
extractedItemsCount,
|
|
||||||
totalRowsExtracted,
|
totalRowsExtracted,
|
||||||
|
schemaItemsExtracted: totalSchemaItemsExtracted,
|
||||||
|
listItemsExtracted: totalListItemsExtracted,
|
||||||
extractedScreenshotsCount,
|
extractedScreenshotsCount,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
googleSheetUpdateTasks[id] = {
|
||||||
|
robotId: plainRun.robotMetaId,
|
||||||
|
runId: id,
|
||||||
|
status: 'pending',
|
||||||
|
retries: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
airtableUpdateTasks[id] = {
|
||||||
|
robotId: plainRun.robotMetaId,
|
||||||
|
runId: id,
|
||||||
|
status: 'pending',
|
||||||
|
retries: 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
processAirtableUpdates();
|
||||||
|
processGoogleSheetUpdates();
|
||||||
|
} catch (err: any) {
|
||||||
|
logger.log('error', `Failed to update Google Sheet for run: ${plainRun.runId}: ${err.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
interpretationInfo: updatedRun.toJSON()
|
interpretationInfo: updatedRun.toJSON()
|
||||||
@@ -790,7 +841,7 @@ router.post("/robots/:id/runs", requireAPIKey, async (req: AuthenticatedRequest,
|
|||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
return res.status(401).json({ ok: false, error: 'Unauthorized' });
|
return res.status(401).json({ ok: false, error: 'Unauthorized' });
|
||||||
}
|
}
|
||||||
const runId = await handleRunRecording(req.params.id, req.user.dataValues.id);
|
const runId = await handleRunRecording(req.params.id, req.user.id);
|
||||||
|
|
||||||
if (!runId) {
|
if (!runId) {
|
||||||
throw new Error('Run ID is undefined');
|
throw new Error('Run ID is undefined');
|
||||||
|
|||||||
Reference in New Issue
Block a user