Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,5 @@ _fresh/

# Deco files
_docker_deps.ts
.metadata/changeset.json
.metadata/changeset.json
.env.local
2 changes: 2 additions & 0 deletions convex/_generated/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {
FunctionReference,
} from "convex/server";
import type * as contatos from "../contatos.js";
import type * as emails from "../emails.js";

/**
* A utility for referencing Convex functions in your app's API.
Expand All @@ -25,6 +26,7 @@ import type * as contatos from "../contatos.js";
*/
declare const fullApi: ApiFromModules<{
contatos: typeof contatos;
emails: typeof emails;
}>;
export declare const api: FilterApi<
typeof fullApi,
Expand Down
8 changes: 8 additions & 0 deletions convex/contatos.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mutation, query } from "./_generated/server.js";
import { v } from "convex/values";
import { internal } from "./_generated/api.js";

export const submitContactForm = mutation({
args: {
Expand All @@ -16,6 +17,13 @@ export const submitContactForm = mutation({
created_at: now,
});

// Agendar envio de notificação por email
await ctx.scheduler.runAfter(0, internal.emails.sendContactNotification, {
nome: args.nome,
email: args.email,
mensagem: args.mensagem,
});

return { id: contactId };
},
});
Expand Down
47 changes: 47 additions & 0 deletions convex/emails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { internalAction } from "./_generated/server.js";
import { v } from "convex/values";

export const sendContactNotification = internalAction({
args: {
nome: v.string(),
email: v.string(),
mensagem: v.string(),
},
handler: async (ctx, args) => {
const apiKey = process.env.RESEND_API_KEY;
if (!apiKey) {
throw new Error("RESEND_API_KEY não configurada");
}

const notificationEmail = process.env.NOTIFICATION_EMAIL ?? "daniel@deriva.earth";

const response = await fetch("https://api.resend.com/emails", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
from: "Deriva <contato@deriva.earth>",
to: [notificationEmail],
subject: `Novo contato: ${args.nome}`,
html: `
<h2>Novo contato pelo site</h2>
<p><strong>Nome:</strong> ${args.nome}</p>
<p><strong>Email:</strong> ${args.email}</p>
<p><strong>Mensagem:</strong></p>
<p>${args.mensagem}</p>
<hr />
<p style="color: #888; font-size: 12px;">Enviado pelo formulário de contato - Deriva Earth</p>
`,
}),
});

if (!response.ok) {
const error = await response.text();
throw new Error(`Erro ao enviar email: ${error}`);
}

return { success: true };
},
});
Loading