Auto-Reply Email Agent
Overview
Learn how to build an email auto-reply agent that automatically responds to incoming emails. This beginner-friendly example demonstrates the core concepts of building with AgentMail: receiving webhooks, processing email events, and sending automated replies.
What You’ll Build
By the end of this guide, you’ll have a working auto-reply agent that:
- Receives incoming emails to a dedicated AgentMail inbox
- Processes webhook events in real-time
- Extracts sender information (name and email)
- Generates personalized replies using a template
- Sends automated responses back to the sender
Here’s what the user experience looks like:
Prerequisites
Before you begin, make sure you have:
Required:
- Python 3.8 or higher installed
- An AgentMail account and API key
- An ngrok account (free tier works)
Project Setup
Step 1: Create Project Directory
Create a new directory for your agent:
Step 2: Create the Agent Code
Create a file named agent.py and paste the following code:
Click to view full agent.py code
Step 3: Create Requirements File
Create a file named requirements.txt:
Step 4: Install Dependencies
Install the required Python packages:
Step 5: Configure Environment Variables
Create a .env file with your credentials:
Code Walkthrough
Let’s understand how the agent works by breaking down the key components.
Architecture Overview
1. Initialization
Key points:
- Load
.envvariables before importing AgentMail - AgentMail SDK automatically reads
AGENTMAIL_API_KEYfrom environment - Flask creates the web server for receiving webhooks
2. Setting Up Infrastructure
The setup_agentmail() function creates your inbox and webhook:
Why client_id?
The client_id parameter makes this operation idempotent - you can run it multiple times without creating duplicates. If the inbox already exists, AgentMail returns the existing one.
What’s happening:
- Ngrok creates a public URL that forwards to
localhost:8080 - We register a webhook with AgentMail
- AgentMail will POST to this URL when emails arrive
3. Processing Webhooks
The webhook endpoint receives incoming email notifications:
Why ignore message.sent?
When your agent sends a reply, AgentMail triggers a message.sent webhook. If we don’t filter this out, the agent would treat its own replies as new emails and respond to itself infinitely!
By returning 200, we tell AgentMail “I received this webhook successfully, but I’m choosing not to process it.”
4. Extracting Email Data
Webhook payload structure:
5. Parsing Sender Information
Email addresses can come in different formats. We handle both:
Examples:
"John Doe <john@example.com>"→ name: “John Doe”, email: “john@example.com”"john@example.com"→ name: “John”, email: “john@example.com”"Last, First <name@example.com>"→ name: “Name”, email: “name@example.com”
6. Generating the Reply
This simple template-based approach requires no AI or external APIs. The reply is personalized with the sender’s name.
7. Sending the Reply
Important details:
toparameter must be a list of email addressesmessage_idlinks the reply to the original email (threading)- Always return
200status to acknowledge the webhook - Errors are logged but don’t crash the server
Why always return 200?
Even if sending the reply fails, we return 200 to AgentMail. This tells AgentMail “I received and processed this webhook.” If we returned an error status, AgentMail would retry sending the webhook multiple times, which isn’t helpful for application errors.
Running the Agent
Start the agent:
You should see output like this:
Success! Your agent is now running and ready to receive emails.
Leave this terminal window open - closing it will stop the agent.
Testing Your Agent
Let’s verify everything works by sending a test email.
Send a Test Email
-
Open your personal email (Gmail, Outlook, etc.)
-
Compose a new email:
-
Send the email
Watch the Magic Happen
In your terminal, you should see:
Check Your Inbox
Within seconds, you should receive an automated reply:
It works! You just built and tested your first AgentMail agent.
The agent extracted your name, personalized the message, and sent an instant reply.
Customization
You can customize the auto-reply message by editing the generate_reply() function in agent.py.
The function has access to:
sender_name- The sender’s name extracted from their emailsubject- The subject line of the email
Simply modify the text in the return statement to change what your agent replies with.
Troubleshooting
Common Issues
ModuleNotFoundError: No module named 'agentmail'
Problem: Python dependencies not installed.
Solution:
If using a virtual environment, make sure it’s activated first:
AgentMail API Error: Unauthorized
Problem: Invalid or missing API key.
Solutions:
- Check your
.envfile has the correctAGENTMAIL_API_KEY - Verify the API key is valid in your AgentMail Dashboard
- Make sure there are no extra spaces or quotes around the key
- Ensure
.envis in the same directory asagent.py
Test your API key:
Ngrok authentication failed
Problem: Invalid or missing ngrok auth token.
Solutions:
- Get your auth token from ngrok dashboard
- Update
NGROK_AUTHTOKENin.env - Verify the token has no extra spaces
Alternatively, configure ngrok globally:
Webhook not receiving emails
Checklist:
- Is the agent running? (
python agent.pyshould show “Waiting for incoming emails…”) - Is ngrok tunnel active? (Check console output for webhook URL)
- Did you send email to the correct inbox? (Check console for inbox address)
- Is the webhook URL accessible? Test with:
curl https://your-domain.ngrok-free.app/webhook/agentmail
Debug steps:
- Add logging to see webhook payloads:
-
Check ngrok dashboard for webhook requests:
- Visit ngrok dashboard
- View request logs to see if webhooks are arriving
-
Verify webhook is registered:
Port 8080 already in use
Problem: Another process is using port 8080.
Solution 1: Kill the process using the port
Solution 2: Use a different port
Reply not being sent
Problem: Webhook received but no reply sent.
Debug steps:
- Check console for error messages
- Verify the reply API parameters:
- Test the reply API directly:
- Ensure
tois a list (common mistake):
Congratulations! You’ve built your first AgentMail agent.
Advanced Feature: AI-Powered Replies
Want to upgrade your agent with intelligent, context-aware responses? You can add AI-powered replies using OpenAI.
Step 1: Install OpenAI
Step 2: Add your OpenAI API key to .env
Step 3: Add thread history and AI reply functions to agent.py
After the generate_reply() function, add:
Step 4: Update the webhook handler
In the receive_webhook() function, add thread_id extraction and replace the reply generation section:
How it works:
- Agent fetches entire email thread using
client.threads.get(thread_id) - Thread history is formatted and passed to OpenAI for context-aware replies
- AI can reference previous messages and provide more intelligent responses
- If OpenAI API fails, keep trying for three times
Result:
Your agent now has conversation memory. When replying to follow-up emails, the AI sees the entire conversation history and can provide contextual, intelligent responses that reference previous exchanges instead of generic auto-replies.
If you build something cool with AgentMail, we’d love to hear about it. Share in our Discord community!
