Automating Client Emails with AI
Draft and send personalized emails directly from your AI agent using Resend.
Dwizi Team
Editorial
Automating Client Emails with AI
We have all used ChatGPT to write an email. You paste in some bullet points, ask it to "make this sound professional," and it spits out a beautifully written message.
Then what do you do?
You highlight the text. Cmd+C. Switch tabs to Gmail. Click "Compose". Cmd+V. Type in the subject line. Type in the recipient's address. Read it over. Click Send.
This is the "Copy-Paste Gap".
For a single email, it's a minor annoyance. But if you want to build an autonomous system—say, an agent that automatically follows up with leads, or sends weekly reports to clients—this gap is a brick wall. An agent that can only draft text but cannot send it is not an agent. It's just a fancy typewriter.
The Fear of the "Send" Button
Why haven't we given agents email access yet? Because it's scary.
We are terrified that the AI will hallucinate. We imagine it sending a "Dear [Customer Name]" placeholder to our biggest client, or promising a discount we can't honor.
To solve this, we need a tool that is constrained. We don't give the AI access to our entire Gmail account. We give it a specific, limited tool to send messages through a transactional provider.
The Solution: Transactional Email as a Tool
We will use Resend (or SendGrid/Mailgun) to build a send_email tool. This tool acts as a funnel. It enforces rules:
- Identity: The AI can only send from the address we hardcode (e.g.,
ai-assistant@company.com). It can't impersonate the CEO. - Tracking: Every email sent via API is logged. We have a paper trail.
- Structure: We force the AI to provide a clear Subject and Body.
The Implementation
/**
* Sends an email to a recipient.
*
* Description for LLM: "Send an email to a user. Use this for follow-ups, reports, or notifications."
*/
// 1. The Input Contract
// We keep it simple. To, Subject, Body.
// Note: We expect 'htmlBody', which encourages the AI to use bolding and lists
// for better readability.
type Input = {
to: string;
subject: string;
htmlBody: string;
};
export default async function sendEmail(args: Input) {
// 2. The Identity Check
// We grab the API key from the vault.
const apiKey = Deno.env.get("RESEND_API_KEY");
if (!apiKey) throw new Error("Missing RESEND_API_KEY");
// CRITICAL: We hardcode the 'from' address.
// The AI cannot choose who this email comes from.
// This prevents identity spoofing hallucinations.
const from = "Agent <notifications@your-domain.com>";
const { to, subject, htmlBody } = args;
// 3. The Transmission
const res = await fetch("https://api.resend.com/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from,
to: [to], // We wrap it in an array because the API expects a list
subject,
html: htmlBody,
}),
});
const data = await res.json();
if (!res.ok) {
// If the email fails (e.g. invalid address), we tell the AI why.
return { success: false, error: data.message };
}
// 4. The Receipt
// We return the ID so the AI can log it: "Email sent (ID: re_123)."
return { success: true, id: data.id };
}
The Human-in-the-Loop Pattern
You might still be nervous about full automation. That's fine! You can use this tool in a "Human-in-the-Loop" workflow.
- Agent: Drafts the email.
- Agent: Asks you in chat: "Here is the email I plan to send to John. Do you approve?"
- Human: "Yes, go ahead."
- Agent: Then calls the
send_emailtool.
This gives you the speed of automation with the safety of human oversight. The tool makes the final step ("Clicking Send") instantaneous, even if the approval step is manual.
The Execution Story
User: "Send a welcome email to the new signup, sarah@tech.com."
Agent Action:
- Drafts a polite welcome message.
- Calls
send_emailwith:{ "to": "sarah@tech.com", "subject": "Welcome to the Platform!", "htmlBody": "<h1>Welcome Sarah!</h1><p>We are glad to have you...</p>" } - Result: Sarah receives the email instantly. The agent reports back: "Email sent successfully."
No copy-paste. No tab switching. Just done.
Subscribe to Dwizi Blog
Get stories on the future of work, autonomous agents, and the infrastructure that powers them. No fluff.
We respect your inbox. Unsubscribe at any time.
Read Next
Building a Slack Bot without a Server
How to let your AI agents post to Slack using a secure, serverless Dwizi tool.
The Junior Dev (GitHub)
Automating the first 15 minutes of every bug report. How to build an agent that triages issues.
Why Your AI Agent Needs a Calculator
LLMs are bad at math. Fix that by giving them a deterministic calculator tool.