Files
scripts/email-cleaner/services/geminiService.ts

112 lines
3.6 KiB
TypeScript
Executable File

/**
* geminiService.ts
*
* @author Descomplicar® Crescimento Digital
* @link https://descomplicar.pt
* @copyright 2025 Descomplicar®
*/
import { GoogleGenAI, Type } from "@google/genai";
import type { Email, ClassifiedCategory, CategorizedEmails } from "../types";
import { EmailCategory } from "../types";
const MOCKED_RESPONSE: ClassifiedCategory[] = [
{
category: EmailCategory.PROMOTIONS,
summary: "Ofertas especiais e descontos de várias lojas online.",
email_ids: [2, 5, 8, 11]
},
{
category: EmailCategory.NOTIFICATIONS,
summary: "Alertas de login, atualizações de projetos e menções em redes sociais.",
email_ids: [1, 4, 7, 10, 13]
},
{
category: EmailCategory.NEWSLETTERS,
summary: "Boletins informativos de tecnologia, design e notícias gerais.",
email_ids: [3, 6, 9, 12, 14]
}
];
const processApiResponse = (
response: ClassifiedCategory[],
allEmails: Email[]
): CategorizedEmails => {
const categorized: CategorizedEmails = {};
for (const item of response) {
const categoryKey = item.category;
if (categoryKey !== EmailCategory.IMPORTANT && categoryKey !== EmailCategory.UNKNOWN) {
const emailsInCategory = item.email_ids.map(id =>
allEmails.find(email => email.id === id)
).filter((email): email is Email => email !== undefined);
if(emailsInCategory.length > 0) {
if (!categorized[categoryKey]) {
categorized[categoryKey] = { summary: item.summary, emails: [] };
}
categorized[categoryKey].summary = item.summary;
categorized[categoryKey].emails.push(...emailsInCategory);
}
}
}
return categorized;
};
export const classifyEmails = async (emails: Email[], apiKey: string): Promise<CategorizedEmails> => {
if (!apiKey) {
console.warn("API_KEY for Gemini is not provided. Using mocked data.");
await new Promise(resolve => setTimeout(resolve, 2000));
return processApiResponse(MOCKED_RESPONSE, emails);
}
const ai = new GoogleGenAI({ apiKey });
const emailPromptData = emails.map(e => ({
id: e.id,
from: e.sender,
subject: e.subject,
snippet: e.snippet
}));
const prompt = `
Você é um especialista em organização de e-mails. Analise a seguinte lista de e-mails em formato JSON.
1. Categorize cada e-mail em uma das seguintes categorias base: ${Object.values(EmailCategory).join(', ')}.
2. Agrupe os e-mails por categoria. Para cada categoria, forneça um breve resumo em português do conteúdo e uma lista dos IDs dos e-mails correspondentes.
3. NÃO inclua a categoria 'IMPORTANTE' no resultado final.
Aqui está a lista de e-mails:
${JSON.stringify(emailPromptData, null, 2)}
`;
try {
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: prompt,
config: {
responseMimeType: "application/json",
responseSchema: {
type: Type.ARRAY,
items: {
type: Type.OBJECT,
properties: {
category: { type: Type.STRING },
summary: { type: Type.STRING },
email_ids: { type: Type.ARRAY, items: { type: Type.INTEGER } }
}
}
}
}
});
const classifiedData = JSON.parse(response.text);
return processApiResponse(classifiedData, emails);
} catch (error) {
console.error("Error calling Gemini API:", error);
throw new Error("Failed to classify emails with Gemini API.");
}
};