AI lead qualification
This workflow scores a lead as soon as it is submitted via the form, records qualified leads in Snowflake and notifies the salesperson by email.
Loading the diagram…
The need
Every lead submitted via the form must be qualified to know whether it deserves the salesperson's attention. An AI agent scores it automatically: qualified leads are recorded in Snowflake and the salesperson is notified by email, the others are published as unqualified on a Google Pub/Sub topic consumed by the CRM.
What the workflow does
- New lead (form) — the Trigger node captures the form submission (
triggerIdform.submitted). The lead data arrives indata. - Score the lead (AI) — the AI Agent node evaluates the lead with the
gemini-1.5-promodel (structured output). The score is stored incontext.agentOutput.answer.score. - Score ≥ 60? — the Condition node routes the lead according to its score.
- Record the qualified lead — if the score is high enough, the Snowflake node inserts the lead in the
leads_qualifiestable. - Notify the salesperson — the Send an email node sends the result to the sales team.
- Publish the unqualified lead (CRM) — otherwise, the Send Google Pub/Sub node publishes
lead_rejectedon the CRM's Pub/Sub topic.
What you need
- A Trigger node that captures the form submission (
triggerIdform.submitted). - The AI Agent node (
gemini-1.5-promodel), the Condition node, the Snowflake node, the Send an email node and the Send Google Pub/Sub node. - The
leads_qualifiesSnowflake table and the CRM's Pub/Sub topic that receiveslead_rejected.
Construction
Copy the workflow definition and paste it into the editor (the Trigger node is recreated automatically, it is not in the snippet):
[
{
"id": "agent-103",
"name": "Score the lead (AI)",
"config": {
"type": "AGENT",
"model": {
"provider": "GEMINI",
"name": "gemini-1.5-pro"
},
"systemPrompt": "You score B2B leads from 0 to 100, with a score field and a summary.",
"message": "Here are the lead details: {{ data.company }}",
"outputKey": "agentOutput",
"responseFormat": "{\"type\": \"object\", \"properties\": {\"score\": {\"type\": \"number\", \"minimum\": 0, \"maximum\": 100}, \"synthesis\": {\"type\": \"string\"}}, \"required\": [\"score\", \"synthesis\"]}",
"tools": []
},
"parents": [
"trigger"
],
"position": {
"x": 0,
"y": 200
},
"next": "cond-103"
},
{
"id": "cond-103",
"name": "Score ≥ 60?",
"config": {
"type": "CONDITION",
"conditionCode": "return context.agentOutput.answer.score >= 60;",
"conditions": [
{
"value": true,
"next": "db-103"
},
{
"value": false,
"next": "event-103"
}
]
},
"parents": [
"agent-103"
],
"position": {
"x": 0,
"y": 400
}
},
{
"id": "db-103",
"name": "Record the qualified lead",
"config": {
"type": "DATABASE_SNOWFLAKE",
"query": "INSERT INTO leads_qualifies (company, score) SELECT '{{ data.company }}', {{ context.agentOutput.answer.score }}",
"outputKey": "snowflakeResult"
},
"parents": [
"cond-103"
],
"position": {
"x": 0,
"y": 600
},
"next": "email-103"
},
{
"id": "email-103",
"name": "Notify the salesperson",
"config": {
"type": "SEND_EMAIL",
"to": [
"ventes@agence-leads.fr"
],
"subject": "New scored lead: {{ data.company }}",
"content": "AI score: {{ context.agentOutput.answer.score }}",
"sendAsHtml": true
},
"parents": [
"db-103"
],
"position": {
"x": 0,
"y": 800
}
},
{
"id": "event-103",
"name": "Publish the unqualified lead (CRM)",
"config": {
"type": "SEND_EVENT",
"provider": {
"type": "GCP_PUBSUB",
"projectId": "mon-projet-crm",
"topicId": "leads"
},
"body": "{\"event\": \"lead_rejected\", \"company\": \"{{ data.company }}\"}"
},
"parents": [
"cond-103"
],
"position": {
"x": 800,
"y": 600
}
}
]
Check that it works
- Expected data: the agent message references
{{ data.company }}— make sure the trigger payload actually exposes this data. The score is read from the agent's output key (defaultcontext.agentOutput); the condition and the email usecontext.agentOutput.answer.score. - Deploy the workflow (Deploy a workflow), then trigger the real scenario: every execution generates a trace you can view (View traces).
Variations
- If you change the agent's output key, update all the references that use it (condition and email).
- The structured output forces the agent to return a reliable JSON object (
score, summary) usable by the condition; without it, the agent's response is plain text. - Without a configured tool, the AI Agent node behaves in conversational mode: it answers but does not trigger external calls.
Going further
See also: Examples and integrations