Files
firecrawl/apps/api/src/controllers/v1/batch-scrape.ts
T

121 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-10-17 19:40:18 +02:00
import { Response } from "express";
import { v4 as uuidv4 } from "uuid";
import {
2024-10-23 15:37:24 -03:00
BatchScrapeRequest,
batchScrapeRequestSchema,
2024-10-17 19:40:18 +02:00
CrawlResponse,
RequestWithAuth,
ScrapeOptions,
2024-10-17 19:40:18 +02:00
} from "./types";
import {
addCrawlJobs,
2024-12-04 23:35:29 +01:00
getCrawl,
2024-10-17 19:40:18 +02:00
lockURLs,
saveCrawl,
StoredCrawl,
} from "../../lib/crawl-redis";
import { logCrawl } from "../../services/logging/crawl_log";
import { getJobPriority } from "../../lib/job-priority";
2024-10-25 20:21:12 +02:00
import { addScrapeJobs } from "../../services/queue-jobs";
import { callWebhook } from "../../services/webhook";
import { logger as _logger } from "../../lib/logger";
2024-10-17 19:40:18 +02:00
2024-10-23 15:37:24 -03:00
export async function batchScrapeController(
req: RequestWithAuth<{}, CrawlResponse, BatchScrapeRequest>,
2024-10-17 19:40:18 +02:00
res: Response<CrawlResponse>
) {
2024-10-23 15:37:24 -03:00
req.body = batchScrapeRequestSchema.parse(req.body);
2024-10-17 19:40:18 +02:00
2024-12-04 23:35:29 +01:00
const id = req.body.appendToId ?? uuidv4();
const logger = _logger.child({ crawlId: id, batchScrapeId: id, module: "api/v1", method: "batchScrapeController", teamId: req.auth.team_id, plan: req.auth.plan });
logger.debug("Batch scrape " + id + " starting", { urlsLength: req.body.urls, appendToId: req.body.appendToId, account: req.account });
2024-10-17 19:40:18 +02:00
2024-12-04 23:35:29 +01:00
if (!req.body.appendToId) {
await logCrawl(id, req.auth.team_id);
}
2024-10-17 19:40:18 +02:00
2024-11-07 20:57:33 +01:00
let { remainingCredits } = req.account!;
2024-10-17 19:40:18 +02:00
const useDbAuthentication = process.env.USE_DB_AUTHENTICATION === 'true';
if(!useDbAuthentication){
remainingCredits = Infinity;
}
2024-12-04 23:35:29 +01:00
const sc: StoredCrawl = req.body.appendToId ? await getCrawl(req.body.appendToId) as StoredCrawl : {
2024-10-17 19:40:18 +02:00
crawlerOptions: null,
2024-11-07 20:57:33 +01:00
scrapeOptions: req.body,
internalOptions: {},
2024-10-17 19:40:18 +02:00
team_id: req.auth.team_id,
createdAt: Date.now(),
plan: req.auth.plan,
};
2024-12-04 23:35:29 +01:00
if (!req.body.appendToId) {
await saveCrawl(id, sc);
}
2024-10-17 19:40:18 +02:00
let jobPriority = 20;
// If it is over 1000, we need to get the job priority,
// otherwise we can use the default priority of 20
if(req.body.urls.length > 1000){
// set base to 21
jobPriority = await getJobPriority({plan: req.auth.plan, team_id: req.auth.team_id, basePriority: 21})
}
logger.debug("Using job priority " + jobPriority, { jobPriority });
2024-10-17 19:40:18 +02:00
2024-12-05 20:49:28 +01:00
const scrapeOptions: ScrapeOptions = { ...req.body };
delete (scrapeOptions as any).urls;
delete (scrapeOptions as any).appendToId;
2024-10-17 19:40:18 +02:00
const jobs = req.body.urls.map((x) => {
return {
data: {
url: x,
2024-10-25 20:21:12 +02:00
mode: "single_urls" as const,
2024-10-17 19:40:18 +02:00
team_id: req.auth.team_id,
2024-11-07 20:57:33 +01:00
plan: req.auth.plan!,
2024-10-17 19:40:18 +02:00
crawlerOptions: null,
2024-12-05 20:49:28 +01:00
scrapeOptions,
2024-10-17 19:40:18 +02:00
origin: "api",
crawl_id: id,
sitemapped: true,
v1: true,
2024-11-14 22:36:28 +01:00
webhook: req.body.webhook,
2024-10-17 19:40:18 +02:00
},
opts: {
2024-10-25 20:21:12 +02:00
jobId: uuidv4(),
2024-10-17 19:40:18 +02:00
priority: 20,
},
};
});
logger.debug("Locking URLs...");
2024-10-17 19:40:18 +02:00
await lockURLs(
id,
sc,
2024-10-17 19:40:18 +02:00
jobs.map((x) => x.data.url)
);
logger.debug("Adding scrape jobs to Redis...");
2024-10-17 19:40:18 +02:00
await addCrawlJobs(
id,
jobs.map((x) => x.opts.jobId)
);
logger.debug("Adding scrape jobs to BullMQ...");
2024-10-25 20:21:12 +02:00
await addScrapeJobs(jobs);
2024-10-17 19:40:18 +02:00
if(req.body.webhook) {
logger.debug("Calling webhook with batch_scrape.started...", { webhook: req.body.webhook });
await callWebhook(req.auth.team_id, id, null, req.body.webhook, true, "batch_scrape.started");
}
2024-10-17 19:40:18 +02:00
const protocol = process.env.ENV === "local" ? req.protocol : "https";
return res.status(200).json({
success: true,
id,
2024-10-23 15:37:24 -03:00
url: `${protocol}://${req.get("host")}/v1/batch/scrape/${id}`,
2024-10-17 19:40:18 +02:00
});
}