@memberjunction/actions-apollo 2.79.0 → 2.80.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/README.md CHANGED
@@ -36,9 +36,12 @@ APOLLO_API_KEY=your_apollo_api_key_here
36
36
 
37
37
  The package uses the following configuration values (defined in `config.ts`):
38
38
 
39
+ - `ApolloAPIEndpoint`: 'https://api.apollo.io/v1' - Apollo.io API base URL
40
+ - `EmailSourceName`: 'Apollo.io' - Source name for enriched emails
39
41
  - `GroupSize`: 10 - Maximum records per API batch request
40
42
  - `ConcurrentGroups`: 1 - Number of concurrent API request groups
41
43
  - `MaxPeopleToEnrichPerOrg`: 500 - Maximum contacts to enrich per organization
44
+ - `ApolloAPIKey`: Read from environment variable `APOLLO_API_KEY`
42
45
 
43
46
  ## Usage
44
47
 
@@ -48,53 +51,49 @@ This action enriches account/organization records by looking up company informat
48
51
 
49
52
  #### Parameters
50
53
 
54
+ The action accepts the following parameters as JSON strings:
55
+
56
+ **Required:**
57
+ - `AccountEntityFieldNameJSON` - Maps account entity fields
58
+
59
+ **Optional:**
60
+ - `AccountTechnologyEntityFieldNameJSON` - Maps account technology relationship fields
61
+ - `TechnologyCategoryEntityFieldNameJSON` - Maps technology category fields
62
+ - `ContactEntityFieldNameJSON` - Maps contact entity fields
63
+ - `ContactEducationHistoryEntityFieldNameJSON` - Maps contact education history fields
64
+
65
+ **AccountEntityFieldNameJSON Structure:**
51
66
  ```typescript
52
67
  {
53
- // Required - JSON mapping for account entity fields
54
- AccountEntityFieldNameJSON: {
55
- EntityName: "Accounts",
56
- DomainParamName: "Domain",
57
- AccountIDName: "ID",
58
- EnrichedAtField: "LastEnrichedAt",
59
- AddressFieldName: "Address",
60
- CityFieldNameName: "City",
61
- StateProvinceFieldName: "State",
62
- PostalCodeFieldName: "PostalCode",
63
- DescriptionFieldName: "Description",
64
- PhoneNumberFieldName: "Phone",
65
- CountryFieldName: "Country",
66
- LinkedInFieldName: "LinkedIn",
67
- LogoURLFieldName: "LogoURL",
68
- FacebookFieldName: "Facebook",
69
- TwitterFieldName: "Twitter",
70
- ExtraFilter: "Domain IS NOT NULL AND LastEnrichedAt IS NULL"
71
- },
72
-
73
- // Optional - JSON mapping for technology tracking
74
- AccountTechnologyEntityFieldNameJSON: {
75
- EntityName: "AccountTechnologies",
76
- AccountIDFieldName: "AccountID",
77
- TechnologyIDFieldName: "TechnologyID",
78
- MatchFoundFieldName: "MatchFound",
79
- EndedUseAtFieldName: "EndedAt"
80
- },
81
-
82
- // Optional - JSON mapping for technology categories
83
- TechnologyCategoryEntityFieldNameJSON: {
84
- EntityName: "TechnologyCategories",
85
- NameFieldName: "Name",
86
- IDFieldName: "ID"
87
- },
88
-
89
- // Optional - JSON mapping for contacts
90
- ContactEntityFieldNameJSON: {
91
- EntityName: "Contacts",
92
- EmailFieldName: "Email",
93
- AccountIDFieldName: "AccountID",
94
- FirstNameFieldName: "FirstName",
95
- LastNameFieldName: "LastName",
96
- // ... other field mappings
97
- }
68
+ EntityName: string; // Target entity name (e.g., "Accounts")
69
+ DomainParamName: string; // Field containing company domain
70
+ AccountIDName: string; // Primary key field name
71
+ EnrichedAtField: string; // Timestamp field for tracking enrichment
72
+ ExtraFilter?: string; // SQL filter for selecting records to process
73
+
74
+ // Optional mapping fields
75
+ AddressFieldName?: string; // Street address field
76
+ CityFieldNameName?: string; // City field
77
+ StateProvinceFieldName?: string; // State/province field
78
+ PostalCodeFieldName?: string; // Postal code field
79
+ DescriptionFieldName?: string; // Company description field
80
+ PhoneNumberFieldName?: string; // Phone number field
81
+ CountryFieldName?: string; // Country field
82
+ LinkedInFieldName?: string; // LinkedIn URL field
83
+ LogoURLFieldName?: string; // Company logo URL field
84
+ FacebookFieldName?: string; // Facebook URL field
85
+ TwitterFieldName?: string; // Twitter URL field
86
+ }
87
+ ```
88
+
89
+ **AccountTechnologyEntityFieldNameJSON Structure:**
90
+ ```typescript
91
+ {
92
+ EntityName: string; // Technology relationship entity name
93
+ AccountIDFieldName: string; // Foreign key to account
94
+ TechnologyIDFieldName: string; // Foreign key to technology
95
+ MatchFoundFieldName: string; // Field indicating if match was found
96
+ EndedUseAtFieldName: string; // Field for marking end of technology use
98
97
  }
99
98
  ```
100
99
 
@@ -133,33 +132,40 @@ This action enriches contact records by matching on name and email combinations.
133
132
 
134
133
  #### Parameters
135
134
 
135
+ The action accepts the following string parameters:
136
+
137
+ **Required:**
138
+ - `EntityName` - Target entity name containing contacts
139
+ - `EmailField` - Field name containing email addresses
140
+ - `FirstNameField` - Field name containing first names
141
+ - `LastNameField` - Field name containing last names
142
+ - `AccountNameField` - Field name containing account/organization names
143
+ - `EnrichedAtField` - Field name for tracking enrichment timestamp
144
+ - `FilterParam` - SQL filter for selecting records to process
145
+
146
+ **Optional:**
147
+ - `domainParam` - Field name containing company domain
148
+ - `linkedinParam` - Field name for storing LinkedIn URLs
149
+ - `EmploymentHistoryFieldMappings` - JSON string with employment history field mappings
150
+ - `EducationHistoryFieldMappings` - JSON string with education history field mappings
151
+
152
+ **EmploymentHistoryFieldMappings Structure:**
136
153
  ```typescript
137
154
  {
138
- EntityName: "Contacts", // Target entity name
139
- EmailField: "Email", // Email field name
140
- FirstNameField: "FirstName", // First name field name
141
- LastNameField: "LastName", // Last name field name
142
- AccountNameField: "AccountName", // Account name field name
143
- EnrichedAtField: "LastEnrichedAt", // Enrichment timestamp field
144
- FilterParam: "Email IS NOT NULL", // Filter for records to enrich
145
- domainParam: "Domain", // Domain field name (optional)
146
- linkedinParam: "LinkedIn", // LinkedIn URL field name (optional)
147
-
148
- // Optional - Employment history field mappings
149
- EmploymentHistoryFieldMappings: {
150
- EmploymentHistoryEntityName: "ContactEmploymentHistory",
151
- EmploymentHistoryContactIDFieldName: "ContactID",
152
- EmploymentHistoryOrganizationFieldName: "Organization",
153
- EmploymentHistoryTitleFieldName: "Title"
154
- },
155
-
156
- // Optional - Education history field mappings
157
- EducationHistoryFieldMappings: {
158
- EducationHistoryEntityName: "ContactEducationHistory",
159
- EducationtHistoryContactIDFieldName: "ContactID",
160
- EducationtHistoryInstitutionFieldName: "Institution",
161
- EducationtHistoryDegreeFieldName: "Degree"
162
- }
155
+ EmploymentHistoryEntityName: string; // Employment history entity name
156
+ EmploymentHistoryContactIDFieldName: string; // Foreign key to contact
157
+ EmploymentHistoryOrganizationFieldName: string; // Organization name field
158
+ EmploymentHistoryTitleFieldName: string; // Job title field
159
+ }
160
+ ```
161
+
162
+ **EducationHistoryFieldMappings Structure:**
163
+ ```typescript
164
+ {
165
+ EducationHistoryEntityName: string; // Education history entity name
166
+ EducationtHistoryContactIDFieldName: string; // Foreign key to contact
167
+ EducationtHistoryInstitutionFieldName: string; // Institution name field
168
+ EducationtHistoryDegreeFieldName: string; // Degree field
163
169
  }
164
170
  ```
165
171
 
@@ -169,7 +175,7 @@ This action enriches contact records by matching on name and email combinations.
169
175
  import { ApolloContactsEnrichmentAction } from '@memberjunction/actions-apollo';
170
176
 
171
177
  const result = await engine.RunAction({
172
- ActionName: 'Apollo Enrichment - Contacts',
178
+ ActionName: 'Apollo Enrichment - Contacts',
173
179
  Params: [
174
180
  { Name: 'EntityName', Value: 'Contacts' },
175
181
  { Name: 'EmailField', Value: 'Email' },
@@ -177,7 +183,18 @@ const result = await engine.RunAction({
177
183
  { Name: 'LastNameField', Value: 'LastName' },
178
184
  { Name: 'AccountNameField', Value: 'AccountName' },
179
185
  { Name: 'EnrichedAtField', Value: 'LastEnrichedAt' },
180
- { Name: 'FilterParam', Value: 'Email IS NOT NULL AND LastEnrichedAt IS NULL' }
186
+ { Name: 'FilterParam', Value: 'Email IS NOT NULL AND LastEnrichedAt IS NULL' },
187
+ { Name: 'domainParam', Value: 'Domain' },
188
+ { Name: 'linkedinParam', Value: 'LinkedIn' },
189
+ {
190
+ Name: 'EmploymentHistoryFieldMappings',
191
+ Value: JSON.stringify({
192
+ EmploymentHistoryEntityName: 'ContactEmploymentHistory',
193
+ EmploymentHistoryContactIDFieldName: 'ContactID',
194
+ EmploymentHistoryOrganizationFieldName: 'Organization',
195
+ EmploymentHistoryTitleFieldName: 'Title'
196
+ })
197
+ }
181
198
  ],
182
199
  ContextUser: currentUser
183
200
  });
@@ -193,17 +210,21 @@ const result = await engine.RunAction({
193
210
  - Historical technology usage tracking
194
211
 
195
212
  ### Contact Enrichment
196
- - Email verification and discovery
197
- - Employment history tracking
198
- - Education history tracking
199
- - Social media profile URLs
200
- - Title exclusion filtering (excludes students, volunteers, etc.)
213
+ - Bulk email verification and discovery (up to 10 contacts per API call)
214
+ - Employment history tracking with date ranges
215
+ - Education history tracking with degree information
216
+ - Social media profile URLs (LinkedIn, Twitter, Facebook)
217
+ - Title exclusion filtering (excludes members, students, volunteers)
218
+ - Pagination support for processing large datasets
219
+ - Duplicate contact detection across accounts
201
220
 
202
221
  ### Error Handling & Rate Limiting
203
- - Automatic retry with exponential backoff for rate limits
204
- - Handles both per-minute and per-hour rate limits
205
- - Comprehensive error logging
206
- - Batch processing to optimize API usage
222
+ - Automatic retry with intelligent backoff for rate limits (1 minute for general limits, 1 hour for hourly limits)
223
+ - Handles both per-minute and per-hour rate limits with different wait times
224
+ - Comprehensive error logging using MemberJunction's logging system
225
+ - Batch processing to optimize API usage and respect Apollo.io limits
226
+ - Graceful handling of missing or incomplete data
227
+ - Transaction rollback support for failed operations
207
228
 
208
229
  ## API Integration
209
230
 
@@ -236,9 +257,12 @@ The package integrates with the following Apollo.io API endpoints:
236
257
  ## Limitations
237
258
 
238
259
  - Maximum 10 records per bulk API request (Apollo.io limitation)
239
- - Rate limits apply based on your Apollo.io subscription
260
+ - Rate limits apply based on your Apollo.io subscription (handled automatically with retries)
240
261
  - Personal emails may not be revealed in GDPR-compliant regions
241
262
  - Some enrichment data may be incomplete depending on Apollo.io's data coverage
263
+ - Account enrichment processes domains sequentially to avoid overwhelming the system
264
+ - Contact enrichment uses pagination with a maximum of 500 contacts per organization
265
+ - Excluded job titles (member, student member, student, volunteer) are automatically skipped
242
266
 
243
267
  ## Troubleshooting
244
268
 
@@ -1,25 +1,335 @@
1
1
  import { BaseAction } from "@memberjunction/actions";
2
- import { BaseEntity, Metadata, UserInfo } from "@memberjunction/core";
2
+ import { Metadata, UserInfo } from "@memberjunction/core";
3
3
  import { AxiosResponse } from "axios";
4
- import { ProcessSingleDomainParams, SearchPeopleResponsePerson, TechnologyMap } from "./generic/apollo.types";
4
+ import { ProcessSingleDomainParams, TechnologyMap } from "./generic/apollo.types";
5
5
  import { ActionResultSimple, RunActionParams } from "@memberjunction/actions-base";
6
- export declare class ApolloAccountsEnrichmentAction extends BaseAction {
7
- private ExcludeTitles;
6
+ /**
7
+ * Action that enriches account records using Apollo.io's organization and people data
8
+ *
9
+ * This action performs comprehensive account enrichment by:
10
+ * 1. Enriching organization data (address, phone, social profiles, etc.)
11
+ * 2. Creating technology stack records for the organization
12
+ * 3. Finding and enriching contacts associated with the organization
13
+ * 4. Creating employment/education history for contacts
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Basic account enrichment
18
+ * await runAction({
19
+ * ActionName: 'ApolloEnrichmentAccountsAction',
20
+ * Params: [{
21
+ * Name: 'AccountEntityFieldMappings',
22
+ * Value: JSON.stringify({
23
+ * EntityName: 'Accounts',
24
+ * Filter: 'Domain IS NOT NULL AND EnrichedAt IS NULL',
25
+ * DomainField: 'Domain',
26
+ * AccountIDField: 'ID',
27
+ * EnrichedAtField: 'EnrichedAt'
28
+ * })
29
+ * }]
30
+ * });
31
+ *
32
+ * // Full enrichment with contacts and technologies
33
+ * await runAction({
34
+ * ActionName: 'ApolloEnrichmentAccountsAction',
35
+ * Params: [{
36
+ * Name: 'AccountEntityFieldMappings',
37
+ * Value: JSON.stringify(accountConfig)
38
+ * }, {
39
+ * Name: 'ContactEntityFieldMappings',
40
+ * Value: JSON.stringify(contactConfig)
41
+ * }, {
42
+ * Name: 'AccountTechnologyEntityFieldMappings',
43
+ * Value: JSON.stringify(technologyConfig)
44
+ * }]
45
+ * });
46
+ * ```
47
+ */
48
+ export declare class ApolloEnrichmentAccountsAction extends BaseAction {
49
+ /**
50
+ * Job titles to exclude when creating contact records
51
+ * These are typically not decision-makers or relevant contacts
52
+ */
53
+ private readonly ExcludeTitles;
54
+ /**
55
+ * Main entry point for the Apollo account enrichment action
56
+ *
57
+ * @param params - The action parameters containing:
58
+ * - AccountEntityFieldMappings: Required JSON configuration for account entity field mappings
59
+ * - ContactEntityFieldMappings: Optional JSON configuration for contact entity field mappings
60
+ * - AccountTechnologyEntityFieldMappings: Optional JSON configuration for technology tracking
61
+ * - TechnologyCategoryEntityFieldMappings: Optional JSON configuration for technology categories
62
+ * - ContactEducationHistoryEntityFieldMappings: Optional JSON configuration for education history
63
+ *
64
+ * @returns Promise<ActionResultSimple> indicating success/failure and any error messages
65
+ */
8
66
  protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
67
+ /**
68
+ * Validates that the Apollo.io API key is configured properly
69
+ * @returns Validation result with success flag and potential error details
70
+ */
71
+ private validateConfiguration;
72
+ /**
73
+ * Extracts and validates all action parameters from the request
74
+ *
75
+ * @param params - The action parameters containing JSON configurations
76
+ * @returns Object with success flag, validated parameters, or error details
77
+ */
78
+ private extractAndValidateParameters;
79
+ /**
80
+ * Gets a required parameter from the action parameters
81
+ * @param params - The action parameters
82
+ * @param paramName - Name of the required parameter
83
+ * @returns The parameter if found, null otherwise
84
+ */
85
+ private getRequiredParam;
86
+ /**
87
+ * Parses an optional JSON parameter with error handling
88
+ * @param params - The action parameters
89
+ * @param paramName - Name of the optional JSON parameter
90
+ * @returns Parsed object of type T or null if not provided/invalid
91
+ */
92
+ private parseOptionalJSONParam;
93
+ /**
94
+ * Parses a parameter value that may be a JSON string or already parsed object
95
+ * Handles the case where action parameters ending with JSON can be either strings or objects
96
+ *
97
+ * @param value - The parameter value to parse (string or object)
98
+ * @returns Parsed object of type T
99
+ * @throws Error if value cannot be parsed as JSON (when it's a string)
100
+ */
101
+ private parseJSONParam;
102
+ /**
103
+ * Recursively processes all account records that match the filter criteria
104
+ * Uses batching and concurrency control to handle large datasets efficiently
105
+ *
106
+ * @param actionParams - Validated action parameters with entity field mappings
107
+ * @param contextUser - User context for data access and security
108
+ * @param executionCount - Current execution count to prevent infinite recursion (max 5)
109
+ * @returns Promise indicating overall success/failure of the batch
110
+ */
111
+ private processAllAccountRecords;
112
+ /**
113
+ * Processes account records in concurrent groups to optimize performance
114
+ * Respects the configured concurrency limit to avoid overwhelming APIs
115
+ *
116
+ * @param results - Array of account records to process
117
+ * @param actionParams - Configuration parameters for enrichment
118
+ * @param md - Metadata instance for entity operations
119
+ * @param contextUser - User context for data access
120
+ */
121
+ private processAccountGroups;
122
+ /**
123
+ * Processes a single domain for both organization and people enrichment
124
+ * This is the main orchestration method for enriching one account
125
+ *
126
+ * @param params - Domain processing parameters with entity configurations
127
+ * @param startRow - Current row number for progress tracking
128
+ * @param totalRows - Total number of rows for progress tracking
129
+ * @param md - Metadata instance for entity operations
130
+ * @param currentUser - User context for data access
131
+ * @returns Promise<boolean> indicating success/failure of domain processing
132
+ */
9
133
  protected ProcessSingleDomain(params: ProcessSingleDomainParams, startRow: number, totalRows: number, md: Metadata, currentUser: UserInfo): Promise<boolean>;
10
- protected EnrichOrganization(params: ProcessSingleDomainParams, startRow: number, totalRows: number, md: Metadata, currentUser: UserInfo): Promise<boolean>;
134
+ /**
135
+ * Enriches organization data using Apollo.io's organization enrichment endpoint
136
+ * Updates account record with company information and triggers technology processing
137
+ *
138
+ * @param params - Domain processing parameters
139
+ * @param startRow - Current row for progress tracking
140
+ * @param totalRows - Total rows for progress tracking
141
+ * @param md - Metadata instance for entity operations
142
+ * @param currentUser - User context for data access
143
+ * @returns Promise<boolean> indicating success/failure
144
+ */
145
+ private enrichOrganization;
146
+ /**
147
+ * Updates an account entity with enriched organization data from Apollo.io
148
+ * Maps Apollo organization fields to the configured account entity fields
149
+ *
150
+ * @param organization - Apollo organization data
151
+ * @param params - Processing parameters with field mappings
152
+ * @param record - Current account record data
153
+ * @param md - Metadata instance for entity operations
154
+ * @param currentUser - User context for data access
155
+ * @returns Promise<boolean> indicating save success/failure
156
+ */
157
+ private updateAccountWithOrganizationData;
158
+ /**
159
+ * Updates the enrichment timestamp on an account even when no data was found
160
+ * Prevents repeated attempts to enrich accounts with no Apollo data
161
+ *
162
+ * @param params - Processing parameters with field mappings
163
+ * @param record - Current account record data
164
+ * @param md - Metadata instance for entity operations
165
+ * @param currentUser - User context for data access
166
+ * @returns Promise<boolean> indicating save success/failure
167
+ */
168
+ private updateAccountEnrichedTimestamp;
169
+ /**
170
+ * Safely sets a field on an entity if the field name is defined and value is not null
171
+ * Prevents errors from undefined field mappings
172
+ *
173
+ * @param entity - Target entity to update
174
+ * @param fieldName - Name of the field (can be undefined)
175
+ * @param value - Value to set (checked for null/undefined)
176
+ */
177
+ private setFieldIfExists;
178
+ /**
179
+ * Creates or updates technology records associated with an account
180
+ * Manages the relationship between accounts and their technology stack
181
+ * Marks old technologies as ended if no longer detected
182
+ *
183
+ * @param params - Processing parameters with technology entity configuration
184
+ * @param accountID - ID of the account to associate technologies with
185
+ * @param technologies - Array of technology data from Apollo
186
+ * @param md - Metadata instance for entity operations
187
+ * @param currentUser - User context for data access
188
+ * @returns Promise<boolean> indicating overall success/failure
189
+ */
11
190
  protected CreateAccountTechnologyRecords(params: ProcessSingleDomainParams, accountID: string | number, technologies: TechnologyMap[], md: Metadata, currentUser: UserInfo): Promise<boolean>;
12
- protected GetOrCreateTechnologyCategoryId(params: ProcessSingleDomainParams, categoryName: string, md: Metadata, currentUser: UserInfo): Promise<number>;
13
- protected GetOrCreateTechnologyId(name: string, categoryId: number, md: Metadata, currentUser: UserInfo): Promise<number>;
14
- protected CreateAndEnrichPeople(params: ProcessSingleDomainParams, accountID: string | number, domain: string, startRow: number, md: Metadata, currentUser: UserInfo): Promise<boolean>;
15
- protected CreateAndEnrichContact(params: ProcessSingleDomainParams, accountID: string | number, person: SearchPeopleResponsePerson, md: Metadata, currentUser: UserInfo, sequence: number, total: number): Promise<boolean>;
16
- protected GetOrCreateContact(params: ProcessSingleDomainParams, accountID: number | string, person: SearchPeopleResponsePerson, md: Metadata, currentUser: UserInfo): Promise<BaseEntity | null>;
17
- protected CreateUpdateContactEmploymentAndEducationHistory(params: ProcessSingleDomainParams, contactID: number | string, person: SearchPeopleResponsePerson, md: Metadata, currentUser: UserInfo): Promise<boolean>;
191
+ /**
192
+ * Gets or creates a technology category record by name
193
+ * Ensures technology categories exist before creating technology records
194
+ *
195
+ * @param params - Processing parameters with category entity configuration
196
+ * @param categoryName - Name of the technology category
197
+ * @param md - Metadata instance for entity operations
198
+ * @param currentUser - User context for data access
199
+ * @returns Promise<number> - ID of the category (0 if error)
200
+ */
201
+ private getOrCreateTechnologyCategoryId;
202
+ /**
203
+ * Gets or creates a technology record by name and category
204
+ * Maintains referential integrity between technologies and categories
205
+ *
206
+ * @param name - Name of the technology
207
+ * @param categoryId - ID of the technology category
208
+ * @param md - Metadata instance for entity operations
209
+ * @param currentUser - User context for data access
210
+ * @returns Promise<number> - ID of the technology (0 if error)
211
+ */
212
+ private getOrCreateTechnologyId;
213
+ /**
214
+ * Searches for and enriches people associated with an organization's domain
215
+ * Uses Apollo's people search to find contacts at the organization
216
+ * Handles pagination to retrieve all available contacts (up to configured limit)
217
+ *
218
+ * @param params - Processing parameters with contact entity configuration
219
+ * @param accountID - ID of the account to associate contacts with
220
+ * @param domain - Organization domain to search for people
221
+ * @param startRow - Current row for progress tracking
222
+ * @param md - Metadata instance for entity operations
223
+ * @param currentUser - User context for data access
224
+ * @returns Promise<boolean> indicating success/failure of people processing
225
+ */
226
+ private createAndEnrichPeople;
227
+ /**
228
+ * Determines if a person should be skipped during contact creation
229
+ * Filters out people with missing data or excluded job titles
230
+ *
231
+ * @param person - Person data from Apollo search response
232
+ * @param domain - Expected domain for email validation
233
+ * @returns boolean - true if person should be skipped
234
+ */
235
+ private shouldSkipPerson;
236
+ /**
237
+ * Creates or updates a contact record with enriched data from Apollo
238
+ * Handles contact deduplication and data validation
239
+ *
240
+ * @param params - Processing parameters with contact entity configuration
241
+ * @param accountID - ID of the account to associate contact with
242
+ * @param person - Person data from Apollo search response
243
+ * @param md - Metadata instance for entity operations
244
+ * @param currentUser - User context for data access
245
+ * @param sequence - Current contact number for progress tracking
246
+ * @param total - Total contacts for progress tracking
247
+ * @returns Promise<boolean> indicating success/failure
248
+ */
249
+ private createAndEnrichContact;
250
+ /**
251
+ * Updates contact entity fields with person data from Apollo
252
+ * Maps Apollo person fields to the configured contact entity fields
253
+ *
254
+ * @param contact - Contact entity to update
255
+ * @param person - Person data from Apollo
256
+ * @param CEntity - Contact entity field name mappings
257
+ */
258
+ private updateContactFields;
259
+ /**
260
+ * Gets an existing contact or creates a new one with conflict detection
261
+ * Prevents duplicate contacts across different accounts
262
+ * Supports matching by email or name combination
263
+ *
264
+ * @param params - Processing parameters with contact entity configuration
265
+ * @param accountID - ID of the account to associate contact with
266
+ * @param person - Person data from Apollo
267
+ * @param md - Metadata instance for entity operations
268
+ * @param currentUser - User context for data access
269
+ * @returns Promise<BaseEntity | null> - Contact entity or null if conflict/error
270
+ */
271
+ private getOrCreateContact;
272
+ /**
273
+ * Creates or updates employment and education history records for a contact
274
+ * Processes Apollo employment history data to create education records
275
+ *
276
+ * @param params - Processing parameters with education entity configuration
277
+ * @param contactID - ID of the contact to create history for
278
+ * @param person - Person data containing employment history
279
+ * @param md - Metadata instance for entity operations
280
+ * @param currentUser - User context for data access
281
+ * @returns Promise<boolean> indicating success/failure
282
+ */
283
+ private createUpdateContactEmploymentAndEducationHistory;
284
+ /**
285
+ * Validates if a date string represents a valid date
286
+ * Used for employment/education history date validation
287
+ *
288
+ * @param dateString - Date string to validate
289
+ * @returns boolean - true if valid date
290
+ */
18
291
  protected IsValidDate(dateString: string): boolean;
292
+ /**
293
+ * Checks if a job title should be excluded from contact creation
294
+ * Filters out non-business contacts like students and volunteers
295
+ *
296
+ * @param title - Job title to check
297
+ * @returns boolean - true if title should be excluded
298
+ */
19
299
  protected IsExcludedTitle(title: string): boolean;
300
+ /**
301
+ * Escapes single quotes in strings for SQL query safety
302
+ * Prevents SQL injection in dynamic filter construction
303
+ *
304
+ * @param str - String to escape
305
+ * @returns string - Escaped string with doubled single quotes
306
+ */
20
307
  protected EscapeSingleQuotes(str: string): string;
308
+ /**
309
+ * Wraps Apollo.io API calls with retry logic for rate limiting
310
+ * Handles 429 (Too Many Requests) responses with exponential backoff
311
+ *
312
+ * @param method - HTTP method ('get' or 'post')
313
+ * @param endpoint - Apollo API endpoint path
314
+ * @param data - Request payload for POST requests
315
+ * @param config - Axios configuration object
316
+ * @param retryAttempts - Number of retry attempts remaining (default: 1)
317
+ * @returns Promise<AxiosResponse> - Apollo API response
318
+ * @throws Error if rate limit exceeded or other API errors
319
+ */
21
320
  protected WrapApolloCall(method: 'get' | 'post', endpoint: string, data: any, config: any, retryAttempts?: number): Promise<AxiosResponse>;
321
+ /**
322
+ * Utility method for creating delays in async operations
323
+ * Used for rate limit backoff and API throttling
324
+ *
325
+ * @param ms - Number of milliseconds to wait
326
+ * @returns Promise that resolves after the specified delay
327
+ */
22
328
  private Timeout;
23
329
  }
330
+ /**
331
+ * Loader function to ensure the ApolloEnrichmentAccountsAction class is included in the bundle
332
+ * Prevents tree shaking from removing this action class
333
+ */
24
334
  export declare function LoadApolloAccountsEnrichmentAction(): void;
25
335
  //# sourceMappingURL=accounts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../src/accounts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../src/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAGrD,OAAO,EAAmC,QAAQ,EAAW,QAAQ,EAAgB,MAAM,sBAAsB,CAAC;AAClH,OAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAoJ,yBAAyB,EAAoF,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtT,OAAO,EAAe,kBAAkB,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAchG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,qBACa,8BAA+B,SAAQ,UAAU;IAC1D;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkE;IAEhG;;;;;;;;;;;OAWG;cACa,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA4BvF;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;;;;OAKG;IACH,OAAO,CAAC,4BAA4B;IAoDpC;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;;;;OAKG;IACH,OAAO,CAAC,sBAAsB;IAc9B;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAetB;;;;;;;;OAQG;YACW,wBAAwB;IAoDtC;;;;;;;;OAQG;YACW,oBAAoB;IA6BlC;;;;;;;;;;OAUG;cACa,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAWlK;;;;;;;;;;OAUG;YACW,kBAAkB;IA2ChC;;;;;;;;;;OAUG;YACW,iCAAiC;IAoC/C;;;;;;;;;OASG;YACW,8BAA8B;IAsB5C;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;;;;;;;;;;OAWG;cACa,8BAA8B,CAAC,MAAM,EAAE,yBAAyB,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAiEnM;;;;;;;;;OASG;YACW,+BAA+B;IAwC7C;;;;;;;;;OASG;YACW,uBAAuB;IAoCrC;;;;;;;;;;;;OAYG;YACW,qBAAqB;IAkEnC;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;;;;;;;OAYG;YACW,sBAAsB;IAmCpC;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAgB3B;;;;;;;;;;;OAWG;YACW,kBAAkB;IA6DhC;;;;;;;;;;OAUG;YACW,gDAAgD;IA+D9D;;;;;;OAMG;IACH,SAAS,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAQlD;;;;;;OAMG;IACH,SAAS,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAOjD;;;;;;OAMG;IACH,SAAS,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAOjD;;;;;;;;;;;OAWG;cACa,cAAc,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAE,MAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAoCnJ;;;;;;OAMG;YACW,OAAO;CAGxB;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,SAEjD"}