Building an Automatic AI Email Replier

Introduction: Building an Automatic AI Email Replier

In this lesson, you’ll learn how to build an automatic AI replier that reads an incoming email and writes a reply on behalf of an employee—in this case, Emily from Acme Corp. You’ve already learned how to parse emails and use different agents. Now, we’ll focus on how to generate and send a reply using the addReply method.

Quick Recap: Parsing Emails and Using Agents

Before we dive in, let’s quickly review what you’ve already learned:

  • Parsing Emails: You know how to read an email thread from a file and break it into structured objects using parseEmailThread.
  • Agents: You’ve built and used two agents:
    • The IntentAgent classifies the intent of an email (e.g., question, meeting request).
    • The SummaryAgent summarizes the email, decides if a reply is needed, and drafts a reply.

Now, let’s see how to use the addReply method to automatically add a reply to an email thread.

How the addReply Method Works

The addReply function is the key to making your AI replier actually participate in an email conversation. It takes three arguments: the original email thread, the reply body (the text of the reply), and the email address of the replier (for example, Emily’s email).

The first thing addReply does is break the thread into individual emails, so it can figure out who sent the original message and what the subject was. It uses your existing parseEmailThread function for this:

TypeScript
const emails = parseEmailThread(threadRaw);
const firstEmail = emails[0];

Now, it prepares the fields for the reply. The from field is set to the agent’s email (e.g., emily@acme-corp.com). The to field is set to the original sender of the first email in the thread. The subject is set to include Re: if it’s not already present:

TypeScript
const from = agentEmail;
const to = firstEmail.from;
let subject = firstEmail.subject.startsWith("Re:") ? firstEmail.subject : `Re: ${firstEmail.subject}`;

Next, it constructs the reply’s header and body, making sure the format matches the rest of the thread. The header includes the From, To, and Subject fields, followed by the reply body:

TypeScript
const header = `From: ${from}\nTo: ${to}\nSubject: ${subject}`;
const replyEmail = `${header}\n\n${replyBody}`;

Finally, the function appends the reply to the end of the thread, separated by a line (\n---\n\n). This makes the reply appear as a new message in the conversation:

TypeScript
return threadRaw.trim() + "\n---\n\n" + replyEmail;

Putting it all together, here’s the complete addReply function:

TypeScript
export function addReply(threadRaw: string, replyBody: string, agentEmail: string) {
  const emails = parseEmailThread(threadRaw);
  const firstEmail = emails[0];

  const from = agentEmail;
  const to = firstEmail.from;
  let subject = firstEmail.subject.startsWith("Re:") ? firstEmail.subject : `Re: ${firstEmail.subject}`;

  const header = `From: ${from}\nTo: ${to}\nSubject: ${subject}`;
  const replyEmail = `${header}\n\n${replyBody}`;

  return threadRaw.trim() + "\n---\n\n" + replyEmail;
}

Example Usage

Here’s a short example showing how you might orchestrate your agents and use addReply to automatically generate and append a reply to an email thread:

TypeScript
async function main() {
  const emailContent = readFileSync("example-email-thread.txt", "utf-8");
  const thread = parseEmailThread(emailContent);

  const summaryAgent = mastra.getAgent("SummaryAgent");
  const intentAgent = mastra.getAgent("IntentAgent");

  const email = thread[0];
  const emailText = email.header + "\n\n" + email.body;

  const intent = (await intentAgent.generate([{ role: "user", content: emailText }])).text;
  const { draftReply, replyNeeded } = await summaryAgent.processEmail(emailText, intent);

  if (replyNeeded) {
    const updatedThread = addReply(emailContent, draftReply, "emily@acme-corp.com");
    console.log("Updated Thread:\n", updatedThread);
  }
}

In this example:

  • The email thread is loaded from a file and parsed.
  • The first email’s content is sent to the IntentAgent to determine the intent.
  • The SummaryAgent uses the email and its intent to decide if a reply is needed and, if so, drafts a reply.
  • If a reply is needed, addReply is called to append the draft reply to the thread as if it came from Emily. The updated thread is then printed.

Example Output

If the original thread is:

plaintext
From: sarah.jones@acme-corp.com
To: engineering-team@acme-corp.com
Subject: Project Phoenix – Action Items & Confirmation Needed

Hi Team,

Thanks for your work on Project Phoenix so far...

After calling addReply, the thread will look like:

plaintext
From: sarah.jones@acme-corp.com
To: engineering-team@acme-corp.com
Subject: Project Phoenix – Action Items & Confirmation Needed

Hi Team,

Thanks for your work on Project Phoenix so far...

---
From: emily@acme-corp.com
To: sarah.jones@acme-corp.com
Subject: Re: Project Phoenix – Action Items & Confirmation Needed

Hi Sarah, I’ve received my task and will start drafting test cases from the updated specs. Let me know if there’s anything else you need from me.

Summary

You now know how the addReply method works to append a new reply to an email thread, making it look like a real response from an employee. This is a key step in building an automatic AI replier that can participate in email conversations on behalf of your team.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal