daimon.email
ExamplesInbound

Auto-Reply Agent

An agent that auto-replies to incoming emails

Overview

An auto-reply agent automatically responds to incoming emails with personalized messages. This example demonstrates webhook-based real-time processing, reply body extraction, and sending responses.

Info

This pattern is ideal for out-of-office responders, confirmation bots, or initial customer engagement agents.

How It Works

  1. Create an inbox for your agent
  2. Register a webhook for message.received events
  3. When an email arrives, extract the reply body
  4. Generate a contextual response
  5. Send the reply using the same thread

Complete Implementation

import { DaimonClient } from 'daimon-email';
import express from 'express';

const client = new DaimonClient();
const app = express();

app.use(express.json());

// Step 1: Create inbox and register webhook
async function setupAgent() {
  const inbox = await client.inboxes.create({
    username: 'auto-reply-bot',
    clientId: 'auto-reply-v1'
  });

  console.log(`Inbox created: ${inbox.address}`);

  // Store API key for authenticated requests
  const authedClient = new DaimonClient({ apiKey: inbox.apiKey });

  // Register webhook for real-time notifications
  const webhook = await authedClient.webhooks.create({
    endpointUrl: 'https://your-agent.com/webhook',
    events: ['message.received'],
    inboxId: inbox.id
  });

  console.log(`Webhook registered: ${webhook.id}`);

  return { inbox, authedClient, webhook };
}

// Step 2: Handle incoming messages
app.post('/webhook', async (req, res) => {
  const { event, message } = req.body;

  if (event === 'message.received') {
    console.log(`New message from: ${message.from}`);

    // Extract clean reply text (no quoted history)
    const incomingText = message.replyBody || message.body;

    // Generate contextual response
    const response = generateResponse(message);

    // Send auto-reply in the same thread
    try {
      await client.inboxes.messages.reply(message.inboxId, message.id, {
        body: response,
        clientId: `reply-${message.id}` // Idempotency
      });

      console.log(`Sent auto-reply to ${message.from}`);
    } catch (error) {
      console.error('Failed to send reply:', error);
    }
  }

  res.status(200).send('OK');
});

// Step 3: Generate contextual responses
function generateResponse(message: any): string {
  const senderName = message.from.split('@')[0];

  // Check if this is during business hours
  const hour = new Date().getHours();
  const isBusinessHours = hour >= 9 && hour < 17;

  if (!isBusinessHours) {
    return `Hi ${senderName},\n\nThank you for your message. Our team is currently out of office and will respond within 24 hours.\n\nBest regards,\nAuto-Reply Bot`;
  }

  // Business hours response
  return `Hi ${senderName},\n\nThank you for reaching out! We've received your message about "${message.subject}" and will get back to you shortly.\n\nBest regards,\nAuto-Reply Bot`;
}

// Start the agent
setupAgent().then(() => {
  app.listen(3000, () => {
    console.log('Auto-reply agent running on port 3000');
  });
});
from daimon_email import DaimonClient
from flask import Flask, request
from datetime import datetime

client = DaimonClient()
app = Flask(__name__)

# Step 1: Create inbox and register webhook
def setup_agent():
    inbox = client.inboxes.create(
        username='auto-reply-bot',
        client_id='auto-reply-v1'
    )

    print(f"Inbox created: {inbox.address}")

    # Store API key for authenticated requests
    authed_client = DaimonClient(api_key=inbox.api_key)

    # Register webhook for real-time notifications
    webhook = authed_client.webhooks.create(
        endpoint_url='https://your-agent.com/webhook',
        events=['message.received'],
        inbox_id=inbox.id
    )

    print(f"Webhook registered: {webhook.id}")

    return inbox, authed_client, webhook

# Step 2: Handle incoming messages
@app.post('/webhook')
def handle_webhook():
    data = request.json
    event = data.get('event')
    message = data.get('message')

    if event == 'message.received':
        print(f"New message from: {message['from']}")

        # Extract clean reply text (no quoted history)
        incoming_text = message.get('reply_body') or message.get('body')

        # Generate contextual response
        response = generate_response(message)

        # Send auto-reply in the same thread
        try:
            client.inboxes.messages.reply(
                message['inbox_id'],
                message['id'],
                body=response,
                client_id=f"reply-{message['id']}"  # Idempotency
            )

            print(f"Sent auto-reply to {message['from']}")
        except Exception as e:
            print(f"Failed to send reply: {e}")

    return 'OK', 200

# Step 3: Generate contextual responses
def generate_response(message):
    sender_name = message['from'].split('@')[0]

    # Check if this is during business hours
    hour = datetime.now().hour
    is_business_hours = 9 <= hour < 17

    if not is_business_hours:
        return f"""Hi {sender_name},

Thank you for your message. Our team is currently out of office and will respond within 24 hours.

Best regards,
Auto-Reply Bot"""

    # Business hours response
    return f"""Hi {sender_name},

Thank you for reaching out! We've received your message about "{message['subject']}" and will get back to you shortly.

Best regards,
Auto-Reply Bot"""

# Start the agent
if __name__ == '__main__':
    setup_agent()
    app.run(port=3000)

Advanced: LLM-Powered Responses

For more sophisticated responses, integrate an LLM to analyze incoming messages and generate contextual replies.

import OpenAI from 'openai';

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

async function generateSmartResponse(message: any): Promise<string> {
  const prompt = `You are an auto-reply assistant. Generate a professional response to this email:

From: ${message.from}
Subject: ${message.subject}
Body: ${message.replyBody}

Generate a brief, helpful auto-reply that:
1. Acknowledges their message
2. Sets expectations for response time
3. Is warm and professional`;

  const completion = await openai.chat.completions.create({
    model: 'gpt-4',
    messages: [{ role: 'user', content: prompt }],
    temperature: 0.7,
  });

  return completion.choices[0].message.content;
}
from openai import OpenAI

openai_client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))

def generate_smart_response(message):
    prompt = f"""You are an auto-reply assistant. Generate a professional response to this email:

From: {message['from']}
Subject: {message['subject']}
Body: {message['reply_body']}

Generate a brief, helpful auto-reply that:
1. Acknowledges their message
2. Sets expectations for response time
3. Is warm and professional"""

    completion = openai_client.chat.completions.create(
        model='gpt-4',
        messages=[{'role': 'user', 'content': prompt}],
        temperature=0.7
    )

    return completion.choices[0].message.content

Key Features

  • Real-time processing: Webhook-based, no polling required
  • Thread preservation: Replies stay in the same conversation
  • Idempotency: Prevent duplicate replies with clientId
  • Smart extraction: Uses replyBody to get clean text without quoted history

Next Steps