daimon.email
ExamplesOutbound

Real-time Sales Agent

Sales agent with real-time response monitoring

Overview

A real-time sales agent uses webhooks to instantly detect and respond to prospect replies, maintaining conversation momentum and maximizing engagement. This example demonstrates webhook-based real-time processing for sales workflows.

Info

Real-time response capabilities can increase conversion rates by 3-5x compared to delayed follow-ups.

How It Works

  1. Set up instant webhook notifications for replies
  2. Detect reply sentiment and intent immediately
  3. Generate contextual follow-ups within seconds
  4. Escalate hot leads to human sales reps in real-time
  5. Maintain thread continuity throughout the conversation

Complete Implementation

import { DaimonClient } from 'daimon-email';
import OpenAI from 'openai';
import express from 'express';
import { createServer } from 'http';
import { Server as SocketIO } from 'socket.io';

const client = new DaimonClient({ apiKey: process.env.DAIMON_API_KEY });
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const app = express();
const httpServer = createServer(app);
const io = new SocketIO(httpServer);

app.use(express.json());

interface ReplyAnalysis {
  sentiment: 'positive' | 'neutral' | 'negative';
  intent: 'interested' | 'not_interested' | 'needs_info' | 'objection';
  urgency: 'high' | 'medium' | 'low';
  shouldEscalate: boolean;
  suggestedResponse: string;
}

// Step 1: Set up real-time webhook
async function setupRealtimeSales() {
  const inbox = await client.inboxes.create({
    username: 'realtime-sales',
    clientId: 'realtime-sales-v1'
  });

  console.log(`Real-time sales inbox: ${inbox.address}`);

  const authedClient = new DaimonClient({ apiKey: inbox.apiKey });

  // Register webhook with high priority
  const webhook = await authedClient.webhooks.create({
    endpointUrl: 'https://your-sales-agent.com/webhook/instant',
    events: ['message.received'],
    inboxId: inbox.id,
    metadata: {
      priority: 'high',
      realtime: true
    }
  });

  console.log('Real-time webhook registered');

  return { inbox, authedClient };
}

// Step 2: Handle instant reply notification
app.post('/webhook/instant', async (req, res) => {
  // Acknowledge webhook immediately
  res.status(200).send('OK');

  // Process asynchronously
  const { event, message } = req.body;

  if (event === 'message.received') {
    // Process with high priority
    setImmediate(async () => {
      await handleInstantReply(message);
    });
  }
});

// Step 3: Real-time reply analysis
async function handleInstantReply(message: any) {
  const startTime = Date.now();

  console.log(`⚡ Instant reply from ${message.from}`);

  // Broadcast to connected dashboards/operators
  io.emit('new_reply', {
    from: message.from,
    subject: message.subject,
    preview: message.replyBody.substring(0, 100),
    timestamp: new Date()
  });

  // Analyze reply with LLM (parallel to other operations)
  const analysisPromise = analyzeReplyIntent(message);

  // Get thread context (parallel)
  const contextPromise = getThreadContext(message.threadId);

  // Wait for both
  const [analysis, context] = await Promise.all([analysisPromise, contextPromise]);

  const processingTime = Date.now() - startTime;
  console.log(`Analysis complete in ${processingTime}ms`);

  // Step 4: Take action based on analysis
  if (analysis.shouldEscalate) {
    await escalateToHuman(message, analysis, context);
  } else if (analysis.intent === 'interested') {
    await sendInstantFollowUp(message, analysis, context);
  } else if (analysis.intent === 'needs_info') {
    await provideInformation(message, analysis, context);
  } else if (analysis.intent === 'not_interested') {
    await sendPoliteDisengagement(message);
  }

  // Track metrics
  io.emit('reply_processed', {
    from: message.from,
    processingTime,
    analysis,
    action: analysis.shouldEscalate ? 'escalated' : 'auto_responded'
  });
}

// Step 4: LLM-powered intent analysis
async function analyzeReplyIntent(message: any): Promise<ReplyAnalysis> {
  const prompt = `Analyze this sales email reply:

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

Return JSON with:
{
  "sentiment": "positive" | "neutral" | "negative",
  "intent": "interested" | "not_interested" | "needs_info" | "objection",
  "urgency": "high" | "medium" | "low",
  "shouldEscalate": true/false,
  "suggestedResponse": "brief response text"
}

Escalate if: shows strong buying intent, mentions budget/timeline, asks for demo, or mentions competitors.`;

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

  return JSON.parse(completion.choices[0].message.content);
}

// Step 5: Instant escalation to human
async function escalateToHuman(message: any, analysis: ReplyAnalysis, context: any) {
  console.log(`🔥 HOT LEAD - Escalating ${message.from} to human`);

  // Notify human sales rep via multiple channels
  await Promise.all([
    // Email notification
    client.inboxes.send(message.inboxId, {
      to: 'sales-team@yourcompany.com',
      subject: `🔥 HOT LEAD: ${message.from}`,
      body: `URGENT: High-intent reply detected!

From: ${message.from}
Sentiment: ${analysis.sentiment}
Intent: ${analysis.intent}
Urgency: ${analysis.urgency}

Their reply:
"${message.replyBody}"

Suggested response:
"${analysis.suggestedResponse}"

Thread: https://app.daimon.email/threads/${message.threadId}

Take over this conversation immediately!`,
      clientId: `escalation-${message.id}`
    }),

    // Real-time dashboard notification
    new Promise(resolve => {
      io.emit('hot_lead', {
        from: message.from,
        subject: message.subject,
        reply: message.replyBody,
        analysis,
        threadId: message.threadId,
        url: `https://app.daimon.email/threads/${message.threadId}`
      });
      resolve(null);
    }),

    // Slack notification (example)
    // slackClient.chat.postMessage({ ... })
  ]);

  // Send holding response to prospect
  await client.inboxes.messages.reply(message.inboxId, message.id, {
    body: `Thanks for your quick response! I'm looping in our senior account executive who can answer your questions in more detail. They'll reach out within the next 30 minutes.`,
    clientId: `holding-${message.id}`
  });
}

// Step 6: Instant AI follow-up
async function sendInstantFollowUp(message: any, analysis: ReplyAnalysis, context: any) {
  console.log(`✅ Positive reply - sending instant follow-up to ${message.from}`);

  // Generate personalized response
  const response = await generatePersonalizedResponse(message, analysis, context);

  // Send within seconds of their reply
  await client.inboxes.messages.reply(message.inboxId, message.id, {
    body: response,
    clientId: `instant-${message.id}`
  });

  console.log(`Sent instant response to ${message.from}`);
}

async function generatePersonalizedResponse(
  message: any,
  analysis: ReplyAnalysis,
  context: any
): Promise<string> {
  const prompt = `Generate a personalized sales response:

Their reply: "${message.replyBody}"
Sentiment: ${analysis.sentiment}
Intent: ${analysis.intent}

Previous conversation:
${context.history.map(m => `${m.from}: ${m.body}`).join('\n')}

Generate a brief, engaging response that:
1. Acknowledges their interest
2. Provides value
3. Moves toward a call/demo
4. Is warm but professional`;

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

  return completion.choices[0].message.content;
}

async function provideInformation(message: any, analysis: ReplyAnalysis, context: any) {
  // Send relevant information based on their question
  const response = analysis.suggestedResponse;

  await client.inboxes.messages.reply(message.inboxId, message.id, {
    body: response,
    clientId: `info-${message.id}`
  });

  console.log(`Provided information to ${message.from}`);
}

async function sendPoliteDisengagement(message: any) {
  await client.inboxes.messages.reply(message.inboxId, message.id, {
    body: `No problem at all! Thanks for your time, and feel free to reach out if anything changes.\n\nBest of luck!`,
    clientId: `disengage-${message.id}`
  });

  console.log(`Polite disengagement sent to ${message.from}`);
}

async function getThreadContext(threadId: string) {
  const thread = await client.threads.get(threadId, {
    includeMessages: true
  });

  return {
    history: thread.messages.map(m => ({
      from: m.from,
      body: m.replyBody || m.body
    }))
  };
}

// Step 7: Real-time dashboard for operators
io.on('connection', (socket) => {
  console.log('Operator dashboard connected');

  socket.on('take_over_thread', async (data) => {
    console.log(`Human taking over thread ${data.threadId}`);

    // Pause AI responses for this thread
    // Mark thread as human-handled
  });
});

// Start real-time sales agent
async function startRealtimeSales() {
  await setupRealtimeSales();

  httpServer.listen(3000, () => {
    console.log('Real-time sales agent running on port 3000');
    console.log('Dashboard available at http://localhost:3000/dashboard');
  });
}

startRealtimeSales();
from daimon_email import DaimonClient
from openai import OpenAI
from flask import Flask, request
from flask_socketio import SocketIO, emit
import os
import time
import json
from datetime import datetime
from typing import Dict

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

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")

# Step 1: Set up real-time webhook
def setup_realtime_sales():
    inbox = client.inboxes.create(
        username='realtime-sales',
        client_id='realtime-sales-v1'
    )

    print(f"Real-time sales inbox: {inbox.address}")

    authed_client = DaimonClient(api_key=inbox.api_key)

    webhook = authed_client.webhooks.create(
        endpoint_url='https://your-sales-agent.com/webhook/instant',
        events=['message.received'],
        inbox_id=inbox.id,
        metadata={
            'priority': 'high',
            'realtime': True
        }
    )

    print('Real-time webhook registered')

    return inbox, authed_client

# Step 2: Handle instant reply notification
@app.post('/webhook/instant')
def handle_webhook():
    data = request.json

    # Acknowledge immediately
    socketio.start_background_task(process_reply, data)

    return 'OK', 200

def process_reply(data):
    event = data.get('event')
    message = data.get('message')

    if event == 'message.received':
        handle_instant_reply(message)

# Step 3: Real-time reply analysis
def handle_instant_reply(message: Dict):
    start_time = time.time()

    print(f"⚡ Instant reply from {message['from']}")

    # Broadcast to dashboards
    socketio.emit('new_reply', {
        'from': message['from'],
        'subject': message['subject'],
        'preview': message.get('reply_body', '')[:100],
        'timestamp': datetime.now().isoformat()
    })

    # Analyze reply
    analysis = analyze_reply_intent(message)
    context = get_thread_context(message['thread_id'])

    processing_time = time.time() - start_time
    print(f"Analysis complete in {processing_time*1000:.0f}ms")

    # Take action based on analysis
    if analysis['shouldEscalate']:
        escalate_to_human(message, analysis, context)
    elif analysis['intent'] == 'interested':
        send_instant_follow_up(message, analysis, context)
    elif analysis['intent'] == 'needs_info':
        provide_information(message, analysis, context)
    elif analysis['intent'] == 'not_interested':
        send_polite_disengagement(message)

    # Track metrics
    socketio.emit('reply_processed', {
        'from': message['from'],
        'processing_time': processing_time * 1000,
        'analysis': analysis,
        'action': 'escalated' if analysis['shouldEscalate'] else 'auto_responded'
    })

# Step 4: LLM-powered intent analysis
def analyze_reply_intent(message: Dict) -> Dict:
    prompt = f"""Analyze this sales email reply:

From: {message['from']}
Subject: {message['subject']}
Reply: {message.get('reply_body', '')}

Return JSON with:
{{
  "sentiment": "positive" | "neutral" | "negative",
  "intent": "interested" | "not_interested" | "needs_info" | "objection",
  "urgency": "high" | "medium" | "low",
  "shouldEscalate": true/false,
  "suggestedResponse": "brief response text"
}}

Escalate if: shows strong buying intent, mentions budget/timeline, asks for demo, or mentions competitors."""

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

    return json.loads(completion.choices[0].message.content)

# Step 5: Instant escalation to human
def escalate_to_human(message: Dict, analysis: Dict, context: Dict):
    print(f"🔥 HOT LEAD - Escalating {message['from']} to human")

    # Email notification
    client.inboxes.send(message['inbox_id'], {
        'to': 'sales-team@yourcompany.com',
        'subject': f"🔥 HOT LEAD: {message['from']}",
        'body': f"""URGENT: High-intent reply detected!

From: {message['from']}
Sentiment: {analysis['sentiment']}
Intent: {analysis['intent']}
Urgency: {analysis['urgency']}

Their reply:
"{message.get('reply_body', '')}"

Suggested response:
"{analysis['suggestedResponse']}"

Thread: https://app.daimon.email/threads/{message['thread_id']}

Take over this conversation immediately!""",
        'client_id': f"escalation-{message['id']}"
    })

    # Dashboard notification
    socketio.emit('hot_lead', {
        'from': message['from'],
        'subject': message['subject'],
        'reply': message.get('reply_body', ''),
        'analysis': analysis,
        'thread_id': message['thread_id'],
        'url': f"https://app.daimon.email/threads/{message['thread_id']}"
    })

    # Holding response
    client.inboxes.messages.reply(message['inbox_id'], message['id'], {
        'body': "Thanks for your quick response! I'm looping in our senior account executive who can answer your questions in more detail. They'll reach out within the next 30 minutes.",
        'client_id': f"holding-{message['id']}"
    })

# Step 6: Instant AI follow-up
def send_instant_follow_up(message: Dict, analysis: Dict, context: Dict):
    print(f"✅ Positive reply - sending instant follow-up to {message['from']}")

    response = generate_personalized_response(message, analysis, context)

    client.inboxes.messages.reply(message['inbox_id'], message['id'], {
        'body': response,
        'client_id': f"instant-{message['id']}"
    })

    print(f"Sent instant response to {message['from']}")

def generate_personalized_response(message: Dict, analysis: Dict, context: Dict) -> str:
    history = '\n'.join([f"{m['from']}: {m['body']}" for m in context['history']])

    prompt = f"""Generate a personalized sales response:

Their reply: "{message.get('reply_body', '')}"
Sentiment: {analysis['sentiment']}
Intent: {analysis['intent']}

Previous conversation:
{history}

Generate a brief, engaging response that:
1. Acknowledges their interest
2. Provides value
3. Moves toward a call/demo
4. Is warm but professional"""

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

    return completion.choices[0].message.content

def provide_information(message: Dict, analysis: Dict, context: Dict):
    client.inboxes.messages.reply(message['inbox_id'], message['id'], {
        'body': analysis['suggestedResponse'],
        'client_id': f"info-{message['id']}"
    })

def send_polite_disengagement(message: Dict):
    client.inboxes.messages.reply(message['inbox_id'], message['id'], {
        'body': "No problem at all! Thanks for your time, and feel free to reach out if anything changes.\n\nBest of luck!",
        'client_id': f"disengage-{message['id']}"
    })

def get_thread_context(thread_id: str) -> Dict:
    thread = client.threads.get(thread_id, include_messages=True)

    return {
        'history': [
            {'from': m['from'], 'body': m.get('reply_body') or m.get('body')}
            for m in thread['messages']
        ]
    }

# Start real-time sales agent
if __name__ == '__main__':
    setup_realtime_sales()
    socketio.run(app, port=3000)

Key Features

  • Sub-second response: Reply analysis and action within 1-2 seconds
  • Hot lead detection: Instant escalation of high-intent prospects
  • Real-time dashboard: Live feed of all replies and actions
  • Smart automation: AI handles routine responses, humans handle hot leads

Next Steps