"use node"; import { action } from "../_generated/server"; import { v } from "convex/values"; import { internal } from "../_generated/api"; export const enviar = action({ args: { emailId: v.id("notificacoesEmail"), }, returns: v.object({ sucesso: v.boolean(), erro: v.optional(v.string()) }), handler: async (ctx, args) => { "use node"; const nodemailer = await import("nodemailer"); try { // Buscar email da fila const email = await ctx.runQuery(internal.email.getEmailById, { emailId: args.emailId, }); if (!email) { return { sucesso: false, erro: "Email não encontrado" }; } // Buscar configuração SMTP ativa com senha descriptografada const config = await ctx.runQuery(internal.email.getActiveEmailConfigWithPassword, {}); if (!config) { return { sucesso: false, erro: "Configuração de email não encontrada ou inativa", }; } if (!config.testadoEm) { return { sucesso: false, erro: "Configuração SMTP não foi testada. Teste a conexão primeiro!", }; } // Marcar como enviando await ctx.runMutation(internal.email.markEmailEnviando, { emailId: args.emailId, }); // Criar transporter do nodemailer const transporter = nodemailer.createTransport({ host: config.servidor, port: config.porta, secure: config.usarSSL, auth: { user: config.usuario, pass: config.senha, // Senha já descriptografada }, tls: { // Permitir certificados autoassinados rejectUnauthorized: false, }, }); // Enviar email const info = await transporter.sendMail({ from: `"${config.nomeRemetente}" <${config.emailRemetente}>`, to: email.destinatario, subject: email.assunto, html: email.corpo, }); console.log("✅ Email enviado com sucesso!", { para: email.destinatario, assunto: email.assunto, messageId: (info as { messageId?: string }).messageId, }); // Marcar como enviado await ctx.runMutation(internal.email.markEmailEnviado, { emailId: args.emailId, }); return { sucesso: true }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error("❌ Erro ao enviar email:", errorMessage); // Marcar como falha await ctx.runMutation(internal.email.markEmailFalha, { emailId: args.emailId, erro: errorMessage, }); return { sucesso: false, erro: errorMessage }; } }, });