linkedin-secret-sauce 0.5.0 → 0.6.0
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/dist/enrichment/auth/index.d.ts +4 -0
- package/dist/enrichment/auth/index.js +17 -0
- package/dist/enrichment/auth/smartlead-auth.d.ts +82 -0
- package/dist/enrichment/auth/smartlead-auth.js +321 -0
- package/dist/enrichment/index.d.ts +11 -8
- package/dist/enrichment/index.js +75 -20
- package/dist/enrichment/matching.d.ts +239 -0
- package/dist/enrichment/matching.js +619 -0
- package/dist/enrichment/orchestrator.d.ts +13 -1
- package/dist/enrichment/orchestrator.js +220 -3
- package/dist/enrichment/providers/apollo.d.ts +2 -2
- package/dist/enrichment/providers/apollo.js +59 -14
- package/dist/enrichment/providers/construct.d.ts +2 -2
- package/dist/enrichment/providers/construct.js +16 -4
- package/dist/enrichment/providers/hunter.d.ts +2 -2
- package/dist/enrichment/providers/hunter.js +48 -22
- package/dist/enrichment/providers/ldd.d.ts +2 -2
- package/dist/enrichment/providers/ldd.js +16 -8
- package/dist/enrichment/providers/smartprospect.d.ts +72 -2
- package/dist/enrichment/providers/smartprospect.js +512 -72
- package/dist/enrichment/types.d.ts +156 -14
- package/dist/enrichment/types.js +56 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -1
- package/package.json +1 -1
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contact Matching Utilities
|
|
3
|
+
*
|
|
4
|
+
* Matches contacts between LinkedIn Sales Navigator and SmartProspect
|
|
5
|
+
* to find the same person across both platforms.
|
|
6
|
+
*/
|
|
7
|
+
import type { SmartProspectContact, SmartProspectConfig, SmartProspectFetchResponse } from './types';
|
|
8
|
+
import { type SmartProspectClient } from './providers/smartprospect';
|
|
9
|
+
/**
|
|
10
|
+
* LinkedIn Sales Navigator contact (simplified from API response)
|
|
11
|
+
*/
|
|
12
|
+
export interface LinkedInContact {
|
|
13
|
+
/** LinkedIn member URN (e.g., "urn:li:member:1044675597") */
|
|
14
|
+
objectUrn?: string;
|
|
15
|
+
/** Sales Nav entity URN */
|
|
16
|
+
entityUrn?: string;
|
|
17
|
+
firstName: string;
|
|
18
|
+
lastName: string;
|
|
19
|
+
fullName?: string;
|
|
20
|
+
/** Geographic region (e.g., "Sofia, Sofia City, Bulgaria") */
|
|
21
|
+
geoRegion?: string;
|
|
22
|
+
/** Current positions array */
|
|
23
|
+
currentPositions?: Array<{
|
|
24
|
+
companyName?: string;
|
|
25
|
+
title?: string;
|
|
26
|
+
companyUrn?: string;
|
|
27
|
+
companyUrnResolutionResult?: {
|
|
28
|
+
name?: string;
|
|
29
|
+
website?: string;
|
|
30
|
+
industry?: string;
|
|
31
|
+
location?: string;
|
|
32
|
+
};
|
|
33
|
+
}>;
|
|
34
|
+
/** Profile picture */
|
|
35
|
+
profilePictureDisplayImage?: {
|
|
36
|
+
rootUrl?: string;
|
|
37
|
+
artifacts?: Array<{
|
|
38
|
+
fileIdentifyingUrlPathSegment?: string;
|
|
39
|
+
}>;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Match result with confidence score
|
|
44
|
+
*/
|
|
45
|
+
export interface MatchResult {
|
|
46
|
+
/** The matched SmartProspect contact */
|
|
47
|
+
smartProspectContact: SmartProspectContact;
|
|
48
|
+
/** The LinkedIn contact that was matched */
|
|
49
|
+
linkedInContact: LinkedInContact;
|
|
50
|
+
/** Match confidence score (0-100) */
|
|
51
|
+
confidence: number;
|
|
52
|
+
/** Which fields matched */
|
|
53
|
+
matchedFields: string[];
|
|
54
|
+
/** Match quality classification */
|
|
55
|
+
quality: 'exact' | 'high' | 'medium' | 'low' | 'none';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Options for matching
|
|
59
|
+
*/
|
|
60
|
+
export interface MatchOptions {
|
|
61
|
+
/** Minimum confidence threshold (default: 50) */
|
|
62
|
+
minConfidence?: number;
|
|
63
|
+
/** Whether to use fuzzy matching for names (default: true) */
|
|
64
|
+
fuzzyNames?: boolean;
|
|
65
|
+
/** Whether to use fuzzy matching for company names (default: true) */
|
|
66
|
+
fuzzyCompany?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Calculate match confidence between a LinkedIn contact and SmartProspect contact
|
|
70
|
+
*/
|
|
71
|
+
export declare function calculateMatchConfidence(linkedin: LinkedInContact, smartprospect: SmartProspectContact, options?: MatchOptions): {
|
|
72
|
+
confidence: number;
|
|
73
|
+
matchedFields: string[];
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Classify match quality based on confidence and matched fields
|
|
77
|
+
*/
|
|
78
|
+
export declare function classifyMatchQuality(confidence: number, matchedFields: string[]): 'exact' | 'high' | 'medium' | 'low' | 'none';
|
|
79
|
+
/**
|
|
80
|
+
* Find the best matching SmartProspect contact for a LinkedIn contact
|
|
81
|
+
*/
|
|
82
|
+
export declare function findBestMatch(linkedInContact: LinkedInContact, smartProspectContacts: SmartProspectContact[], options?: MatchOptions): MatchResult | null;
|
|
83
|
+
/**
|
|
84
|
+
* Match multiple LinkedIn contacts to SmartProspect contacts
|
|
85
|
+
*/
|
|
86
|
+
export declare function matchContacts(linkedInContacts: LinkedInContact[], smartProspectContacts: SmartProspectContact[], options?: MatchOptions): MatchResult[];
|
|
87
|
+
/**
|
|
88
|
+
* Build SmartProspect search filters from a LinkedIn contact
|
|
89
|
+
* This helps you search SmartProspect for a specific LinkedIn contact
|
|
90
|
+
*/
|
|
91
|
+
export declare function buildSmartProspectFiltersFromLinkedIn(linkedInContact: LinkedInContact): {
|
|
92
|
+
firstName: string[];
|
|
93
|
+
lastName: string[];
|
|
94
|
+
companyName?: string[];
|
|
95
|
+
title?: string[];
|
|
96
|
+
country?: string[];
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Parse LinkedIn Sales Navigator API response elements into LinkedInContact array
|
|
100
|
+
*/
|
|
101
|
+
export declare function parseLinkedInSearchResponse(elements: Array<Record<string, unknown>>): LinkedInContact[];
|
|
102
|
+
/**
|
|
103
|
+
* Result of enriching a LinkedIn contact via SmartProspect
|
|
104
|
+
*/
|
|
105
|
+
export interface LinkedInEnrichmentResult {
|
|
106
|
+
/** Whether enrichment was successful */
|
|
107
|
+
success: boolean;
|
|
108
|
+
/** The original LinkedIn contact */
|
|
109
|
+
linkedInContact: LinkedInContact;
|
|
110
|
+
/** The matched SmartProspect contact (if found) */
|
|
111
|
+
matchedContact: SmartProspectContact | null;
|
|
112
|
+
/** Match confidence score (0-100) */
|
|
113
|
+
matchConfidence: number;
|
|
114
|
+
/** Match quality classification */
|
|
115
|
+
matchQuality: 'exact' | 'high' | 'medium' | 'low' | 'none';
|
|
116
|
+
/** Which fields matched */
|
|
117
|
+
matchedFields: string[];
|
|
118
|
+
/** Enriched email (if fetched) */
|
|
119
|
+
email: string | null;
|
|
120
|
+
/** Email deliverability score (0-1) */
|
|
121
|
+
emailDeliverability: number;
|
|
122
|
+
/** Email verification status */
|
|
123
|
+
verificationStatus: string | null;
|
|
124
|
+
/** All candidate contacts found in SmartProspect */
|
|
125
|
+
allCandidates: SmartProspectContact[];
|
|
126
|
+
/** Total candidates found in search */
|
|
127
|
+
totalCandidatesFound: number;
|
|
128
|
+
/** Error message if failed */
|
|
129
|
+
error?: string;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Options for LinkedIn contact enrichment
|
|
133
|
+
*/
|
|
134
|
+
export interface LinkedInEnrichmentOptions {
|
|
135
|
+
/** Minimum match confidence to consider (default: 60) */
|
|
136
|
+
minConfidence?: number;
|
|
137
|
+
/** Whether to auto-fetch email if good match found (default: true) - COSTS CREDITS */
|
|
138
|
+
autoFetch?: boolean;
|
|
139
|
+
/** Whether to use fuzzy name matching (default: true) */
|
|
140
|
+
fuzzyNames?: boolean;
|
|
141
|
+
/** Whether to use fuzzy company matching (default: true) */
|
|
142
|
+
fuzzyCompany?: boolean;
|
|
143
|
+
/** Search limit - how many candidates to retrieve (default: 25) */
|
|
144
|
+
searchLimit?: number;
|
|
145
|
+
/** Whether to include company name in search (default: true) */
|
|
146
|
+
includeCompany?: boolean;
|
|
147
|
+
/** Whether to include location in search (default: false) */
|
|
148
|
+
includeLocation?: boolean;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Enrich a LinkedIn Sales Navigator contact using SmartProspect
|
|
152
|
+
*
|
|
153
|
+
* This is the main function consumers should use. It:
|
|
154
|
+
* 1. Takes a LinkedIn contact from Sales Navigator search results
|
|
155
|
+
* 2. Searches SmartProspect for matching candidates
|
|
156
|
+
* 3. Uses intelligent matching to find the exact same person
|
|
157
|
+
* 4. Optionally fetches their verified email (costs credits)
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* import { enrichLinkedInContact } from 'linkedin-secret-sauce';
|
|
162
|
+
*
|
|
163
|
+
* // From your LinkedIn Sales Nav search result
|
|
164
|
+
* const linkedInContact = {
|
|
165
|
+
* firstName: 'Valentin',
|
|
166
|
+
* lastName: 'Rangelov',
|
|
167
|
+
* geoRegion: 'Sofia, Sofia City, Bulgaria',
|
|
168
|
+
* currentPositions: [{
|
|
169
|
+
* companyName: 'Recruitica',
|
|
170
|
+
* title: 'Chief Technology Officer'
|
|
171
|
+
* }]
|
|
172
|
+
* };
|
|
173
|
+
*
|
|
174
|
+
* const result = await enrichLinkedInContact(linkedInContact, {
|
|
175
|
+
* email: process.env.SMARTLEAD_EMAIL,
|
|
176
|
+
* password: process.env.SMARTLEAD_PASSWORD
|
|
177
|
+
* });
|
|
178
|
+
*
|
|
179
|
+
* if (result.success && result.email) {
|
|
180
|
+
* console.log(`Found email: ${result.email}`);
|
|
181
|
+
* console.log(`Match confidence: ${result.matchConfidence}%`);
|
|
182
|
+
* console.log(`Deliverability: ${result.emailDeliverability * 100}%`);
|
|
183
|
+
* }
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export declare function enrichLinkedInContact(linkedInContact: LinkedInContact, smartProspectConfig: SmartProspectConfig, options?: LinkedInEnrichmentOptions): Promise<LinkedInEnrichmentResult>;
|
|
187
|
+
/**
|
|
188
|
+
* Enrich multiple LinkedIn contacts in batch
|
|
189
|
+
*
|
|
190
|
+
* Processes contacts sequentially to avoid rate limits.
|
|
191
|
+
* For parallel processing, use Promise.all with rate limiting.
|
|
192
|
+
*/
|
|
193
|
+
export declare function enrichLinkedInContactsBatch(linkedInContacts: LinkedInContact[], smartProspectConfig: SmartProspectConfig, options?: LinkedInEnrichmentOptions & {
|
|
194
|
+
/** Delay between requests in ms (default: 200) */
|
|
195
|
+
delayMs?: number;
|
|
196
|
+
/** Callback for progress updates */
|
|
197
|
+
onProgress?: (completed: number, total: number, result: LinkedInEnrichmentResult) => void;
|
|
198
|
+
}): Promise<LinkedInEnrichmentResult[]>;
|
|
199
|
+
/**
|
|
200
|
+
* Create a reusable enricher function with pre-configured SmartProspect client
|
|
201
|
+
*
|
|
202
|
+
* More efficient for multiple enrichments as it reuses the same client/token.
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```ts
|
|
206
|
+
* const enricher = createLinkedInEnricher({
|
|
207
|
+
* email: process.env.SMARTLEAD_EMAIL,
|
|
208
|
+
* password: process.env.SMARTLEAD_PASSWORD
|
|
209
|
+
* });
|
|
210
|
+
*
|
|
211
|
+
* // Now use for multiple contacts
|
|
212
|
+
* const result1 = await enricher.enrich(contact1);
|
|
213
|
+
* const result2 = await enricher.enrich(contact2);
|
|
214
|
+
*
|
|
215
|
+
* // Or batch
|
|
216
|
+
* const results = await enricher.enrichBatch([contact1, contact2, contact3]);
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
export declare function createLinkedInEnricher(smartProspectConfig: SmartProspectConfig, defaultOptions?: LinkedInEnrichmentOptions): {
|
|
220
|
+
/** The underlying SmartProspect client */
|
|
221
|
+
client: SmartProspectClient;
|
|
222
|
+
/** Enrich a single LinkedIn contact */
|
|
223
|
+
enrich: (contact: LinkedInContact, options?: LinkedInEnrichmentOptions) => Promise<LinkedInEnrichmentResult>;
|
|
224
|
+
/** Enrich multiple LinkedIn contacts */
|
|
225
|
+
enrichBatch: (contacts: LinkedInContact[], options?: LinkedInEnrichmentOptions & {
|
|
226
|
+
delayMs?: number;
|
|
227
|
+
onProgress?: (completed: number, total: number, result: LinkedInEnrichmentResult) => void;
|
|
228
|
+
}) => Promise<LinkedInEnrichmentResult[]>;
|
|
229
|
+
/** Search SmartProspect for a LinkedIn contact without fetching (FREE) */
|
|
230
|
+
searchOnly: (contact: LinkedInContact, options?: {
|
|
231
|
+
searchLimit?: number;
|
|
232
|
+
includeCompany?: boolean;
|
|
233
|
+
}) => Promise<{
|
|
234
|
+
candidates: SmartProspectContact[];
|
|
235
|
+
bestMatch: MatchResult | null;
|
|
236
|
+
}>;
|
|
237
|
+
/** Fetch email for a specific SmartProspect contact ID (COSTS CREDITS) */
|
|
238
|
+
fetchEmail: (contactId: string) => Promise<SmartProspectFetchResponse>;
|
|
239
|
+
} | null;
|