init: scripts diversos (crawlers, conversores, scrapers)
This commit is contained in:
80
email-cleaner/api/scan.ts
Executable file
80
email-cleaner/api/scan.ts
Executable file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* scan.ts
|
||||
*
|
||||
* @author Descomplicar® Crescimento Digital
|
||||
* @link https://descomplicar.pt
|
||||
* @copyright 2025 Descomplicar®
|
||||
*/
|
||||
|
||||
// Este arquivo representa o seu backend sem servidor (Serverless Function).
|
||||
// Você deve implementá-lo em uma plataforma como Google Cloud Run, Vercel ou Netlify Functions.
|
||||
// As credenciais (API Key, CRM Token) devem ser configuradas como variáveis de ambiente na sua plataforma de hospedagem.
|
||||
|
||||
import { classifyEmails } from '../services/geminiService';
|
||||
import { deleteTicketsFromSendersInPerfex } from '../services/perfexCrmService';
|
||||
import { mockEmails } from '../data/mockEmails';
|
||||
import { EmailCategory, type CrmSettings } from '../types';
|
||||
|
||||
// Em um ambiente de servidor real, você precisaria de um framework como Express
|
||||
// para lidar com requisições HTTP. Esta é uma simulação para fins de demonstração.
|
||||
// A função `handleRequest` simula o ponto de entrada da sua função na nuvem.
|
||||
|
||||
async function handleRequest() {
|
||||
console.log('Iniciando tarefa de limpeza automática...');
|
||||
|
||||
// 1. Ler configurações das variáveis de ambiente
|
||||
const apiKey = process.env.GEMINI_API_KEY;
|
||||
const crmSettings: CrmSettings = {
|
||||
url: process.env.PERFEX_CRM_URL || '',
|
||||
token: process.env.PERFEX_CRM_TOKEN || '',
|
||||
autoDeleteTickets: process.env.PERFEX_AUTO_DELETE_TICKETS === 'true',
|
||||
};
|
||||
|
||||
// Validação básica
|
||||
if (!apiKey) {
|
||||
console.error('Erro: A variável de ambiente GEMINI_API_KEY não está definida.');
|
||||
return { success: false, message: 'Chave da API do Gemini não configurada no servidor.' };
|
||||
}
|
||||
|
||||
try {
|
||||
// 2. Classificar e-mails usando o serviço Gemini
|
||||
const categorizedEmails = await classifyEmails(mockEmails, apiKey);
|
||||
console.log('E-mails classificados com sucesso.');
|
||||
|
||||
// 3. Excluir tickets do CRM, se configurado
|
||||
if (crmSettings.autoDeleteTickets && crmSettings.url && crmSettings.token) {
|
||||
const spamAndNotificationEmails = [
|
||||
...(categorizedEmails[EmailCategory.SPAM]?.emails || []),
|
||||
...(categorizedEmails[EmailCategory.NOTIFICATIONS]?.emails || [])
|
||||
];
|
||||
|
||||
const senderEmails = [...new Set(spamAndNotificationEmails.map(email => email.sender))];
|
||||
|
||||
if (senderEmails.length > 0) {
|
||||
try {
|
||||
const deletedCount = await deleteTicketsFromSendersInPerfex(crmSettings, senderEmails);
|
||||
console.log(`${deletedCount} tickets foram excluídos do CRM.`);
|
||||
} catch (err) {
|
||||
console.error('Erro ao excluir tickets do CRM:', (err as Error).message);
|
||||
}
|
||||
} else {
|
||||
console.log('Nenhum e-mail de spam ou notificação encontrado para exclusão de tickets.');
|
||||
}
|
||||
} else {
|
||||
console.log('A exclusão automática de tickets está desativada ou o CRM não está configurado.');
|
||||
}
|
||||
|
||||
console.log('Tarefa de limpeza automática concluída com sucesso.');
|
||||
return { success: true, message: 'Limpeza automática executada com sucesso.' };
|
||||
|
||||
} catch (error) {
|
||||
console.error('Ocorreu um erro durante a execução da tarefa de limpeza automática:', error);
|
||||
return { success: false, message: 'Falha na execução da limpeza automática.' };
|
||||
}
|
||||
}
|
||||
|
||||
// Para simular a execução, você pode chamar a função.
|
||||
// Numa implementação real, o seu provedor de nuvem (ex: Cloud Run) chamaria
|
||||
// uma função exportada quando o endpoint HTTP fosse acionado.
|
||||
// Ex: `export default async (req, res) => { ... }`
|
||||
handleRequest();
|
||||
88
email-cleaner/api/test-imap.ts
Executable file
88
email-cleaner/api/test-imap.ts
Executable file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* test-imap.ts
|
||||
*
|
||||
* @author Descomplicar® Crescimento Digital
|
||||
* @link https://descomplicar.pt
|
||||
* @copyright 2025 Descomplicar®
|
||||
*/
|
||||
|
||||
|
||||
// Em uma plataforma como Vercel ou Netlify, este arquivo se tornaria um endpoint de API.
|
||||
// Ex: POST /api/test-imap
|
||||
|
||||
import { ImapFlow } from 'imapflow';
|
||||
import type { ImapAccount } from '../types';
|
||||
|
||||
// Esta função simula o handler de uma requisição de API.
|
||||
// Em um ambiente real com Express, por exemplo, seria algo como:
|
||||
// export default async (req: Request, res: Response) => { ... }
|
||||
// Aqui, vamos simular o corpo da função.
|
||||
|
||||
const handler = async (account: Omit<ImapAccount, 'provider' | 'id' | 'avatar'>) => {
|
||||
const { host, port, user, password, secure } = account;
|
||||
|
||||
if (!host || !port || !user || !password) {
|
||||
// No mundo real, retornaríamos um status HTTP 400
|
||||
return {
|
||||
success: false,
|
||||
message: 'Todos os campos (host, porta, usuário, senha) são obrigatórios.',
|
||||
};
|
||||
}
|
||||
|
||||
const client = new ImapFlow({
|
||||
host,
|
||||
port,
|
||||
secure,
|
||||
auth: {
|
||||
user,
|
||||
pass: password,
|
||||
},
|
||||
logger: false, // Mude para true para debug detalhado no console do servidor
|
||||
});
|
||||
|
||||
try {
|
||||
await client.connect();
|
||||
await client.logout();
|
||||
|
||||
// No mundo real, retornaríamos um status HTTP 200
|
||||
return {
|
||||
success: true,
|
||||
message: 'Conexão IMAP bem-sucedida!',
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(`Falha na conexão IMAP para ${user}@${host}:`, err);
|
||||
|
||||
let friendlyMessage = 'Falha na conexão IMAP. Verifique suas credenciais e configurações.';
|
||||
if (err instanceof Error) {
|
||||
if (err.message.includes('ENOTFOUND')) {
|
||||
friendlyMessage = 'O host do servidor não foi encontrado. Verifique o endereço do host.';
|
||||
} else if (err.message.includes('ECONNREFUSED')) {
|
||||
friendlyMessage = 'A conexão foi recusada. Verifique a porta e as configurações de segurança (TLS/SSL).';
|
||||
} else if (err.message.toLowerCase().includes('authentication failed')) {
|
||||
friendlyMessage = 'Falha na autenticação. Verifique o usuário e a senha.';
|
||||
}
|
||||
}
|
||||
|
||||
// No mundo real, retornaríamos um status HTTP 500 ou 401
|
||||
return {
|
||||
success: false,
|
||||
message: friendlyMessage,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Para fins de teste, você pode simular uma chamada.
|
||||
// Em um projeto real, o framework (Express/Next/Vercel) chamaria o handler
|
||||
// com base no corpo da requisição (req.body).
|
||||
//
|
||||
// Exemplo de como o frontend chamaria esta API:
|
||||
//
|
||||
// const response = await fetch('/api/test-imap', {
|
||||
// method: 'POST',
|
||||
// headers: { 'Content-Type': 'application/json' },
|
||||
// body: JSON.stringify({ host, port, user, password, secure })
|
||||
// });
|
||||
// const result = await response.json();
|
||||
// alert(result.message);
|
||||
|
||||
export default handler;
|
||||
Reference in New Issue
Block a user