"use node"; import { internalAction } from "./_generated/server"; import { v } from "convex/values"; import { internal } from "./_generated/api"; import { AgentMailClient } from "agentmail"; // Send contact form email via AgentMail SDK // Internal action that sends email to configured recipient // Uses official AgentMail SDK: https://docs.agentmail.to/quickstart export const sendContactEmail = internalAction({ args: { messageId: v.id("contactMessages"), name: v.string(), email: v.string(), message: v.string(), source: v.string(), }, returns: v.null(), handler: async (ctx, args) => { const apiKey = process.env.AGENTMAIL_API_KEY; const inbox = process.env.AGENTMAIL_INBOX; // Contact form sends to AGENTMAIL_CONTACT_EMAIL or falls back to inbox const recipientEmail = process.env.AGENTMAIL_CONTACT_EMAIL || inbox; // Silently fail if environment variables not configured if (!apiKey || !inbox || !recipientEmail) { return null; } // Build email HTML const html = `

New Contact Form Submission

From: ${escapeHtml(args.name)}
Email: ${escapeHtml(args.email)}
Source: ${escapeHtml(args.source)}

Message:

${escapeHtml(args.message)}
`; // Plain text version const text = `New Contact Form Submission\n\nFrom: ${args.name}\nEmail: ${args.email}\nSource: ${args.source}\n\nMessage:\n${args.message}`; try { // Initialize AgentMail client with API key const client = new AgentMailClient({ apiKey }); // Send email using official SDK // https://docs.agentmail.to/sending-receiving-email await client.inboxes.messages.send(inbox, { to: recipientEmail, subject: `Contact: ${args.name} via ${args.source}`, text, html, }); // Mark email as sent in database await ctx.runMutation(internal.contact.markEmailSent, { messageId: args.messageId, }); } catch { // Silently fail on error } return null; }, }); // Helper function to escape HTML entities function escapeHtml(text: string): string { return text .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }