infoalloggi-monorepo/apps/infoalloggi/src/server/services/puppeteer.service.ts

87 lines
2.4 KiB
TypeScript
Raw Normal View History

import { TRPCError } from "@trpc/server";
import puppeteer from "puppeteer-core";
import { env } from "~/env";
import type { AnnunciId } from "~/schemas/public/Annunci";
import { getKeydbClient } from "~/utils/keydb";
import { TOKEN_CONFIG } from "../auth/configs";
export const genPdfSchedaAnnuncioBase64 = async (annuncioId: AnnunciId) => {
const pdf = await genPdfSchedaAnnuncio(annuncioId);
const pdfBase64 = Buffer.from(pdf).toString("base64");
const base64Content = pdfBase64.includes("base64,")
? pdfBase64.split("base64,")[1]
: pdfBase64;
if (!base64Content) {
throw new Error("Failed to convert PDF to base64");
}
return base64Content;
};
export const genPdfSchedaAnnuncio = async (annuncioId: AnnunciId) => {
const keybd = getKeydbClient();
if (keybd) {
const cacheKey = `scheda-annuncio-${annuncioId}`;
const cached = await keybd.get(cacheKey);
if (cached) {
return new Uint8Array(Buffer.from(cached, "base64"));
}
const scheda = await puppeteerSchedaAnnuncio(annuncioId);
await keybd.set(
cacheKey,
Buffer.from(scheda).toString("base64"),
"EX",
3600 * 5,
);
return scheda;
}
return await puppeteerSchedaAnnuncio(annuncioId);
};
const puppeteerSchedaAnnuncio = async (annuncioId: AnnunciId) => {
let browser = null;
try {
browser = await puppeteer.connect({
browserWSEndpoint: env.BROWSER_WS_URL,
});
const page = await browser.newPage();
const productionDomain = new URL(env.INTERNAL_BASE_URL).hostname;
const newCookies = [
{
name: TOKEN_CONFIG.OVERRIDE_TOKEN_COOKIE_NAME,
value: env.EXP_API_PASS,
domain:
env.NODE_ENV === "production"
? productionDomain
: "host.docker.internal",
path: "/",
},
];
await browser.setCookie(...newCookies);
const baseUrl =
env.NODE_ENV === "production"
? env.INTERNAL_BASE_URL
: `http://host.docker.internal:3000`;
const targetUrl = `${baseUrl}/area-riservata/admin/scheda-annuncio-stampa/${annuncioId}?raw=true`;
await page.goto(targetUrl, { waitUntil: "networkidle0" });
const pdf = await page.pdf({
format: "A4",
printBackground: true,
});
return pdf;
} catch (error) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: `Errore nella generazione del PDF: ${(error as Error).message}`,
});
} finally {
// 'disconnect' tells browserless you're done with this tab
if (browser) await browser.disconnect();
}
};