@thierryteisseire/leadgenius-skill 1.1.1 → 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/SKILL.md +3 -0
- package/package.json +1 -1
- package/references/api_reference.md +2 -49
- package/scripts/api_call.py +2 -21
- package/scripts/auth.py +1 -1
- package/scripts/lgp.py +99 -28
package/SKILL.md
CHANGED
|
@@ -65,6 +65,9 @@ python3 scripts/lgp.py auth --email your@email.com
|
|
|
65
65
|
# List leads
|
|
66
66
|
python3 scripts/lgp.py leads list
|
|
67
67
|
|
|
68
|
+
# Find specific leads
|
|
69
|
+
python3 scripts/lgp.py leads find --full-name "Hugo Sanchez"
|
|
70
|
+
|
|
68
71
|
# Enrich specific leads
|
|
69
72
|
python3 scripts/lgp.py leads enrich --ids lead_1 lead_2
|
|
70
73
|
```
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This document provides a detailed breakdown of all available endpoints in the LeadGenius Pro Agent API.
|
|
4
4
|
|
|
5
5
|
## Base URL
|
|
6
|
-
`https://
|
|
6
|
+
`https://your-domain.com/api/agent`
|
|
7
7
|
|
|
8
8
|
## Authentication
|
|
9
9
|
All requests require an API key passed in headers:
|
|
@@ -41,7 +41,7 @@ Lifecycle management for marketing and sales leads.
|
|
|
41
41
|
|
|
42
42
|
### `GET /leads`
|
|
43
43
|
List leads with advanced filtering.
|
|
44
|
-
- **Filters**: `status`, `campaignId`, `email`, `companyName`.
|
|
44
|
+
- **Filters**: `status`, `campaignId`, `email`, `companyName`, `firstName`, `lastName`, `fullName`.
|
|
45
45
|
- **Pagination**: `page`, `pageSize` (Default 20, Max 100).
|
|
46
46
|
|
|
47
47
|
### `POST /leads`
|
|
@@ -120,50 +120,3 @@ Manage connections to CRMs (Salesforce, HubSpot) and Mail Platforms.
|
|
|
120
120
|
|
|
121
121
|
### `GET /webhooks`
|
|
122
122
|
Configure event-based real-time notifications.
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## 🛠️ Maintenance & System Health
|
|
127
|
-
Endpoints for reporting issues and providing feedback.
|
|
128
|
-
|
|
129
|
-
### `GET /maintenance/bugs`
|
|
130
|
-
List reported bugs.
|
|
131
|
-
|
|
132
|
-
### `POST /maintenance/bugs`
|
|
133
|
-
Report a discovered issue.
|
|
134
|
-
- **Body**: `{ description, userEmail }`
|
|
135
|
-
|
|
136
|
-
### `GET /maintenance/enhancements`
|
|
137
|
-
List requested enhancements.
|
|
138
|
-
|
|
139
|
-
### `POST /maintenance/enhancements`
|
|
140
|
-
Request a new feature.
|
|
141
|
-
- **Body**: `{ description, userEmail }`
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## 👑 Global Administration (Admin Only)
|
|
146
|
-
High-level system management. Requires Master Admin status.
|
|
147
|
-
Root Path: `/api/admin`
|
|
148
|
-
|
|
149
|
-
### `GET /companies`
|
|
150
|
-
List all organizations currently using the platform.
|
|
151
|
-
|
|
152
|
-
### `GET /users`
|
|
153
|
-
Get the global directory of all platform users and their roles.
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## 🔑 Authentication & API Keys
|
|
158
|
-
### `POST /epsimo-auth`
|
|
159
|
-
Exchange email/password for a JWT token.
|
|
160
|
-
- **Root Path**: `/api/epsimo-auth`
|
|
161
|
-
- **Body**: `{ email, password }`
|
|
162
|
-
|
|
163
|
-
### `POST /agent-api-keys`
|
|
164
|
-
Generate a new persistent API Key.
|
|
165
|
-
- **Auth**: Requires JWT (Bearer)
|
|
166
|
-
- **Body**: `{ name, description }`
|
|
167
|
-
|
|
168
|
-
### `GET /agent-api-keys`
|
|
169
|
-
List active API keys for the current user.
|
package/scripts/api_call.py
CHANGED
|
@@ -10,7 +10,7 @@ def main():
|
|
|
10
10
|
parser.add_argument("method", choices=["GET", "POST", "PUT", "DELETE"], help="HTTP method")
|
|
11
11
|
parser.add_argument("endpoint", help="API endpoint (e.g., /leads)")
|
|
12
12
|
parser.add_argument("--data", help="JSON data for POST/PUT requests")
|
|
13
|
-
parser.add_argument("--base-url", default="
|
|
13
|
+
parser.add_argument("--base-url", default="http://localhost:3000/api/agent", help="Base URL")
|
|
14
14
|
parser.add_argument("--key", help="API Key (defaults to LGP_API_KEY env var)")
|
|
15
15
|
|
|
16
16
|
args = parser.parse_args()
|
|
@@ -37,26 +37,8 @@ def main():
|
|
|
37
37
|
print("Error: API Key is required. Run 'python3 scripts/auth.py' first, use --key, or set LGP_API_KEY.")
|
|
38
38
|
sys.exit(1)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
root_base = args.base_url.rstrip('/').replace('/api/agent', '')
|
|
42
|
-
|
|
43
|
-
if args.endpoint.startswith('/admin') or args.endpoint.startswith('admin/'):
|
|
44
|
-
# Admin routes
|
|
45
|
-
base_url = f"{root_base}/api/admin"
|
|
46
|
-
clean_endpoint = args.endpoint.replace('/admin/', '').replace('admin/', '').lstrip('/')
|
|
47
|
-
elif 'epsimo-auth' in args.endpoint or 'agent-api-keys' in args.endpoint:
|
|
48
|
-
# Root API routes
|
|
49
|
-
base_url = f"{root_base}/api"
|
|
50
|
-
clean_endpoint = args.endpoint.lstrip('/')
|
|
51
|
-
else:
|
|
52
|
-
# Default Agent routes
|
|
53
|
-
base_url = f"{root_base}/api/agent"
|
|
54
|
-
clean_endpoint = args.endpoint.lstrip('/')
|
|
55
|
-
|
|
56
|
-
url = f"{base_url}/{clean_endpoint}"
|
|
57
|
-
|
|
40
|
+
url = f"{args.base_url.rstrip('/')}/{args.endpoint.lstrip('/')}"
|
|
58
41
|
headers = {
|
|
59
|
-
"Authorization": f"Bearer {api_key}",
|
|
60
42
|
"X-API-Key": api_key,
|
|
61
43
|
"Content-Type": "application/json"
|
|
62
44
|
}
|
|
@@ -66,7 +48,6 @@ def main():
|
|
|
66
48
|
if args.data:
|
|
67
49
|
data = json.loads(args.data)
|
|
68
50
|
|
|
69
|
-
print(f"Calling: {args.method} {url}")
|
|
70
51
|
response = requests.request(args.method, url, headers=headers, json=data)
|
|
71
52
|
|
|
72
53
|
print(f"Status: {response.status_code}")
|
package/scripts/auth.py
CHANGED
package/scripts/lgp.py
CHANGED
|
@@ -5,9 +5,9 @@ import os
|
|
|
5
5
|
import requests
|
|
6
6
|
import sys
|
|
7
7
|
from getpass import getpass
|
|
8
|
-
from datetime import datetime
|
|
8
|
+
from datetime import datetime
|
|
9
9
|
|
|
10
|
-
DEFAULT_BASE_URL = "
|
|
10
|
+
DEFAULT_BASE_URL = "http://localhost:3000"
|
|
11
11
|
AUTH_FILE = os.path.expanduser("~/.leadgenius_auth.json")
|
|
12
12
|
|
|
13
13
|
class LeadGeniusCLI:
|
|
@@ -32,16 +32,13 @@ class LeadGeniusCLI:
|
|
|
32
32
|
pass
|
|
33
33
|
return None
|
|
34
34
|
|
|
35
|
-
def _request(self, method, endpoint, data=None, params=None
|
|
35
|
+
def _request(self, method, endpoint, data=None, params=None):
|
|
36
36
|
if not self.token:
|
|
37
37
|
print("Error: Not authenticated. Set LGP_API_KEY or run 'lgp auth'.")
|
|
38
38
|
sys.exit(1)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
url = f"{self.base_url}/{base_path.strip('/')}/{endpoint.lstrip('/')}"
|
|
42
|
-
|
|
40
|
+
url = f"{self.base_url}/api/agent/{endpoint.lstrip('/')}"
|
|
43
41
|
headers = {
|
|
44
|
-
"Authorization": f"Bearer {self.token}",
|
|
45
42
|
"X-API-Key": self.token,
|
|
46
43
|
"Content-Type": "application/json"
|
|
47
44
|
}
|
|
@@ -63,11 +60,7 @@ class LeadGeniusCLI:
|
|
|
63
60
|
print("Make sure LGP_API_KEY is set to a valid API Key.")
|
|
64
61
|
return None
|
|
65
62
|
if response.status_code >= 400:
|
|
66
|
-
|
|
67
|
-
if response.status_code == 403:
|
|
68
|
-
print(f"Error (403): Master Admin access required for {url}")
|
|
69
|
-
else:
|
|
70
|
-
print(f"Error ({response.status_code}): {response.text}")
|
|
63
|
+
print(f"Error ({response.status_code}): {response.text}")
|
|
71
64
|
return None
|
|
72
65
|
return response.json()
|
|
73
66
|
except Exception as e:
|
|
@@ -161,6 +154,54 @@ class LeadGeniusCLI:
|
|
|
161
154
|
if data:
|
|
162
155
|
print(json.dumps(data, indent=2))
|
|
163
156
|
|
|
157
|
+
def find_lead(self, first_name=None, last_name=None, full_name=None, email=None, company=None):
|
|
158
|
+
params = {"pageSize": 100}
|
|
159
|
+
if first_name:
|
|
160
|
+
params["firstName"] = first_name
|
|
161
|
+
if last_name:
|
|
162
|
+
params["lastName"] = last_name
|
|
163
|
+
if full_name:
|
|
164
|
+
params["fullName"] = full_name
|
|
165
|
+
if email:
|
|
166
|
+
params["email"] = email
|
|
167
|
+
if company:
|
|
168
|
+
params["companyName"] = company
|
|
169
|
+
data = self._request("GET", "leads", params=params)
|
|
170
|
+
if data:
|
|
171
|
+
leads = data.get("data", [])
|
|
172
|
+
if not leads:
|
|
173
|
+
print("No leads found matching criteria.")
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
# Client-side filtering (polyfill for server limitation)
|
|
177
|
+
filtered_leads = []
|
|
178
|
+
for lead in leads:
|
|
179
|
+
match = True
|
|
180
|
+
if first_name and first_name.lower() not in (lead.get('firstName') or '').lower(): match = False
|
|
181
|
+
if last_name and last_name.lower() not in (lead.get('lastName') or '').lower(): match = False
|
|
182
|
+
if full_name and full_name.lower() not in (lead.get('fullName') or '').lower(): match = False
|
|
183
|
+
if email and email.lower() not in (lead.get('email') or '').lower(): match = False
|
|
184
|
+
if company and company.lower() not in (lead.get('companyName') or '').lower(): match = False
|
|
185
|
+
|
|
186
|
+
if match:
|
|
187
|
+
filtered_leads.append(lead)
|
|
188
|
+
|
|
189
|
+
if not filtered_leads:
|
|
190
|
+
print("No leads found matching criteria (checked 100 most recent).")
|
|
191
|
+
return
|
|
192
|
+
|
|
193
|
+
print(f"Found {len(filtered_leads)} lead(s):\n")
|
|
194
|
+
for lead in filtered_leads:
|
|
195
|
+
print(f" ID: {lead.get('id')}")
|
|
196
|
+
print(f" Name: {lead.get('fullName') or lead.get('contactName', 'N/A')}")
|
|
197
|
+
print(f" Title: {lead.get('title', 'N/A')}")
|
|
198
|
+
print(f" Company: {lead.get('companyName', 'N/A')}")
|
|
199
|
+
print(f" Email: {lead.get('email', 'N/A')}")
|
|
200
|
+
print(f" LinkedIn: {lead.get('linkedinUrl', 'N/A')}")
|
|
201
|
+
print(f" Location: {lead.get('city', 'N/A')}, {lead.get('country', 'N/A')}")
|
|
202
|
+
print(f" Status: {lead.get('status', 'N/A')}")
|
|
203
|
+
print()
|
|
204
|
+
|
|
164
205
|
def enrich_leads(self, lead_ids, type="technographic"):
|
|
165
206
|
payload = {"leadIds": lead_ids, "enrichmentType": type}
|
|
166
207
|
data = self._request("POST", "enrichment/trigger", data=payload)
|
|
@@ -171,12 +212,7 @@ class LeadGeniusCLI:
|
|
|
171
212
|
def list_campaigns(self):
|
|
172
213
|
data = self._request("GET", "campaigns")
|
|
173
214
|
if data:
|
|
174
|
-
|
|
175
|
-
campaigns = data.get("data")
|
|
176
|
-
if campaigns is None: # Fallback for local/legacy if applicable
|
|
177
|
-
campaigns = data.get("campaigns", [])
|
|
178
|
-
|
|
179
|
-
for c in campaigns:
|
|
215
|
+
for c in data.get("campaigns", []):
|
|
180
216
|
print(f"[{c.get('id')}] {c.get('name')} ({c.get('status')})")
|
|
181
217
|
|
|
182
218
|
def create_campaign(self, name, type="abm"):
|
|
@@ -186,7 +222,7 @@ class LeadGeniusCLI:
|
|
|
186
222
|
print(f"Campaign created: {data.get('id')}")
|
|
187
223
|
|
|
188
224
|
# Analytics
|
|
189
|
-
def show_pipeline(self, start_date, end_date):
|
|
225
|
+
def show_pipeline(self, start_date=None, end_date=None):
|
|
190
226
|
params = {"startDate": start_date, "endDate": end_date}
|
|
191
227
|
data = self._request("GET", "analytics/pipeline", params=params)
|
|
192
228
|
if data:
|
|
@@ -220,17 +256,36 @@ class LeadGeniusCLI:
|
|
|
220
256
|
enh = data.get('enhancement', {})
|
|
221
257
|
print(f"Enhancement requested: ID {enh.get('id')}")
|
|
222
258
|
|
|
223
|
-
# Admin
|
|
259
|
+
# Admin
|
|
224
260
|
def list_all_companies(self):
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
261
|
+
# Admin endpoint call attempt
|
|
262
|
+
print("Warning: Admin endpoints require session cookies. This might fail with API Key.")
|
|
263
|
+
url = f"{self.base_url}/api/admin/companies"
|
|
264
|
+
headers = {
|
|
265
|
+
"Content-Type": "application/json",
|
|
266
|
+
# Try passing API Key anyway, maybe backend changes later
|
|
267
|
+
"X-API-Key": self.token
|
|
268
|
+
}
|
|
269
|
+
try:
|
|
270
|
+
response = requests.get(url, headers=headers)
|
|
271
|
+
print(f"Status: {response.status_code}")
|
|
272
|
+
print(response.text)
|
|
273
|
+
except Exception as e:
|
|
274
|
+
print(f"Error: {e}")
|
|
228
275
|
|
|
229
276
|
def list_all_users(self):
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
277
|
+
print("Warning: Admin endpoints require session cookies. This might fail with API Key.")
|
|
278
|
+
url = f"{self.base_url}/api/admin/users"
|
|
279
|
+
headers = {
|
|
280
|
+
"Content-Type": "application/json",
|
|
281
|
+
"X-API-Key": self.token
|
|
282
|
+
}
|
|
283
|
+
try:
|
|
284
|
+
response = requests.get(url, headers=headers)
|
|
285
|
+
print(f"Status: {response.status_code}")
|
|
286
|
+
print(response.text)
|
|
287
|
+
except Exception as e:
|
|
288
|
+
print(f"Error: {e}")
|
|
234
289
|
|
|
235
290
|
def main():
|
|
236
291
|
parser = argparse.ArgumentParser(description="LeadGenius Pro Agent CLI")
|
|
@@ -248,8 +303,13 @@ def main():
|
|
|
248
303
|
|
|
249
304
|
# Leads
|
|
250
305
|
leads_parser = subparsers.add_parser("leads", help="Manage leads")
|
|
251
|
-
leads_parser.add_argument("action", choices=["list", "enrich"])
|
|
306
|
+
leads_parser.add_argument("action", choices=["list", "find", "enrich"])
|
|
252
307
|
leads_parser.add_argument("--ids", nargs="+", help="Lead IDs for enrichment")
|
|
308
|
+
leads_parser.add_argument("--first-name", help="First name filter (for find)")
|
|
309
|
+
leads_parser.add_argument("--last-name", help="Last name filter (for find)")
|
|
310
|
+
leads_parser.add_argument("--full-name", help="Full name search (for find)")
|
|
311
|
+
leads_parser.add_argument("--email", help="Email filter (for find)")
|
|
312
|
+
leads_parser.add_argument("--company", help="Company name filter (for find)")
|
|
253
313
|
|
|
254
314
|
# Campaigns
|
|
255
315
|
camp_parser = subparsers.add_parser("campaigns", help="Manage campaigns")
|
|
@@ -291,6 +351,17 @@ def main():
|
|
|
291
351
|
elif args.command == "leads":
|
|
292
352
|
if args.action == "list":
|
|
293
353
|
cli.list_leads()
|
|
354
|
+
elif args.action == "find":
|
|
355
|
+
if not any([args.first_name, args.last_name, args.full_name, args.email, args.company]):
|
|
356
|
+
print("Error: provide at least one filter: --first-name, --last-name, --full-name, --email, or --company")
|
|
357
|
+
return
|
|
358
|
+
cli.find_lead(
|
|
359
|
+
first_name=args.first_name,
|
|
360
|
+
last_name=args.last_name,
|
|
361
|
+
full_name=args.full_name,
|
|
362
|
+
email=args.email,
|
|
363
|
+
company=args.company,
|
|
364
|
+
)
|
|
294
365
|
elif args.action == "enrich":
|
|
295
366
|
if not args.ids:
|
|
296
367
|
print("Error: --ids required for enrichment")
|