· 4 years ago · Jul 07, 2021, 06:12 AM
1// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2import type { NextApiRequest, NextApiResponse } from "next";
3const puppeteer = require('puppeteer');
4
5// Environment stuff.
6const inProduction =
7 process.env.ENVIRONMENT && process.env.ENVIRONMENT == "production";
8const secretKey = process.env.SECRET;
9
10type RequestBody = {
11 url: string;
12};
13
14type ResponseBody = {
15 content?: string;
16 error?: string;
17};
18
19export default async function handler(
20 req: NextApiRequest,
21 res: NextApiResponse<ResponseBody>
22) {
23 if (!req.headers.authorization || req.headers.authorization != secretKey) {
24 res.status(401).json({ error: "not authorized" });
25 return
26 }
27 let body = req.body as RequestBody;
28 if (!body.url || body.url == "") {
29 res.status(400).json({ error: "invalid request url" });
30 return;
31 }
32 const start = new Date().getTime();
33 var content;
34 try {
35 const browser = await puppeteer.launch({
36 args: inProduction ? ["--no-sandbox", "--font-render-hinting=none"] : [],
37 executablePath: inProduction
38 ? "/usr/bin/chromium-browser"
39 : process.platform === "win32"
40 ? "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
41 : process.platform === "linux"
42 ? "/usr/bin/google-chrome"
43 : "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
44 headless: true,
45 });
46 const page = await browser.newPage();
47 await page.goto(body.url, { waitUntil: "networkidle0" });
48 content = await page.evaluate(() => document.querySelector("*")?.outerHTML);
49 await browser.close();
50 } catch (err) {
51 console.warn(err);
52 res.status(500).json({ error: "error occured while fetching; see console output" });
53 return;
54 }
55 console.log("Fetched %s in %dms.", body.url, new Date().getTime() - start);
56 res.status(200).json({ content });
57}
58