Lead Management & Qualification Workflow
Automated lead qualification workflow with AI scoring and sales officer assignment
Workflow Information
ID: lead_qualification_workflow
Namespace: default
Version: 1.0
Created: 2025-07-01
Updated: 2025-07-01
Tasks: 13
Quick Actions
Inputs
| Name | Type | Required | Default |
|---|---|---|---|
lead_id |
string | Optional |
LEAD_12345
|
Outputs
| Name | Type | Source |
|---|---|---|
officer_assignment |
object | Sales officer assignment details |
notification_status |
object | Notification delivery status |
deal_creation_result |
object | Deal creation details for qualified leads |
lead_qualification_result |
object | Final lead qualification outcome |
Tasks
get_lead_data_from_crm
scriptRetrieve lead information from CRM system
get_historical_data_from_bigquery
scriptQuery historical customer data for analysis
get_similar_leads_from_dynamics
scriptRetrieve similar leads data for benchmarking
get_sales_officer_workload
scriptCheck sales officers availability and capacity
calculate_lead_score
scriptAI-powered lead scoring based on collected data
determine_qualification_status
scriptDetermine if lead is qualified based on score
recommend_sales_officer
scriptRecommend best sales officer for qualified leads
create_deal_in_crm
scriptCreate new deal for qualified lead
update_crm_lead_status_qualified
scriptUpdate lead status to qualified in CRM
update_crm_lead_status_unqualified
scriptUpdate lead status to unqualified in CRM
log_activity_in_dynamics
scriptLog AI qualification activity in Dynamics 365
notify_sales_officer
scriptSend notification to assigned sales officer
schedule_followup
scriptSchedule follow-up actions for unqualified leads
Triggers
POST /webhook/new-lead
YAML Source
id: lead_qualification_workflow
name: Lead Management & Qualification Workflow
tasks:
- id: get_lead_data_from_crm
name: Get Lead Data from CRM
type: script
script: "#!/usr/bin/env python3\nimport json\nimport os\n\nprint(\"\U0001F50D Retrieving\
\ lead data from CRM...\")\n\n# Mock CRM API response\nlead_data = {\n \"lead_id\"\
: \"LEAD_12345\",\n \"name\": \"John Smith\",\n \"email\": \"john.smith@techcorp.com\"\
,\n \"phone\": \"+1234567890\",\n \"company\": \"TechCorp Industries\",\n\
\ \"industry\": \"Technology\",\n \"company_size\": \"500-1000\",\n \"\
inquiry_source\": \"website_form\",\n \"inquiry_details\": \"Interested in\
\ CRM solutions for 500+ employees. Looking for implementation timeline and pricing\"\
,\n \"created_at\": \"2025-06-25T14:30:00Z\",\n \"budget_range\": \"50k-100k\"\
,\n \"decision_timeline\": \"Q3_2025\",\n \"contact_level\": \"director\"\
\n}\n\nprint(f\"\u2705 Lead data retrieved: {lead_data['name']} from {lead_data['company']}\"\
)\nprint(f\" Industry: {lead_data['industry']}\")\nprint(f\" Company Size:\
\ {lead_data['company_size']}\")\nprint(f\" Budget Range: {lead_data['budget_range']}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(lead_data)}\")\n"
outputs:
- name: lead_info
value: Lead data retrieved from CRM
packages:
- requests==2.31.0
- json==2.0.9
description: Retrieve lead information from CRM system
- id: get_historical_data_from_bigquery
name: Get Historical Data from BigQuery
type: script
script: "#!/usr/bin/env python3\nimport json\n\nprint(\"\U0001F4CA Querying historical\
\ data from BigQuery...\")\n\n# Mock BigQuery response\nhistorical_data = [\n\
\ {\n \"customer_id\": \"CUST_001\",\n \"company_name\": \"Similar\
\ Tech Corp\",\n \"total_revenue\": 125000.00,\n \"engagement_score\"\
: 0.85,\n \"conversion_outcome\": \"won\",\n \"industry\": \"Technology\"\
,\n \"company_size\": \"500-1000\",\n \"sales_cycle_days\": 45\n\
\ },\n {\n \"customer_id\": \"CUST_002\", \n \"company_name\"\
: \"Tech Solutions Inc\",\n \"total_revenue\": 95000.00,\n \"engagement_score\"\
: 0.78,\n \"conversion_outcome\": \"won\",\n \"industry\": \"Technology\"\
,\n \"company_size\": \"500-1000\",\n \"sales_cycle_days\": 52\n\
\ }\n]\n\nprint(f\"\u2705 Found {len(historical_data)} similar customers\"\
)\nprint(f\" Average deal size: ${sum(c['total_revenue'] for c in historical_data)\
\ / len(historical_data):,.2f}\")\n\nprint(f\"__OUTPUTS__ {json.dumps(historical_data)}\"\
)\n"
outputs:
- name: historical_data
value: Historical customer data retrieved
packages:
- json==2.0.9
depends_on:
- get_lead_data_from_crm
description: Query historical customer data for analysis
- id: get_similar_leads_from_dynamics
name: Get Similar Leads from Dynamics
type: script
script: "#!/usr/bin/env python3\nimport json\n\nprint(\"\U0001F504 Retrieving similar\
\ leads from Dynamics 365...\")\n\n# Mock Dynamics 365 response\nsimilar_leads\
\ = {\n \"total_similar_leads\": 25,\n \"conversion_rate\": 0.68,\n \"\
average_deal_size\": 78500.00,\n \"average_sales_cycle\": 52,\n \"leads\"\
: [\n {\n \"leadid\": \"12345678-1234-1234-1234-123456789abc\"\
,\n \"companyname\": \"Enterprise Tech Solutions\",\n \"\
industry\": \"Technology\",\n \"company_size\": \"500-1000\",\n \
\ \"conversion_result\": \"won\",\n \"deal_value\": 85000.00,\n\
\ \"days_to_conversion\": 45\n }\n ],\n \"success_factors\"\
: [\n \"enterprise_focus\",\n \"technology_industry\", \n \
\ \"qualified_budget\"\n ]\n}\n\nprint(f\"\u2705 Found {similar_leads['total_similar_leads']}\
\ similar leads\")\nprint(f\" Conversion rate: {similar_leads['conversion_rate']*100:.1f}%\"\
)\nprint(f\" Average deal size: ${similar_leads['average_deal_size']:,.2f}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(similar_leads)}\")\n"
outputs:
- name: similar_leads_data
value: Similar leads data retrieved from Dynamics
packages:
- json==2.0.9
depends_on:
- get_historical_data_from_bigquery
description: Retrieve similar leads data for benchmarking
- id: get_sales_officer_workload
name: Get Sales Officer Workload
type: script
script: "#!/usr/bin/env python3\nimport json\n\nprint(\"\U0001F465 Checking sales\
\ officers workload...\")\n\n# Mock sales officers data\nofficers_workload = [\n\
\ {\n \"officer_id\": \"OFF_001\",\n \"name\": \"Sarah Johnson\"\
,\n \"active_deals\": 15,\n \"pipeline_value\": 850000.00,\n \
\ \"capacity_utilization\": 0.60,\n \"success_rate\": 0.72,\n \
\ \"specialization\": [\"technology\", \"enterprise\"],\n \"availability_score\"\
: 0.85\n },\n {\n \"officer_id\": \"OFF_002\",\n \"name\"\
: \"Mike Chen\",\n \"active_deals\": 12,\n \"pipeline_value\": 650000.00,\n\
\ \"capacity_utilization\": 0.48,\n \"success_rate\": 0.68,\n \
\ \"specialization\": [\"technology\", \"mid-market\"],\n \"availability_score\"\
: 0.92\n }\n]\n\nprint(f\"\u2705 Retrieved workload for {len(officers_workload)}\
\ sales officers\")\nfor officer in officers_workload:\n print(f\" {officer['name']}:\
\ {officer['capacity_utilization']*100:.0f}% capacity, {officer['success_rate']*100:.0f}%\
\ success rate\")\n\nprint(f\"__OUTPUTS__ {json.dumps(officers_workload)}\")\n"
outputs:
- name: officers_data
value: Sales officers workload data retrieved
packages:
- json==2.0.9
depends_on:
- get_similar_leads_from_dynamics
description: Check sales officers availability and capacity
- id: calculate_lead_score
name: Calculate Lead Score
type: script
script: "#!/usr/bin/env python3\nimport json\n\nprint(\"\U0001F916 Calculating AI\
\ lead score...\")\n\n# Mock AI scoring calculation\nlead_scoring = {\n \"\
lead_score\": 85.7,\n \"confidence_level\": 0.92,\n \"score_grade\": \"\
A\",\n \"score_percentile\": 88,\n \"scoring_breakdown\": {\n \"\
company_fit\": 22.5,\n \"intent_signals\": 20.0,\n \"contact_quality\"\
: 18.5,\n \"historical_performance\": 15.2,\n \"market_timing\"\
: 9.5\n },\n \"predictions\": {\n \"conversion_probability\": 0.73,\n\
\ \"estimated_deal_value\": 87500.00,\n \"predicted_sales_cycle\"\
: 48\n },\n \"qualification_factors\": [\n \"budget_confirmed\",\n\
\ \"authority_verified\", \n \"need_established\",\n \"timeline_defined\"\
\n ]\n}\n\nprint(f\"\u2705 Lead score calculated: {lead_scoring['lead_score']:.1f}/100\"\
)\nprint(f\" Grade: {lead_scoring['score_grade']}\")\nprint(f\" Conversion\
\ probability: {lead_scoring['predictions']['conversion_probability']*100:.0f}%\"\
)\nprint(f\" Estimated deal value: ${lead_scoring['predictions']['estimated_deal_value']:,.2f}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(lead_scoring)}\")\n"
outputs:
- name: lead_score_result
value: Lead scoring completed
packages:
- json==2.0.9
depends_on:
- get_sales_officer_workload
description: AI-powered lead scoring based on collected data
- id: determine_qualification_status
name: Determine Qualification Status
type: script
script: "#!/usr/bin/env python3\nimport json\n\nprint(\"\U0001F3AF Determining qualification\
\ status...\")\n\n# Get lead score from previous task\nlead_score = 85.7 # From\
\ calculate_lead_score task\nqualification_threshold = 70.0\n\nqualification_result\
\ = {\n \"is_qualified\": lead_score >= qualification_threshold,\n \"qualification_status\"\
: \"qualified\" if lead_score >= qualification_threshold else \"unqualified\"\
,\n \"threshold_used\": qualification_threshold,\n \"score_achieved\": lead_score,\n\
\ \"qualification_confidence\": 0.92,\n \"qualification_reasons\": [\n \
\ \"Score exceeds threshold\",\n \"Strong budget indicators\",\n\
\ \"Clear timeline established\",\n \"Decision authority confirmed\"\
\n ]\n}\n\nstatus = qualification_result[\"qualification_status\"]\nprint(f\"\
\u2705 Qualification determined: {status.upper()}\")\nprint(f\" Score: {lead_score:.1f}\
\ (Threshold: {qualification_threshold})\")\nprint(f\" Confidence: {qualification_result['qualification_confidence']*100:.0f}%\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(qualification_result)}\")\n"
outputs:
- name: qualification_result
value: Qualification status determined
packages:
- json==2.0.9
depends_on:
- calculate_lead_score
description: Determine if lead is qualified based on score
- id: recommend_sales_officer
name: Recommend Sales Officer
type: script
script: "#!/usr/bin/env python3\nimport json\n\nprint(\"\U0001F464 Recommending\
\ sales officer assignment...\")\n\n# Mock recommendation logic\nrecommendation\
\ = {\n \"recommended_officer\": \"OFF_002\",\n \"officer_name\": \"Mike\
\ Chen\",\n \"match_confidence\": 0.89,\n \"assignment_reasons\": [\n \
\ \"Lower current workload (48% vs 60%)\",\n \"Technology specialization\
\ match\",\n \"Higher availability score (92%)\",\n \"Good success\
\ rate (68%)\"\n ],\n \"match_score\": 87.5,\n \"expected_performance\"\
: {\n \"success_probability\": 0.71,\n \"estimated_close_timeline\"\
: \"45-52 days\"\n }\n}\n\nprint(f\"\u2705 Recommended officer: {recommendation['officer_name']}\"\
)\nprint(f\" Match confidence: {recommendation['match_confidence']*100:.0f}%\"\
)\nprint(f\" Assignment reasons: {', '.join(recommendation['assignment_reasons'][:2])}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(recommendation)}\")\n"
outputs:
- name: officer_recommendation
value: Sales officer recommendation completed
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == true
depends_on:
- determine_qualification_status
description: Recommend best sales officer for qualified leads
- id: create_deal_in_crm
name: Create Deal in CRM
type: script
script: "#!/usr/bin/env python3\nimport json\nfrom datetime import datetime, timedelta\n\
\nprint(\"\U0001F4BC Creating deal in CRM...\")\n\n# Mock deal creation\ndeal_data\
\ = {\n \"deal_id\": \"DEAL_2025_001234\",\n \"lead_id\": \"LEAD_12345\"\
,\n \"customer_name\": \"TechCorp Industries\",\n \"deal_name\": \"TechCorp\
\ CRM Implementation\",\n \"estimated_value\": 87500.00,\n \"probability\"\
: 0.73,\n \"expected_close_date\": \"2025-08-15\",\n \"assigned_officer\"\
: \"OFF_002\",\n \"deal_stage\": \"qualified\",\n \"created_at\": datetime.now().isoformat(),\n\
\ \"ai_generated\": True,\n \"source\": \"ai_qualification\"\n}\n\nprint(f\"\
\u2705 Deal created: {deal_data['deal_name']}\")\nprint(f\" Deal ID: {deal_data['deal_id']}\"\
)\nprint(f\" Value: ${deal_data['estimated_value']:,.2f}\")\nprint(f\" Assigned\
\ to: {deal_data['assigned_officer']}\")\n\nprint(f\"__OUTPUTS__ {json.dumps(deal_data)}\"\
)\n"
outputs:
- name: deal_created
value: Deal created in CRM
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == true
depends_on:
- recommend_sales_officer
description: Create new deal for qualified lead
- id: update_crm_lead_status_qualified
name: Update CRM Lead Status - Qualified
type: script
script: "#!/usr/bin/env python3\nimport json\nfrom datetime import datetime\n\n\
print(\"\u2705 Updating lead status to QUALIFIED...\")\n\n# Mock CRM update\n\
update_result = {\n \"lead_id\": \"LEAD_12345\",\n \"previous_status\":\
\ \"new\",\n \"new_status\": \"qualified\",\n \"updated_at\": datetime.now().isoformat(),\n\
\ \"updated_by\": \"ai_agent\",\n \"score\": 85.7,\n \"assigned_officer\"\
: \"OFF_002\",\n \"next_actions\": [\n {\n \"action\": \"\
schedule_discovery_call\",\n \"due_date\": \"2025-06-27T10:00:00Z\"\
,\n \"priority\": \"high\"\n }\n ]\n}\n\nprint(f\"\u2705\
\ Lead status updated to: {update_result['new_status'].upper()}\")\nprint(f\"\
\ Score: {update_result['score']}\")\nprint(f\" Assigned to: {update_result['assigned_officer']}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(update_result)}\")\n"
outputs:
- name: lead_update_qualified
value: Lead status updated to qualified
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == true
depends_on:
- create_deal_in_crm
description: Update lead status to qualified in CRM
- id: update_crm_lead_status_unqualified
name: Update CRM Lead Status - Unqualified
type: script
script: "#!/usr/bin/env python3\nimport json\nfrom datetime import datetime\n\n\
print(\"\u274C Updating lead status to UNQUALIFIED...\")\n\n# Mock CRM update\
\ for unqualified lead\nupdate_result = {\n \"lead_id\": \"LEAD_12345\",\n\
\ \"previous_status\": \"new\",\n \"new_status\": \"unqualified\",\n \
\ \"updated_at\": datetime.now().isoformat(),\n \"updated_by\": \"ai_agent\"\
,\n \"score\": 45.2, # Mock low score\n \"unqualification_reasons\": [\n\
\ \"Score below threshold\",\n \"Budget not confirmed\",\n \
\ \"No clear timeline\"\n ],\n \"recommended_actions\": [\n \"\
nurture_campaign\",\n \"follow_up_in_90_days\"\n ]\n}\n\nprint(f\"\u274C\
\ Lead status updated to: {update_result['new_status'].upper()}\")\nprint(f\"\
\ Score: {update_result['score']}\")\nprint(f\" Reasons: {', '.join(update_result['unqualification_reasons'])}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(update_result)}\")\n"
outputs:
- name: lead_update_unqualified
value: Lead status updated to unqualified
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == false
depends_on:
- determine_qualification_status
description: Update lead status to unqualified in CRM
- id: log_activity_in_dynamics
name: Log Activity in Dynamics
type: script
script: "#!/usr/bin/env python3\nimport json\nfrom datetime import datetime\n\n\
print(\"\U0001F4DD Logging activity in Dynamics 365...\")\n\n# Mock Dynamics activity\
\ creation\nactivity_result = {\n \"activity_id\": \"99887766-5544-3322-1100-ffeeddccbbaa\"\
,\n \"subject\": \"AI Lead Qualification Completed\",\n \"regardingobjectid\"\
: \"12345678-1234-1234-1234-123456789abc\",\n \"activity_type\": \"ai_qualification\"\
,\n \"created_at\": datetime.now().isoformat(),\n \"ai_confidence_score\"\
: 0.92,\n \"qualification_score\": 85.7,\n \"processing_time_seconds\":\
\ 12.5,\n \"qualification_factors\": [\n \"budget_verified\",\n \
\ \"authority_confirmed\", \n \"need_established\"\n ],\n \"next_steps\"\
: [\n \"schedule_discovery_call\",\n \"send_welcome_email\"\n \
\ ]\n}\n\nprint(f\"\u2705 Activity logged in Dynamics 365\")\nprint(f\" Activity\
\ ID: {activity_result['activity_id']}\")\nprint(f\" Subject: {activity_result['subject']}\"\
)\nprint(f\" AI Confidence: {activity_result['ai_confidence_score']*100:.0f}%\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(activity_result)}\")\n"
outputs:
- name: dynamics_activity
value: Activity logged in Dynamics 365
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == true
depends_on:
- update_crm_lead_status_qualified
description: Log AI qualification activity in Dynamics 365
- id: notify_sales_officer
name: Notify Sales Officer
type: script
script: "#!/usr/bin/env python3\nimport json\nfrom datetime import datetime\n\n\
print(\"\U0001F514 Sending notification to sales officer...\")\n\n# Mock notification\n\
notification_result = {\n \"notification_id\": \"NOTIF_2025_009876\",\n \
\ \"recipient_id\": \"OFF_002\",\n \"recipient_name\": \"Mike Chen\",\n \
\ \"notification_type\": \"lead_assignment\",\n \"priority\": \"high\",\n \
\ \"sent_at\": datetime.now().isoformat(),\n \"channels_used\": [\"email\"\
, \"slack\", \"push\"],\n \"message\": \"New qualified lead assigned - TechCorp\
\ Industries. Score: 85.7/100, Value: $87,500\",\n \"action_buttons\": [\n\
\ \"View Lead Details\",\n \"Schedule Call\"\n ],\n \"delivery_status\"\
: {\n \"email\": \"delivered\",\n \"slack\": \"delivered\", \n \
\ \"push\": \"delivered\"\n }\n}\n\nprint(f\"\u2705 Notification sent\
\ to {notification_result['recipient_name']}\")\nprint(f\" Channels: {', '.join(notification_result['channels_used'])}\"\
)\nprint(f\" Priority: {notification_result['priority'].upper()}\")\n\nprint(f\"\
__OUTPUTS__ {json.dumps(notification_result)}\")\n"
outputs:
- name: notification_sent
value: Sales officer notification sent
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == true
depends_on:
- log_activity_in_dynamics
description: Send notification to assigned sales officer
- id: schedule_followup
name: Schedule Follow-up
type: script
script: "#!/usr/bin/env python3\nimport json\nfrom datetime import datetime, timedelta\n\
\nprint(\"\U0001F4C5 Scheduling follow-up for unqualified lead...\")\n\n# Mock\
\ follow-up scheduling\nfollowup_result = {\n \"task_id\": \"TASK_2025_012345\"\
,\n \"lead_id\": \"LEAD_12345\",\n \"task_type\": \"nurture_followup\",\n\
\ \"scheduled_for\": (datetime.now() + timedelta(days=90)).isoformat(),\n \
\ \"actions\": [\n {\n \"action\": \"send_nurture_email\"\
,\n \"scheduled_date\": (datetime.now() + timedelta(days=30)).isoformat()\n\
\ },\n {\n \"action\": \"qualification_retry\",\n \
\ \"scheduled_date\": (datetime.now() + timedelta(days=90)).isoformat()\n\
\ }\n ],\n \"campaign_type\": \"unqualified_nurture\",\n \"expected_outcome\"\
: \"re_evaluation\"\n}\n\nprint(f\"\u2705 Follow-up scheduled for unqualified\
\ lead\")\nprint(f\" Next action: {followup_result['actions'][0]['action']}\"\
)\nprint(f\" Scheduled for: {followup_result['actions'][0]['scheduled_date']}\"\
)\n\nprint(f\"__OUTPUTS__ {json.dumps(followup_result)}\")\n"
outputs:
- name: followup_scheduled
value: Follow-up scheduled for unqualified lead
packages:
- json==2.0.9
condition: ${qualification_result.is_qualified} == false
depends_on:
- update_crm_lead_status_unqualified
description: Schedule follow-up actions for unqualified leads
inputs:
- name: lead_id
type: string
default: LEAD_12345
description: Lead ID from CRM webhook
outputs:
officer_assignment:
type: object
source: recommend_sales_officer
description: Sales officer assignment details
notification_status:
type: object
source: notify_sales_officer
description: Notification delivery status
deal_creation_result:
type: object
source: create_deal_in_crm
description: Deal creation details for qualified leads
lead_qualification_result:
type: object
source: determine_qualification_status
description: Final lead qualification outcome
version: '1.0'
triggers:
- name: New Lead Created
path: /webhook/new-lead
type: webhook
config:
method: POST
headers:
- name: Content-Type
value: application/json
required: true
authentication: none
description: Triggered when new lead is created in CRM
input_mapping:
- webhook_field: lead_id
workflow_input: lead_id
- name: Manual Lead Qualification
type: manual
description: Manually trigger lead qualification process
description: Automated lead qualification workflow with AI scoring and sales officer
assignment