DEV Community

ahmad rabbani
ahmad rabbani

Posted on

The Actual Lead Generation System using OpenClaw

OpenClaw Challenge Submission 🦞

I built a lead generation system that can simulate and verify AI outreach without sending a single real email.

While building an AI outreach workflow for Play2Earn Sports, a Canada-based sports platform, I ran into a familiar problem: it is easy to demo an AI feature once, and much harder to prove it actually works inside a real backend flow.

So instead of stopping at β€œthe prompt looks good,” I added a dedicated Laravel seeder that creates synthetic global club leads and runs them through the same OpenClaw drafting path the production app uses.
That turned the feature from a demo into something I could verify.
πŸ› οΈ Build This Yourself
To reproduce this workflow:

Install OpenClaw and make sure the gateway is running locally.
Add a small Node.js proxy that exposes /v1/chat/completions.
In Laravel, send club lead data as a structured prompt.
Ask OpenClaw to return JSON with subject and body.
Save the draft back to the lead record.
Store draft_provider in metadata so you can verify the source.
Sample prompt
System:
Write a concise, professional cold outreach email for a sports club.
Return valid JSON only with subject and body.

User:
Business: Play2Earn Sports
Business location: Canada
Club name: Toronto Falcons Football Academy
Sport: football
City: Toronto
Country: Canada
Booking link: https://play2earn.example/outreach/book/demo-token-123
Sample curl

curl -X POST http://127.0.0.1:3000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openclaw-local",
    "messages": [
      {
        "role": "system",
        "content": "Write a concise, professional cold outreach email for a sports club. Return valid JSON only with subject and body."
      },
      {
        "role": "user",
        "content": "Business: Play2Earn Sports\nBusiness location: Canada\nClub name: Toronto Falcons Football Academy\nSport: football\nCity: Toronto\nCountry: Canada\nBooking link: https://play2earn.example/outreach/book/demo-token-123"
      }
    ]
  }'
Enter fullscreen mode Exit fullscreen mode

Expected response

{
  "choices": [
    {
      "message": {
        "content": "{\"subject\":\"Partnership Opportunity...\",\"body\":\"Hi Toronto Falcons Football Academy team...\"}"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Sample Laravel save flow

$rawContent = $response['choices'][0]['message']['content'] ?? null;
$draft = json_decode($rawContent, true);

$lead->update([
    'email_subject' => $draft['subject'] ?? null,
    'email_body' => $draft['body'] ?? null,
    'status' => 'draft_ready',
    'metadata' => [
        'draft_provider' => 'openclaw',
    ],
]);

Enter fullscreen mode Exit fullscreen mode

That last part is important. Storing draft_provider made the OpenClaw integration verifiable, especially when running the seeded demo leads through the real draft pipeline.

**The Workflow
The outreach module helps admins:

discover sports clubs
store public business contact info
generate personalized outreach drafts
approve or reject leads
log emails
offer demo booking links
automate follow-ups
OpenClaw is used for one narrow but important part: generating the initial outreach draft.

**The Architecture
**The path looks like this:


Laravel talks to an OpenAI-style HTTP endpoint, and the proxy bridges that into the OpenClaw side.

That kept the application code simple and gave me a clean provider boundary.

Why the Seeder Matters
The most useful part of this integration was not the prompt. It was the seeder.

I created AiOutreachDemoSeeder to:
seed global synthetic clubs from Canada, the UK, Australia, and South Africa
create outreach settings and demo slots
generate drafts through the real EmailCampaignService -> AiEmailService path
create visible admin data for approved, emailed, and demo-booked leads
That means I can test the full workflow without touching real contacts.

The Important Detail: Verifiability
Each generated draft stores its source in lead metadata using draft_provider.

So after seeding, I can tell whether a lead was drafted by:

openclaw
openai
template
That one field made the integration much easier to trust.

If OpenClaw fails and the app falls back, I do not have to guess. The record tells me.

Why This Is Better Than Fake Sample Content
A lot of teams seed nice-looking AI output directly into the database.

I did not want that.

I wanted the seed to exercise the real application path, because that proves more than formatting. It proves:

config is wired
prompt settings are loaded
provider calls are working
results are saved correctly
admin screens reflect the real state
That is a much more honest test.

What I Learned
A few things became clear very quickly.

First, AI features need observability more than they need hype.

Second, backend workflows are where a lot of AI work becomes real. The interesting part is not β€œcan the model answer?” It is β€œcan the system show what happened?”

Third, OpenClaw felt most useful when treated as an infrastructure component, not just a chat interface.

The Reproducible Flow
The workflow is now simple:

configure the OpenClaw endpoint
run migrations
seed the outreach demo data
open the admin outreach dashboard
inspect lead status, email logs, and draft_provider
That makes verification repeatable for anyone on the team.

Closing Thought
The best part of this build was not the generated email. It was making the AI layer testable inside the product.

That changed my view of AI integration a bit: a useful AI feature is not just one that produces output. It is one that another developer can verify without guesswork.

For this project, the seeder ended up being just as important as the model call.

ClawCon Michigan
I like that this challenge pushes people to share practical OpenClaw workflows, not just screenshots of prompts. That is where the real engineering lessons are.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.