@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 +0 -0
- package/README.md +0 -0
- package/SKILL.md +148 -17
- package/package.json +2 -2
- package/references/api_reference.md +27 -2
- package/references/openapi.json +0 -0
- package/scripts/api_call.py +18 -1
- package/scripts/auth.py +65 -0
- package/scripts/create_edu_demo.py +114 -0
- package/scripts/create_fin_demo.py +120 -0
- package/scripts/fix_leads.py +87 -0
- package/scripts/index_leads.py +91 -0
- package/scripts/lead_distribution.py +125 -0
- package/scripts/lgp.py +409 -0
- package/scripts/rest_lead_stats.py +84 -0
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
|
-
- **
|
|
14
|
-
- **
|
|
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
|
|
29
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
- **
|
|
41
|
-
- **
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
package/references/openapi.json
CHANGED
|
File without changes
|
package/scripts/api_call.py
CHANGED
|
@@ -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
|
-
|
|
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('/')}"
|
package/scripts/auth.py
ADDED
|
@@ -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!")
|