Skip to content

Lead Capture Bot

A lead collection bot using tools to save data, with OpenRouter integration.

Features

  • 🛠️ Tool integration
  • 📧 Email extraction
  • 👤 Name extraction
  • ☁️ OpenRouter provider

Complete Code

typescript
import {
  agent,
  flow,
  FlowEngine,
  MemoryStorage,
  OpenRouterAdapter,
  Tools,
  name,
  email,
} from "@andresaya/flowkit";
import * as readline from "readline";

const assistant = agent("Lead Bot")
  .strict()
  .personality("professional")
  .build();

const leadFlow = flow("lead-capture", assistant)
  .ask("name", "Hello! What's your name?", name(), "lead_name")
  .then("email")
  .ask("email", "Thanks {{lead_name}}! What's your email?", email(), "lead_email")
  .then("save")
  .say("save", "Saving your information...")
  .do("save_lead", { name: "{{lead_name}}", email: "{{lead_email}}" })
  .then("done")
  .say("done", "All set! We'll be in touch, {{lead_name}}!")
  .done()
  .build();

async function main() {
  const adapter = new OpenRouterAdapter({
    apiKey: process.env.OPENROUTER_API_KEY!,
    model: "anthropic/claude-3-haiku",
  });

  // Register tools
  const tools = new Tools();
  tools.register("save_lead", async (payload) => {
    console.log("📝 Saving lead:", payload);
    // In a real app: await db.leads.insert(payload);
    return { success: true, id: `lead-${Date.now()}` };
  });

  const storage = new MemoryStorage();
  const engine = new FlowEngine(leadFlow, { 
    llm: adapter, 
    storage,
    tools,
    onEvent: (event) => {
      if (event.type === "tool:call") {
        console.log(`🔧 Calling tool: ${event.tool}`);
      }
      if (event.type === "tool:result") {
        console.log(`✅ Tool result:`, event.result);
      }
    }
  });

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  const sessionId = `session-${Date.now()}`;
  const startResult = await engine.start(sessionId);
  console.log(`\n🤖 Bot: ${startResult.message}\n`);

  const chat = () => {
    rl.question("👤 You: ", async (input) => {
      if (input === "exit") {
        rl.close();
        return;
      }

      const result = await engine.handle(sessionId, input);
      console.log(`\n🤖 Bot: ${result.message}\n`);

      if (result.done) {
        console.log("\n📊 Final data:", result.state.slots);
        rl.close();
        return;
      }

      chat();
    });
  };

  chat();
}

main().catch(console.error);

Sample Conversation

🤖 Bot: Hello! What's your name?

👤 You: I'm John Smith

🤖 Bot: Thanks John Smith! What's your email?

👤 You: john@example.com

🤖 Bot: Saving your information...

🔧 Calling tool: save_lead
📝 Saving lead: { name: "John Smith", email: "john@example.com" }
✅ Tool result: { success: true, id: "lead-1703123456789" }

🤖 Bot: All set! We'll be in touch, John Smith!

📊 Final data: { lead_name: "John Smith", lead_email: "john@example.com" }

Using Different Providers

You can use any provider with this example:

typescript
import { OpenAIAdapter } from "@andresaya/flowkit";

const adapter = new OpenAIAdapter({
  apiKey: process.env.OPENAI_API_KEY!,
  model: "gpt-4o-mini",
});
typescript
import { OllamaAdapter } from "@andresaya/flowkit";

const adapter = new OllamaAdapter({
  model: "qwen3:4b",
});
typescript
import { AnthropicAdapter } from "@andresaya/flowkit";

const adapter = new AnthropicAdapter({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: "claude-3-5-sonnet-20241022",
});

Advanced: Database Integration

typescript
import { Pool } from "pg";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

const tools = new Tools();

tools.register("save_lead", async (payload) => {
  const result = await pool.query(
    `INSERT INTO leads (name, email, created_at) 
     VALUES ($1, $2, NOW()) 
     RETURNING id`,
    [payload.name, payload.email]
  );
  
  return { 
    success: true, 
    id: result.rows[0].id 
  };
});

Advanced: CRM Integration

typescript
tools.register("save_lead", async (payload) => {
  // HubSpot integration
  const response = await fetch("https://api.hubapi.com/contacts/v1/contact", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.HUBSPOT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      properties: [
        { property: "firstname", value: payload.name.split(" ")[0] },
        { property: "lastname", value: payload.name.split(" ").slice(1).join(" ") },
        { property: "email", value: payload.email },
      ]
    }),
  });
  
  const data = await response.json();
  return { success: true, contactId: data.vid };
});

Released under the MIT License.