@thierryteisseire/leadgenius-skill 1.0.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.txt CHANGED
File without changes
package/README.md CHANGED
File without changes
package/SKILL.md CHANGED
@@ -10,9 +10,10 @@ This skill provides a comprehensive interface for interacting with the LeadGeniu
10
10
  ## Core Workflows
11
11
 
12
12
  ### 1. Lead Management
13
- - **Find Leads**: Use `GET /leads` to list contacts.
14
- - **Enrich Leads**: Use `POST /enrichment/trigger` to start AI augmentation.
13
+ - **Bulk List (EnrichLeads)**: Use `GET /enrich-leads/list` for high-volume data extraction from the enriched leads table (requires Amplify API key).
14
+ - **Bulk List (SourceLeads)**: Use `GET /source-leads/list` for raw source data extraction (requires Amplify API key).
15
15
  - **Update Status**: Use `PUT /leads/{id}/status` to track progress (New -> Qualified -> Contacted).
16
+ - **Batch Operations**: Create or delete multiple leads simultaneously with `POST /leads/batch` or `DELETE /leads/batch`.
16
17
 
17
18
  ### 2. Campaign Operations
18
19
  - **Overview**: List all active ABM campaigns with `GET /campaigns`.
@@ -23,27 +24,157 @@ This skill provides a comprehensive interface for interacting with the LeadGeniu
23
24
  - **Account Lists**: Manage high-value targets with `GET /target-accounts`.
24
25
  - **Scoring**: Update account intent and fit scores with `PUT /target-accounts/{id}/score`.
25
26
 
27
+ ### 4. Outreach & Engagement
28
+ - **Sequences**: List communication sequences with `GET /sequences`.
29
+ - **Enrollment**: Enroll leads into a specific sequence with `POST /sequences/{id}/enroll`.
30
+
31
+ ### 5. Automation & Workflows
32
+ - **Custom Workflows**: Manage automated processes and agent handoffs with `GET /workflows`.
33
+ - **Status Jobs**: Monitor long-running processes (like enrichment or exports) with `GET /enrichment/status/{jobId}`.
34
+
35
+ ### 6. Analytics & Insights
36
+ - **Pipeline Health**: Total visibility into conversion rates and pipeline velocity with `GET /analytics/pipeline`.
37
+
38
+ ### 7. Maintenance & System Health
39
+ - **Bug Reporting**: Use `POST /maintenance/bugs` to report issues discovered by agents.
40
+ - **Enhancement Requests**: Use `POST /maintenance/enhancements` to suggest features.
41
+
42
+ ### 8. Master Administration
43
+ - **Global Visibility**: List all companies and users across the platform (Admin only).
44
+ - **API Key Management**: Generate and rotate API keys for agent access.
45
+
26
46
  ## Technical Reference
27
47
 
28
- ### Base URL
29
- All requests are relative to: `/api/agent` (e.g. `https://your-domain.com/api/agent/leads`)
48
+ ### Base URLs
49
+ The API uses separate root paths depending on the operation scope. Standard agent interaction occurs via the **Agent Scope**, while high-volume extraction uses the **System Scope**.
50
+
51
+ 1. **Agent API Operations**: `/api/agent` (e.g., `https://last.leadgenius.app/api/agent/leads`). Requires `X-API-Key` (lgp_...).
52
+ 2. **Bulk Data Extraction (System Scope)**: `/api` (e.g., `https://last.leadgenius.app/api/enrich-leads/list`). Requires `x-api-key` (Amplify API key).
53
+ 3. **Admin Scope**: `/api/admin` (e.g., `.../api/admin/companies`).
54
+
55
+ ### Unified CLI (lgp.py)
56
+ The primary way to interact with LeadGenius is via the `lgp` CLI tool.
57
+
58
+ #### 1. Setup & Auth
59
+ ```bash
60
+ python3 scripts/lgp.py auth --email your@email.com
61
+ ```
62
+
63
+ #### 2. Manage Leads
64
+ ```bash
65
+ # List leads
66
+ python3 scripts/lgp.py leads list
67
+
68
+ # Find specific leads
69
+ python3 scripts/lgp.py leads find --full-name "Hugo Sanchez"
70
+
71
+ # Enrich specific leads
72
+ python3 scripts/lgp.py leads enrich --ids lead_1 lead_2
73
+ ```
74
+
75
+ #### 3. Manage Campaigns
76
+ ```bash
77
+ # List active campaigns
78
+ python3 scripts/lgp.py campaigns list
79
+
80
+ # Create a new campaign
81
+ python3 scripts/lgp.py campaigns create --name "Q3 Expansion"
82
+ ```
83
+
84
+ #### 4. Insights & Analytics
85
+ ```bash
86
+ # Show pipeline health for a specific period
87
+ python3 scripts/lgp.py pipeline --start 2026-01-01 --end 2026-02-08
88
+ ```
89
+
90
+ #### 5. Maintenance & Support
91
+ ```bash
92
+ # List and report bugs
93
+ python3 scripts/lgp.py maintenance bugs list
94
+ python3 scripts/lgp.py maintenance bugs report --desc "Enrichment fails on LinkedIn URLs"
95
+
96
+ # List and request enhancements
97
+ python3 scripts/lgp.py maintenance enhancements list
98
+ python3 scripts/lgp.py maintenance enhancements request --desc "Add support for Google Maps leads"
99
+ ```
100
+
101
+ #### 6. API Key Generation
102
+ ```bash
103
+ # Generate a new API Key (Requires active session)
104
+ python3 scripts/lgp.py generate-key --name "Production Agent" --desc "Key for main auto-agent"
105
+ ```
30
106
 
31
- ### Authentication
32
- Include your API key in the headers:
33
- ```http
34
- X-API-Key: lgp_your_secret_key
35
- # OR
36
- Authorization: Bearer lgp_your_secret_key
107
+ #### 7. Global Administration (Admin Only)
108
+ ```bash
109
+ # View system-wide data
110
+ python3 scripts/lgp.py admin companies
111
+ python3 scripts/lgp.py admin users
37
112
  ```
38
113
 
39
114
  ### Reference Material
40
- - **OpenAPI Spec**: See [openapi.json](references/openapi.json) for a full list of endpoints, parameters, and schemas.
41
- - **Documentation**: A detailed HTML guide is available at `/api/agent/docs`.
115
+ - **API Reference**: See [api_reference.md](references/api_reference.md) for detailed endpoint descriptions.
116
+ - **OpenAPI Spec**: See [openapi.json](references/openapi.json) for machine-readable schemas.
42
117
 
43
118
  ### Helper Scripts
44
- Use [scripts/api_call.py](scripts/api_call.py) to make authenticated requests from the command line.
119
+ - **[scripts/lgp.py](scripts/lgp.py)**: Unified CLI for all common operations.
120
+ - **[scripts/api_call.py](scripts/api_call.py)**: Low-level utility for custom raw API requests.
121
+ - **[scripts/auth.py](scripts/auth.py)**: Standalone auth utility.
122
+
123
+
124
+
125
+ ## Common Payloads
126
+
127
+ ### Create Campaign
128
+ ```json
129
+ {
130
+ "name": "Q1 ABM Tech Giants",
131
+ "description": "Targeting top 50 tech firms for SaaS expansion",
132
+ "campaignType": "abm",
133
+ "status": "active"
134
+ }
135
+ ```
136
+
137
+ ### Enrich Leads
138
+ ```json
139
+ {
140
+ "leadIds": ["lead_123", "lead_456"],
141
+ "enrichmentType": "technographic",
142
+ "priority": "high"
143
+ }
144
+ ```
145
+
146
+ ## Quick Start
147
+ To test your connection:
148
+ 1. Set your API Key: `export LGP_API_KEY=lgp_your_key`
149
+ 2. Fetch campaigns:
150
+ ```bash
151
+ python3 scripts/api_call.py GET /campaigns
152
+ ```
153
+
154
+
155
+ ## Data Architecture & Logic
156
+ ### 1. Multi-Tenant Isolation
157
+ All data is strictly isolated by `company_id`. Even though agents use their own API keys, the system enforces that they only see leads associated with their assigned `company_id`.
158
+
159
+ ### 2. Search Logic (LeadService)
160
+ The standard lead listing (`GET /leads`) uses a dual-query strategy to ensure no leads are missed:
161
+ - **By Company**: Queries the `company_id-GSI` to find all company-level leads.
162
+ - **By Owner**: Queries the `owner-GSI` to find leads specifically created by/assigned to the agent.
163
+ - **Merging**: Results are deduplicated and merged to provide a unified view.
164
+
165
+ ### 3. Bulk Data Access
166
+ High-volume extraction (`GET /enrich-leads/list`) bypasses standard CRM logic in favor of raw GSI performance, requiring an explicit `companyId` parameter and matching Amplify API key.
167
+
168
+ ### 4. Guardrails & Limits
169
+ - **Rate Limits**:
170
+ - **Minute**: 60 requests.
171
+ - **Hour**: 1,000 requests.
172
+ - **Day**: 10,000 requests.
173
+ - **Batching**:
174
+ - **Lead Creation**: Max 100 leads per request.
175
+ - **Enrichment Trigger**: Max 500 leads per request.
176
+ - **Pagination**:
177
+ - **Standard API**: Default 20, Max 100 per page.
178
+ - **Bulk API**: Default 1,000, Max 5,000 per page.
179
+ - **Search Depth**: LeadService scans up to 1,000 records per GSI before in-memory merging.
45
180
 
46
- ## Guardrails
47
- - **Rate Limits**: Default limit is 60 requests per minute.
48
- - **Batching**: Limit batch lead creation to 100 per request.
49
- - **Permissions**: Ensure your API key has the required scope (Read/Write/Admin).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thierryteisseire/leadgenius-skill",
3
- "version": "1.0.0",
3
+ "version": "1.1.2",
4
4
  "description": "LeadGenius Pro Agent API Skill for AI agents",
5
5
  "main": "SKILL.md",
6
6
  "repository": {
@@ -27,4 +27,4 @@
27
27
  "LICENSE.txt",
28
28
  "README.md"
29
29
  ]
30
- }
30
+ }
@@ -10,6 +10,11 @@ All requests require an API key passed in headers:
10
10
  - `X-API-Key: lgp_...`
11
11
  - OR `Authorization: Bearer lgp_...`
12
12
 
13
+ **Global Throttles**:
14
+ - 60 requests/minute
15
+ - 1,000 requests/hour
16
+ - 10,000 requests/day
17
+
13
18
  ---
14
19
 
15
20
  ## 📊 Campaigns
@@ -17,7 +22,7 @@ Manage ABM campaigns and track performance.
17
22
 
18
23
  ### `GET /campaigns`
19
24
  List all campaigns.
20
- - **Query Params**: `page`, `pageSize`, `status`, `campaignType`.
25
+ - **Query Params**: `page`, `pageSize` (Max 100), `status`, `campaignType`.
21
26
 
22
27
  ### `POST /campaigns`
23
28
  Create a new campaign.
@@ -36,7 +41,8 @@ Lifecycle management for marketing and sales leads.
36
41
 
37
42
  ### `GET /leads`
38
43
  List leads with advanced filtering.
39
- - **Filters**: `status`, `campaignId`, `email`, `companyName`.
44
+ - **Filters**: `status`, `campaignId`, `email`, `companyName`, `firstName`, `lastName`, `fullName`.
45
+ - **Pagination**: `page`, `pageSize` (Default 20, Max 100).
40
46
 
41
47
  ### `POST /leads`
42
48
  Create a single lead.
@@ -50,6 +56,25 @@ Transition a lead status (e.g., `new` -> `qualified`).
50
56
 
51
57
  ---
52
58
 
59
+ ## 📋 Bulk Lead Listing (External Access)
60
+ Direct lead listing endpoints using Amplify API key auth. Use these for high-volume data retrieval without Cognito sessions.
61
+
62
+ **Base URL:** `https://your-domain.com/api` (not `/api/agent`)
63
+
64
+ **Authentication:** `x-api-key` header with the Amplify API key (from `amplify_outputs.json`).
65
+
66
+ ### `GET /enrich-leads/list`
67
+ Bulk list enriched leads by company.
68
+ - **Required**: `companyId` — company_id for multi-tenant isolation.
69
+ - **Optional**: `clientId`, `limit` (default 1000, max 5000), `nextToken`, `fields` (comma-separated).
70
+ - **Query Strategy**: Uses `company_id` GSI or `client_id` GSI + company filter.
71
+ - **Response**: `{ success, data, nextToken, meta: { totalReturned, queryMethod, clientSummary, ... } }`
72
+
73
+ ### `GET /source-leads/list`
74
+ Bulk list source leads by company. Same parameters and response shape as `/enrich-leads/list`.
75
+
76
+ ---
77
+
53
78
  ## ✨ Enrichment
54
79
  Trigger AI-powered data augmentation.
55
80
 
File without changes
@@ -15,9 +15,26 @@ def main():
15
15
 
16
16
  args = parser.parse_args()
17
17
 
18
+ # Authentication resolution order:
19
+ # 1. --key argument
20
+ # 2. LGP_API_KEY environment variable
21
+ # 3. Saved credentials in ~/.leadgenius_auth.json
18
22
  api_key = args.key or os.environ.get("LGP_API_KEY")
23
+
19
24
  if not api_key:
20
- print("Error: API Key is required. Use --key or set LGP_API_KEY environment variable.")
25
+ auth_file = os.path.expanduser("~/.leadgenius_auth.json")
26
+ if os.path.exists(auth_file):
27
+ try:
28
+ with open(auth_file, "r") as f:
29
+ auth_data = json.load(f)
30
+ api_key = auth_data.get("token")
31
+ if api_key:
32
+ print(f"Using saved credentials for {auth_data.get('email', 'unknown user')}")
33
+ except Exception as e:
34
+ print(f"Warning: Failed to read saved credentials: {e}")
35
+
36
+ if not api_key:
37
+ print("Error: API Key is required. Run 'python3 scripts/auth.py' first, use --key, or set LGP_API_KEY.")
21
38
  sys.exit(1)
22
39
 
23
40
  url = f"{args.base_url.rstrip('/')}/{args.endpoint.lstrip('/')}"
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ import json
4
+ import os
5
+ import requests
6
+ import sys
7
+ from getpass import getpass
8
+
9
+ DEFAULT_BASE_URL = "http://localhost:3000"
10
+ AUTH_FILE = os.path.expanduser("~/.leadgenius_auth.json")
11
+
12
+ def main():
13
+ parser = argparse.ArgumentParser(description="Authenticate with LeadGenius Pro/EpsimoAI")
14
+ parser.add_argument("--email", help="User email")
15
+ parser.add_argument("--password", help="User password")
16
+ parser.add_argument("--base-url", default=DEFAULT_BASE_URL, help=f"Application base URL (default: {DEFAULT_BASE_URL})")
17
+ parser.add_argument("--save", action="store_true", default=True, help="Save credentials (default: True)")
18
+
19
+ args = parser.parse_args()
20
+
21
+ email = args.email or input("Email: ")
22
+ password = args.password or getpass("Password: ")
23
+
24
+ url = f"{args.base_url.rstrip('/')}/api/epsimo-auth"
25
+
26
+ print(f"Authenticating with {url}...")
27
+
28
+ try:
29
+ response = requests.post(
30
+ url,
31
+ json={"email": email, "password": password},
32
+ headers={"Content-Type": "application/json"}
33
+ )
34
+
35
+ if response.status_code == 200:
36
+ data = response.json()
37
+ token = data.get("jwt_token")
38
+
39
+ if not token:
40
+ print("Error: Authentication succeeded but no token was returned.")
41
+ sys.exit(1)
42
+
43
+ print("Successfully authenticated!")
44
+
45
+ if args.save:
46
+ auth_data = {
47
+ "token": token,
48
+ "email": email,
49
+ "base_url": args.base_url
50
+ }
51
+ with open(AUTH_FILE, "w") as f:
52
+ json.dump(auth_data, f, indent=2)
53
+ print(f"Credentials saved to {AUTH_FILE}")
54
+
55
+ return token
56
+ else:
57
+ print(f"Authentication failed (Status {response.status_code}): {response.text}")
58
+ sys.exit(1)
59
+
60
+ except Exception as e:
61
+ print(f"Error connecting to authentication service: {e}")
62
+ sys.exit(1)
63
+
64
+ if __name__ == "__main__":
65
+ main()
@@ -0,0 +1,114 @@
1
+ import requests
2
+ import json
3
+
4
+ url = "https://ugdmgjyxenhipk74b5swx4xvuy.appsync-api.us-east-1.amazonaws.com/graphql"
5
+ headers = {
6
+ "Content-Type": "application/json",
7
+ "x-api-key": "da2-5u4a7hbhvbb2fdsj2ys2h2pljy"
8
+ }
9
+
10
+ company_id = "company-1769080774403-0fbkihn"
11
+ owner = "2498a4e8-5071-70f7-987b-cc3e1d6ffc51"
12
+ client_name = "Global Education Excellence"
13
+ client_id_str = "client_global_education"
14
+
15
+ def run_query(query, variables=None):
16
+ payload = {"query": query, "variables": variables}
17
+ response = requests.post(url, headers=headers, json=payload)
18
+ return response.json()
19
+
20
+ # 1. Create Client
21
+ create_client_mutation = """
22
+ mutation CreateClient($input: CreateClientInput!) {
23
+ createClient(input: $input) {
24
+ id
25
+ clientName
26
+ }
27
+ }
28
+ """
29
+ client_input = {
30
+ "client_id": client_id_str,
31
+ "clientName": client_name,
32
+ "companyURL": "https://education.example.com",
33
+ "description": "Targeting Higher Ed and K-12 for demo",
34
+ "owner": owner,
35
+ "company_id": company_id
36
+ }
37
+
38
+ print(f"Creating client: {client_name}...")
39
+ res = run_query(create_client_mutation, {"input": client_input})
40
+ client_uuid = res.get('data', {}).get('createClient', {}).get('id')
41
+ print(f"Client Created. UUID: {client_uuid}")
42
+
43
+ # 2. Create Campaign
44
+ create_campaign_mutation = """
45
+ mutation CreateABMCampaign($input: CreateABMCampaignInput!) {
46
+ createABMCampaign(input: $input) {
47
+ id
48
+ name
49
+ }
50
+ }
51
+ """
52
+ campaign_input = {
53
+ "name": "Higher Ed Innovation 2026",
54
+ "description": "Strategic outreach for education sector",
55
+ "campaignType": "abm",
56
+ "status": "active",
57
+ "client_id": client_id_str, # Use string ID for dashboard
58
+ "company_id": company_id,
59
+ "owner": owner
60
+ }
61
+
62
+ print("Creating campaign...")
63
+ res = run_query(create_campaign_mutation, {"input": campaign_input})
64
+ campaign_id = res.get('data', {}).get('createABMCampaign', {}).get('id')
65
+ print(f"Campaign Created. ID: {campaign_id}")
66
+
67
+ # 3. Create 12 Leads
68
+ create_lead_mutation = """
69
+ mutation CreateEnrichLeads($input: CreateEnrichLeadsInput!) {
70
+ createEnrichLeads(input: $input) {
71
+ id
72
+ }
73
+ }
74
+ """
75
+
76
+ mock_leads = [
77
+ {"first": "Sarah", "last": "Miller", "email": "s.miller@stanford.edu", "company": "Stanford University", "title": "Dean of Engineering"},
78
+ {"first": "James", "last": "Wilson", "email": "j.wilson@harvard.edu", "company": "Harvard University", "title": "IT Director"},
79
+ {"first": "Emily", "last": "Chen", "email": "chen@mit.edu", "company": "MIT", "title": "Head of Admissions"},
80
+ {"first": "Robert", "last": "Taylor", "email": "r.taylor@cps.edu", "company": "Chicago Public Schools", "title": "Superintendent"},
81
+ {"first": "Linda", "last": "Garcia", "email": "lgarcia@nyu.edu", "company": "NYU", "title": "VP Student Affairs"},
82
+ {"first": "David", "last": "Brown", "email": "d.brown@asu.edu", "company": "Arizona State University", "title": "Chief Innovation Officer"},
83
+ {"first": "Susan", "last": "White", "email": "s.white@ox.ac.uk", "company": "Oxford University", "title": "Director of Research"},
84
+ {"first": "Michael", "last": "Davis", "email": "m.davis@yale.edu", "company": "Yale University", "title": "Provost"},
85
+ {"first": "Karen", "last": "Black", "email": "k.black@cam.ac.uk", "company": "University of Cambridge", "title": "Digital Transformation Lead"},
86
+ {"first": "Thomas", "last": "Green", "email": "tgreen@ucla.edu", "company": "UCLA", "title": "Head of EdTech"},
87
+ {"first": "Jennifer", "last": "Adams", "email": "jadams@columbia.edu", "company": "Columbia University", "title": "Registrar"},
88
+ {"first": "Patricia", "last": "King", "email": "p.king@berkeley.edu", "company": "UC Berkeley", "title": "Chancellor"}
89
+ ]
90
+
91
+ print(f"Inserting 12 leads for {client_name}...")
92
+ for lead in mock_leads:
93
+ full_name = f"{lead['first']} {lead['last']}"
94
+ lead_input = {
95
+ "firstName": lead['first'],
96
+ "lastName": lead['last'],
97
+ "fullName": full_name,
98
+ "contactName": full_name,
99
+ "email": lead['email'],
100
+ "companyName": lead['company'],
101
+ "title": lead['title'],
102
+ "status": "new",
103
+ "campaignId": campaign_id,
104
+ "client_id": client_id_str,
105
+ "company_id": company_id,
106
+ "owner": owner
107
+ }
108
+ # Note: GraphQL create doesn't automatically set lead_id for self-ref usually without custom logic,
109
+ # but we'll let the system handle it or manually set id/lead_id if needed.
110
+ # To be safe and follow visibility rules:
111
+ res = run_query(create_lead_mutation, {"input": lead_input})
112
+ print(f"Inserted: {full_name} ({lead['company']})")
113
+
114
+ print("\nAll tasks completed successfully!")
@@ -0,0 +1,120 @@
1
+ import requests
2
+ import json
3
+
4
+ url = "https://ugdmgjyxenhipk74b5swx4xvuy.appsync-api.us-east-1.amazonaws.com/graphql"
5
+ headers = {
6
+ "Content-Type": "application/json",
7
+ "x-api-key": "da2-5u4a7hbhvbb2fdsj2ys2h2pljy"
8
+ }
9
+
10
+ company_id = "company-1769080774403-0fbkihn"
11
+ owner = "2498a4e8-5071-70f7-987b-cc3e1d6ffc51"
12
+ client_name = "Premier Financial Services"
13
+ client_id_str = "client_fin_services"
14
+
15
+ def run_query(query, variables=None):
16
+ payload = {"query": query, "variables": variables}
17
+ response = requests.post(url, headers=headers, json=payload)
18
+ return response.json()
19
+
20
+ # 1. Create/Verify Client
21
+ create_client_mutation = """
22
+ mutation CreateClient($input: CreateClientInput!) {
23
+ createClient(input: $input) {
24
+ id
25
+ clientName
26
+ }
27
+ }
28
+ """
29
+ client_input = {
30
+ "client_id": client_id_str,
31
+ "clientName": client_name,
32
+ "companyURL": "https://finance.example.com",
33
+ "description": "Mock client for Financial Services demo",
34
+ "owner": owner,
35
+ "company_id": company_id
36
+ }
37
+
38
+ print(f"Creating client: {client_name}...")
39
+ res = run_query(create_client_mutation, {"input": client_input})
40
+ # We don't worry about duplicate client_id errors for now as we just need the campaign to link to the string ID
41
+ print(f"Client Processed.")
42
+
43
+ # 2. Create Campaign
44
+ create_campaign_mutation = """
45
+ mutation CreateABMCampaign($input: CreateABMCampaignInput!) {
46
+ createABMCampaign(input: $input) {
47
+ id
48
+ name
49
+ }
50
+ }
51
+ """
52
+ campaign_input = {
53
+ "name": "Banking & Fintech Outreach 2026",
54
+ "description": "Global outreach campaign for top-tier financial institutions",
55
+ "campaignType": "abm",
56
+ "status": "active",
57
+ "client_id": client_id_str,
58
+ "company_id": company_id,
59
+ "owner": owner
60
+ }
61
+
62
+ print("Creating campaign...")
63
+ res = run_query(create_campaign_mutation, {"input": campaign_input})
64
+ campaign_id = res.get('data', {}).get('createABMCampaign', {}).get('id')
65
+ print(f"Campaign Created. ID: {campaign_id}")
66
+
67
+ # 3. Define 20 Leads
68
+ mock_leads = [
69
+ {"first": "Mark", "last": "Stevens", "email": "m.stevens@goldmansachs.com", "company": "Goldman Sachs", "title": "Managing Director, Investment Banking"},
70
+ {"first": "Angela", "last": "Wong", "email": "a.wong@jpmorgan.com", "company": "JP Morgan Chase", "title": "Head of Fintech Innovation"},
71
+ {"first": "Christopher", "last": "Bell", "email": "c.bell@morganstanley.com", "company": "Morgan Stanley", "title": "VP Wealth Management"},
72
+ {"first": "Jessica", "last": "Lange", "email": "j.lange@hsbc.com", "company": "HSBC", "title": "Chief Compliance Officer"},
73
+ {"first": "Andrew", "last": "Foster", "email": "a.foster@barclays.com", "company": "Barclays", "title": "Head of Digital Transformation"},
74
+ {"first": "Michelle", "last": "Ross", "email": "m.ross@citigroup.com", "company": "Citigroup", "title": "Global Risk Manager"},
75
+ {"first": "Patrick", "last": "Murphy", "email": "p.murphy@wellsfargo.com", "company": "Wells Fargo", "title": "VP Consumer Lending"},
76
+ {"first": "Sandra", "last": "Bullock", "email": "s.bullock@bankofamerica.com", "company": "Bank of America", "title": "Director of Strategy"},
77
+ {"first": "Kevin", "last": "Hart", "email": "k.hart@fidelity.com", "company": "Fidelity Investments", "title": "Portfolio Manager"},
78
+ {"first": "Rachel", "last": "Green", "email": "r.green@vanguard.com", "company": "Vanguard", "title": "Head of Client Experience"},
79
+ {"first": "Monica", "last": "Geller", "email": "m.geller@blackrock.com", "company": "BlackRock", "title": "Managing Director, ESG"},
80
+ {"first": "Chandler", "last": "Bing", "email": "c.bing@ubs.com", "company": "UBS", "title": "Head of Private Banking"},
81
+ {"first": "Joey", "last": "Tribbiani", "email": "j.tribbiani@allianz.com", "company": "Allianz", "title": "VP Marketing"},
82
+ {"first": "Phoebe", "last": "Buffay", "email": "p.buffay@axa.com", "company": "AXA", "title": "HR Director"},
83
+ {"first": "Ross", "last": "Geller", "email": "r.geller@prudential.com", "company": "Prudential Financial", "title": "Chief Data Officer"},
84
+ {"first": "William", "last": "Shatner", "email": "w.shatner@metlife.com", "company": "MetLife", "title": "VP Enterprise Sales"},
85
+ {"first": "Leonard", "last": "Nimoy", "email": "l.nimoy@statestreet.com", "company": "State Street", "title": "Head of Custody Services"},
86
+ {"first": "Hiroshi", "last": "Tanaka", "email": "h.tanaka@bnymellon.com", "company": "BNY Mellon", "title": "Director of Operations"},
87
+ {"first": "Elena", "last": "Petrova", "email": "e.petrova@nomura.com", "company": "Nomura Holdings", "title": "Investment Strategist"},
88
+ {"first": "Sven", "last": "Gunnar", "email": "s.gunnar@ubs.com", "company": "UBS", "title": "Senior Portfolio Analyst"}
89
+ ]
90
+
91
+ # 4. Insert Leads
92
+ create_lead_mutation = """
93
+ mutation CreateEnrichLeads($input: CreateEnrichLeadsInput!) {
94
+ createEnrichLeads(input: $input) {
95
+ id
96
+ }
97
+ }
98
+ """
99
+
100
+ print(f"Inserting 20 leads for {client_name}...")
101
+ for lead in mock_leads:
102
+ full_name = f"{lead['first']} {lead['last']}"
103
+ lead_input = {
104
+ "firstName": lead['first'],
105
+ "lastName": lead['last'],
106
+ "fullName": full_name,
107
+ "contactName": full_name,
108
+ "email": lead['email'],
109
+ "companyName": lead['company'],
110
+ "title": lead['title'],
111
+ "status": "new",
112
+ "campaignId": campaign_id,
113
+ "client_id": client_id_str,
114
+ "company_id": company_id,
115
+ "owner": owner
116
+ }
117
+ res = run_query(create_lead_mutation, {"input": lead_input})
118
+ print(f"Inserted: {full_name} ({lead['company']})")
119
+
120
+ print("\nAll 20 leads for Financial Services completed successfully!")