@memberjunction/integration-connectors 5.8.0 → 5.9.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/HubSpotConnector.d.ts +84 -29
- package/dist/HubSpotConnector.d.ts.map +1 -1
- package/dist/HubSpotConnector.js +413 -71
- package/dist/HubSpotConnector.js.map +1 -1
- package/dist/YourMembershipConnector.d.ts +106 -39
- package/dist/YourMembershipConnector.d.ts.map +1 -1
- package/dist/YourMembershipConnector.js +568 -362
- package/dist/YourMembershipConnector.js.map +1 -1
- package/package.json +5 -5
package/dist/HubSpotConnector.js
CHANGED
|
@@ -5,96 +5,438 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { RegisterClass } from '@memberjunction/global';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const HS_CONTACTS_DELETED_FIELD = 'is_deleted';
|
|
8
|
+
import { Metadata } from '@memberjunction/core';
|
|
9
|
+
import { BaseIntegrationConnector, BaseRESTIntegrationConnector, } from '@memberjunction/integration-engine';
|
|
10
|
+
// ─── Constants ────────────────────────────────────────────────────────
|
|
11
|
+
const HUBSPOT_API_BASE = 'https://api.hubapi.com';
|
|
12
|
+
const DEFAULT_API_VERSION = 'v3';
|
|
13
|
+
/** Maximum retries for rate-limited or failed requests */
|
|
14
|
+
const MAX_RETRIES = 5;
|
|
15
|
+
/** HTTP request timeout in milliseconds */
|
|
16
|
+
const REQUEST_TIMEOUT_MS = 30000;
|
|
17
|
+
/** Minimum milliseconds between API requests (HubSpot: 100 req/10s for private apps) */
|
|
18
|
+
const MIN_REQUEST_INTERVAL_MS = 100;
|
|
20
19
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* Known properties to request per object type. HubSpot's list endpoint
|
|
21
|
+
* only returns a handful of default properties unless you explicitly
|
|
22
|
+
* specify which properties to include via the `properties` query param.
|
|
24
23
|
*/
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
const HUBSPOT_PROPERTIES = {
|
|
25
|
+
contacts: [
|
|
26
|
+
'email', 'firstname', 'lastname', 'phone', 'mobilephone', 'company',
|
|
27
|
+
'jobtitle', 'lifecyclestage', 'hs_lead_status', 'address', 'city',
|
|
28
|
+
'state', 'zip', 'country', 'website', 'industry',
|
|
29
|
+
'annualrevenue', 'numberofemployees', 'hs_object_id',
|
|
30
|
+
'createdate', 'lastmodifieddate', 'associatedcompanyid',
|
|
31
|
+
'notes_last_contacted', 'notes_last_updated', 'hs_email_optout',
|
|
32
|
+
],
|
|
33
|
+
companies: [
|
|
34
|
+
'name', 'domain', 'industry', 'phone', 'address', 'address2',
|
|
35
|
+
'city', 'state', 'zip', 'country', 'website', 'description',
|
|
36
|
+
'numberofemployees', 'annualrevenue', 'lifecyclestage',
|
|
37
|
+
'type', 'hs_object_id', 'createdate', 'hs_lastmodifieddate',
|
|
38
|
+
'founded_year', 'is_public',
|
|
39
|
+
],
|
|
40
|
+
deals: [
|
|
41
|
+
'dealname', 'amount', 'dealstage', 'pipeline', 'closedate',
|
|
42
|
+
'createdate', 'hs_object_id', 'hs_lastmodifieddate',
|
|
43
|
+
'dealtype', 'description', 'hs_deal_stage_probability',
|
|
44
|
+
'hs_projected_amount', 'hs_priority', 'hubspot_owner_id',
|
|
45
|
+
'notes_last_contacted', 'num_associated_contacts',
|
|
46
|
+
],
|
|
47
|
+
tickets: [
|
|
48
|
+
'subject', 'content', 'hs_pipeline', 'hs_pipeline_stage',
|
|
49
|
+
'hs_ticket_priority', 'hs_ticket_category', 'createdate',
|
|
50
|
+
'hs_lastmodifieddate', 'hs_object_id', 'closed_date',
|
|
51
|
+
'source_type', 'hubspot_owner_id',
|
|
52
|
+
],
|
|
53
|
+
products: [
|
|
54
|
+
'name', 'description', 'price', 'hs_cost_of_goods_sold',
|
|
55
|
+
'hs_recurring_billing_period', 'hs_sku', 'tax',
|
|
56
|
+
'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
57
|
+
],
|
|
58
|
+
line_items: [
|
|
59
|
+
'name', 'description', 'quantity', 'price', 'amount',
|
|
60
|
+
'discount', 'tax', 'hs_product_id', 'hs_line_item_currency_code',
|
|
61
|
+
'hs_sku', 'hs_cost_of_goods_sold', 'hs_recurring_billing_period',
|
|
62
|
+
'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
63
|
+
],
|
|
64
|
+
quotes: [
|
|
65
|
+
'hs_title', 'hs_expiration_date', 'hs_status', 'hs_quote_amount',
|
|
66
|
+
'hs_currency', 'hs_sender_firstname', 'hs_sender_lastname',
|
|
67
|
+
'hs_sender_email', 'hs_sender_company_name', 'hs_language',
|
|
68
|
+
'hs_locale', 'hs_slug', 'hs_public_url_key',
|
|
69
|
+
'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
70
|
+
],
|
|
71
|
+
calls: [
|
|
72
|
+
'hs_call_title', 'hs_call_body', 'hs_call_status',
|
|
73
|
+
'hs_call_direction', 'hs_call_duration', 'hs_call_from_number',
|
|
74
|
+
'hs_call_to_number', 'hs_call_disposition',
|
|
75
|
+
'hs_call_recording_url', 'hubspot_owner_id',
|
|
76
|
+
'hs_timestamp', 'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
77
|
+
],
|
|
78
|
+
emails: [
|
|
79
|
+
'hs_email_subject', 'hs_email_text', 'hs_email_html',
|
|
80
|
+
'hs_email_status', 'hs_email_direction',
|
|
81
|
+
'hs_email_sender_email', 'hs_email_sender_firstname',
|
|
82
|
+
'hs_email_sender_lastname', 'hs_email_to_email',
|
|
83
|
+
'hubspot_owner_id',
|
|
84
|
+
'hs_timestamp', 'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
85
|
+
],
|
|
86
|
+
notes: [
|
|
87
|
+
'hs_note_body', 'hs_timestamp', 'hubspot_owner_id',
|
|
88
|
+
'hs_attachment_ids', 'hs_body_preview', 'hs_body_preview_is_truncated',
|
|
89
|
+
'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
90
|
+
],
|
|
91
|
+
tasks: [
|
|
92
|
+
'hs_task_subject', 'hs_task_body', 'hs_task_status',
|
|
93
|
+
'hs_task_priority', 'hs_task_type', 'hs_timestamp',
|
|
94
|
+
'hs_task_completion_date', 'hs_queue_membership_ids',
|
|
95
|
+
'hubspot_owner_id',
|
|
96
|
+
'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
97
|
+
],
|
|
98
|
+
meetings: [
|
|
99
|
+
'hs_meeting_title', 'hs_meeting_body', 'hs_meeting_start_time',
|
|
100
|
+
'hs_meeting_end_time', 'hs_meeting_outcome', 'hs_meeting_location',
|
|
101
|
+
'hs_meeting_external_url', 'hs_internal_meeting_notes',
|
|
102
|
+
'hs_activity_type', 'hubspot_owner_id',
|
|
103
|
+
'hs_timestamp', 'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
104
|
+
],
|
|
105
|
+
feedback_submissions: [
|
|
106
|
+
'hs_survey_id', 'hs_survey_name', 'hs_survey_type',
|
|
107
|
+
'hs_submission_name', 'hs_content', 'hs_response_group',
|
|
108
|
+
'hs_sentiment', 'hs_survey_channel',
|
|
109
|
+
'hs_timestamp', 'createdate', 'hs_lastmodifieddate', 'hs_object_id',
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
// ─── Connector ────────────────────────────────────────────────────────
|
|
113
|
+
/**
|
|
114
|
+
* Connector for HubSpot CRM via the HubSpot REST API v3.
|
|
115
|
+
*
|
|
116
|
+
* Extends BaseRESTIntegrationConnector to leverage metadata-driven object/field
|
|
117
|
+
* discovery from IntegrationEngineBase cache and generic pagination handling.
|
|
118
|
+
*
|
|
119
|
+
* Uses Bearer token authentication (private app key or OAuth access token).
|
|
120
|
+
* Supports cursor-based pagination and automatic response flattening.
|
|
121
|
+
*
|
|
122
|
+
* DATA SAFETY: This connector is READ-ONLY. It never writes data back to HubSpot.
|
|
123
|
+
*/
|
|
124
|
+
let HubSpotConnector = class HubSpotConnector extends BaseRESTIntegrationConnector {
|
|
125
|
+
constructor() {
|
|
126
|
+
super(...arguments);
|
|
127
|
+
/** Timestamp of the last API request, used for throttling */
|
|
128
|
+
this.lastRequestTime = 0;
|
|
129
|
+
}
|
|
130
|
+
// ─── Abstract method implementations (BaseRESTIntegrationConnector) ──
|
|
131
|
+
async Authenticate(companyIntegration) {
|
|
132
|
+
const credentials = await this.LoadCredentials(companyIntegration);
|
|
133
|
+
const auth = {
|
|
134
|
+
Token: credentials.AccessToken,
|
|
135
|
+
Credentials: credentials,
|
|
136
|
+
};
|
|
137
|
+
return auth;
|
|
138
|
+
}
|
|
139
|
+
BuildHeaders(auth) {
|
|
140
|
+
return {
|
|
141
|
+
'Authorization': `Bearer ${auth.Token}`,
|
|
142
|
+
'Accept': 'application/json',
|
|
143
|
+
};
|
|
36
144
|
}
|
|
145
|
+
async MakeHTTPRequest(_auth, url, method, headers, _body) {
|
|
146
|
+
// Throttle: ensure minimum interval between requests
|
|
147
|
+
const elapsed = Date.now() - this.lastRequestTime;
|
|
148
|
+
if (elapsed < MIN_REQUEST_INTERVAL_MS) {
|
|
149
|
+
await this.Sleep(MIN_REQUEST_INTERVAL_MS - elapsed);
|
|
150
|
+
}
|
|
151
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
152
|
+
const response = await this.FetchWithTimeout(url, method, headers);
|
|
153
|
+
this.lastRequestTime = Date.now();
|
|
154
|
+
if (response.status === 429) {
|
|
155
|
+
const delayMs = this.CalculateRetryDelay(response, attempt);
|
|
156
|
+
console.warn(`[HubSpot] Rate limited (429), retrying in ${delayMs}ms ` +
|
|
157
|
+
`(attempt ${attempt + 1}/${MAX_RETRIES})`);
|
|
158
|
+
await this.Sleep(delayMs);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const body = await response.json();
|
|
162
|
+
return this.BuildRESTResponse(response, body);
|
|
163
|
+
}
|
|
164
|
+
throw new Error(`HubSpot API request failed after ${MAX_RETRIES} retries: ${url}`);
|
|
165
|
+
}
|
|
166
|
+
NormalizeResponse(rawBody, responseDataKey) {
|
|
167
|
+
const body = rawBody;
|
|
168
|
+
// Extract the records array using the responseDataKey (typically "results")
|
|
169
|
+
let records;
|
|
170
|
+
if (responseDataKey != null) {
|
|
171
|
+
const data = body[responseDataKey];
|
|
172
|
+
if (!data || !Array.isArray(data))
|
|
173
|
+
return [];
|
|
174
|
+
records = data;
|
|
175
|
+
}
|
|
176
|
+
else if (Array.isArray(rawBody)) {
|
|
177
|
+
records = rawBody;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
return [];
|
|
181
|
+
}
|
|
182
|
+
// Flatten HubSpot's nested { id, properties: {...}, createdAt, updatedAt, archived }
|
|
183
|
+
return records.map(r => this.FlattenHubSpotRecord(r));
|
|
184
|
+
}
|
|
185
|
+
ExtractPaginationInfo(rawBody, _paginationType, _currentPage, _currentOffset, _pageSize) {
|
|
186
|
+
const body = rawBody;
|
|
187
|
+
const paging = body['paging'];
|
|
188
|
+
const nextCursor = paging?.next?.after;
|
|
189
|
+
if (nextCursor) {
|
|
190
|
+
return { HasMore: true, NextCursor: nextCursor };
|
|
191
|
+
}
|
|
192
|
+
return { HasMore: false };
|
|
193
|
+
}
|
|
194
|
+
GetBaseURL(_companyIntegration) {
|
|
195
|
+
return HUBSPOT_API_BASE;
|
|
196
|
+
}
|
|
197
|
+
// ─── HubSpot-specific pagination ─────────────────────────────────
|
|
37
198
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* @returns Array of default field mappings
|
|
199
|
+
* Overrides base pagination URL building to use HubSpot's parameter names.
|
|
200
|
+
* HubSpot uses `after` for cursor pagination (not `cursor`), and needs
|
|
201
|
+
* `limit` instead of `pageSize`. Also appends `properties` query param.
|
|
42
202
|
*/
|
|
203
|
+
BuildPaginatedURL(basePath, obj, _page, _offset, cursor) {
|
|
204
|
+
const separator = basePath.includes('?') ? '&' : '?';
|
|
205
|
+
const objectName = this.ExtractObjectNameFromPath(basePath);
|
|
206
|
+
const propertiesParam = this.BuildPropertiesParam(objectName);
|
|
207
|
+
if (cursor) {
|
|
208
|
+
return `${basePath}${separator}limit=${obj.DefaultPageSize}&after=${encodeURIComponent(cursor)}${propertiesParam}`;
|
|
209
|
+
}
|
|
210
|
+
return `${basePath}${separator}limit=${obj.DefaultPageSize}${propertiesParam}`;
|
|
211
|
+
}
|
|
212
|
+
// ─── TestConnection ─────────────────────────────────────────────
|
|
213
|
+
/** Tests connectivity by authenticating and fetching 1 contact. */
|
|
214
|
+
async TestConnection(companyIntegration, _contextUser) {
|
|
215
|
+
try {
|
|
216
|
+
const auth = await this.Authenticate(companyIntegration);
|
|
217
|
+
const headers = this.BuildHeaders(auth);
|
|
218
|
+
const response = await this.MakeHTTPRequest(auth, `${HUBSPOT_API_BASE}/crm/v3/objects/contacts?limit=1`, 'GET', headers);
|
|
219
|
+
if (response.Status >= 200 && response.Status < 300) {
|
|
220
|
+
const hubSpotAuth = auth;
|
|
221
|
+
return {
|
|
222
|
+
Success: true,
|
|
223
|
+
Message: 'Successfully connected to HubSpot CRM API',
|
|
224
|
+
ServerVersion: `HubSpot CRM API ${hubSpotAuth.Credentials.ApiVersion}`,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const bodyPreview = typeof response.Body === 'string'
|
|
228
|
+
? response.Body.slice(0, 500)
|
|
229
|
+
: JSON.stringify(response.Body).slice(0, 500);
|
|
230
|
+
return {
|
|
231
|
+
Success: false,
|
|
232
|
+
Message: `HubSpot API returned ${response.Status}: ${bodyPreview}`,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
237
|
+
return { Success: false, Message: `Connection failed: ${message}` };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// ─── GetDefaultFieldMappings ──────────────────────────────────
|
|
43
241
|
GetDefaultFieldMappings(objectName, _entityName) {
|
|
44
242
|
switch (objectName) {
|
|
45
243
|
case 'contacts':
|
|
46
|
-
return
|
|
244
|
+
return [
|
|
245
|
+
{ SourceFieldName: 'email', DestinationFieldName: 'Email', IsKeyField: true },
|
|
246
|
+
{ SourceFieldName: 'firstname', DestinationFieldName: 'FirstName' },
|
|
247
|
+
{ SourceFieldName: 'lastname', DestinationFieldName: 'LastName' },
|
|
248
|
+
{ SourceFieldName: 'phone', DestinationFieldName: 'Phone' },
|
|
249
|
+
{ SourceFieldName: 'company', DestinationFieldName: 'CompanyName' },
|
|
250
|
+
{ SourceFieldName: 'lifecyclestage', DestinationFieldName: 'Status' },
|
|
251
|
+
];
|
|
47
252
|
case 'companies':
|
|
48
|
-
return
|
|
253
|
+
return [
|
|
254
|
+
{ SourceFieldName: 'name', DestinationFieldName: 'Name', IsKeyField: true },
|
|
255
|
+
{ SourceFieldName: 'domain', DestinationFieldName: 'Website' },
|
|
256
|
+
{ SourceFieldName: 'industry', DestinationFieldName: 'Industry' },
|
|
257
|
+
{ SourceFieldName: 'city', DestinationFieldName: 'City' },
|
|
258
|
+
{ SourceFieldName: 'state', DestinationFieldName: 'State' },
|
|
259
|
+
];
|
|
260
|
+
case 'deals':
|
|
261
|
+
return [
|
|
262
|
+
{ SourceFieldName: 'dealname', DestinationFieldName: 'Name', IsKeyField: true },
|
|
263
|
+
{ SourceFieldName: 'amount', DestinationFieldName: 'Amount' },
|
|
264
|
+
{ SourceFieldName: 'dealstage', DestinationFieldName: 'Stage' },
|
|
265
|
+
{ SourceFieldName: 'closedate', DestinationFieldName: 'CloseDate' },
|
|
266
|
+
{ SourceFieldName: 'pipeline', DestinationFieldName: 'Pipeline' },
|
|
267
|
+
];
|
|
49
268
|
default:
|
|
50
269
|
return [];
|
|
51
270
|
}
|
|
52
271
|
}
|
|
272
|
+
// ─── Default Configuration ──────────────────────────────────────
|
|
273
|
+
GetDefaultConfiguration() {
|
|
274
|
+
return {
|
|
275
|
+
DefaultSchemaName: 'HubSpot',
|
|
276
|
+
DefaultObjects: [], // Objects are auto-discovered from metadata via DiscoverObjects
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// ─── Schema Discovery Helpers ────────────────────────────────────
|
|
280
|
+
/** Converts a HubSpot property definition to ExternalFieldSchema format */
|
|
281
|
+
MapPropertyToField(prop) {
|
|
282
|
+
return {
|
|
283
|
+
Name: prop.name,
|
|
284
|
+
Label: prop.label || prop.name,
|
|
285
|
+
DataType: this.MapHubSpotType(prop.type, prop.fieldType),
|
|
286
|
+
IsRequired: false, // HubSpot doesn't expose required via properties API
|
|
287
|
+
IsUniqueKey: prop.hasUniqueValue,
|
|
288
|
+
IsReadOnly: prop.calculated || (prop.modificationMetadata?.readOnlyValue ?? false),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
/** Maps HubSpot type + fieldType to a simplified data type string */
|
|
292
|
+
MapHubSpotType(type, fieldType) {
|
|
293
|
+
switch (type) {
|
|
294
|
+
case 'string':
|
|
295
|
+
if (fieldType === 'textarea')
|
|
296
|
+
return 'text';
|
|
297
|
+
if (fieldType === 'html')
|
|
298
|
+
return 'html';
|
|
299
|
+
return 'string';
|
|
300
|
+
case 'number':
|
|
301
|
+
return 'number';
|
|
302
|
+
case 'date':
|
|
303
|
+
case 'datetime':
|
|
304
|
+
return 'datetime';
|
|
305
|
+
case 'bool':
|
|
306
|
+
return 'boolean';
|
|
307
|
+
case 'enumeration':
|
|
308
|
+
return 'enum';
|
|
309
|
+
default:
|
|
310
|
+
return type;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
// ─── Credential management ────────────────────────────────────
|
|
53
314
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* @returns Column name for the primary key
|
|
315
|
+
* Reads credentials from CompanyIntegration.CredentialID -> Credential.Values JSON,
|
|
316
|
+
* or falls back to CompanyIntegration Configuration JSON for backwards compat.
|
|
57
317
|
*/
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
318
|
+
async LoadCredentials(companyIntegration) {
|
|
319
|
+
// Try loading from linked Credential entity first
|
|
320
|
+
const credentialID = companyIntegration.Get('CredentialID');
|
|
321
|
+
if (credentialID) {
|
|
322
|
+
const creds = await this.LoadFromCredentialEntity(credentialID);
|
|
323
|
+
if (creds)
|
|
324
|
+
return creds;
|
|
64
325
|
}
|
|
326
|
+
// Fallback: read from CompanyIntegration Configuration JSON
|
|
327
|
+
const configJson = companyIntegration.Get('Configuration');
|
|
328
|
+
if (configJson) {
|
|
329
|
+
const creds = this.ParseCredentialJson(configJson);
|
|
330
|
+
if (creds)
|
|
331
|
+
return creds;
|
|
332
|
+
}
|
|
333
|
+
throw new Error('No HubSpot credentials found. Attach a credential with an accessToken or apiKey, ' +
|
|
334
|
+
'or set Configuration JSON on the CompanyIntegration.');
|
|
335
|
+
}
|
|
336
|
+
/** Loads credentials from a Credential entity by ID. */
|
|
337
|
+
async LoadFromCredentialEntity(credentialID) {
|
|
338
|
+
const md = new Metadata();
|
|
339
|
+
const credential = await md.GetEntityObject('MJ: Credentials');
|
|
340
|
+
const loaded = await credential.Load(credentialID);
|
|
341
|
+
if (!loaded || !credential.Values)
|
|
342
|
+
return null;
|
|
343
|
+
return this.ParseCredentialJson(credential.Values);
|
|
65
344
|
}
|
|
345
|
+
/** Parses a JSON string to extract HubSpot credentials. Returns null if no token found. */
|
|
346
|
+
ParseCredentialJson(json) {
|
|
347
|
+
try {
|
|
348
|
+
const parsed = JSON.parse(json);
|
|
349
|
+
const token = parsed['accessToken'] ?? parsed['AccessToken'] ?? parsed['apiKey'] ?? parsed['ApiKey'];
|
|
350
|
+
if (token) {
|
|
351
|
+
return {
|
|
352
|
+
AccessToken: token,
|
|
353
|
+
ApiVersion: parsed['apiVersion'] ?? DEFAULT_API_VERSION,
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// ─── Response flattening ─────────────────────────────────────────
|
|
66
363
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
364
|
+
* Flattens a HubSpot CRM record from the nested format:
|
|
365
|
+
* { id, properties: { field1, field2 }, createdAt, updatedAt, archived }
|
|
366
|
+
* into a flat record with all properties at the top level,
|
|
367
|
+
* plus system fields (hs_object_id, createdAt, updatedAt, archived).
|
|
71
368
|
*/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
369
|
+
FlattenHubSpotRecord(record) {
|
|
370
|
+
const properties = record['properties'];
|
|
371
|
+
const result = {};
|
|
372
|
+
// Add flattened properties first
|
|
373
|
+
if (properties) {
|
|
374
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
375
|
+
result[key] = value;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
// Add system fields (these override any conflicting property names)
|
|
379
|
+
result['hs_object_id'] = record['id'];
|
|
380
|
+
result['createdAt'] = record['createdAt'];
|
|
381
|
+
result['updatedAt'] = record['updatedAt'];
|
|
382
|
+
result['archived'] = record['archived'];
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
// ─── URL helpers ─────────────────────────────────────────────────
|
|
386
|
+
/**
|
|
387
|
+
* Extracts the HubSpot object name from an API path.
|
|
388
|
+
* E.g., "/crm/v3/objects/contacts" -> "contacts"
|
|
389
|
+
*/
|
|
390
|
+
ExtractObjectNameFromPath(path) {
|
|
391
|
+
// Remove query string
|
|
392
|
+
const pathOnly = path.split('?')[0];
|
|
393
|
+
// Get the last path segment
|
|
394
|
+
const segments = pathOnly.split('/').filter(s => s.length > 0);
|
|
395
|
+
return segments[segments.length - 1] ?? '';
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Builds the `properties` query parameter for a HubSpot object type.
|
|
399
|
+
* Returns empty string if no properties are configured for the object.
|
|
400
|
+
*/
|
|
401
|
+
BuildPropertiesParam(objectName) {
|
|
402
|
+
const properties = HUBSPOT_PROPERTIES[objectName];
|
|
403
|
+
if (properties && properties.length > 0) {
|
|
404
|
+
return `&properties=${properties.join(',')}`;
|
|
405
|
+
}
|
|
406
|
+
return '';
|
|
407
|
+
}
|
|
408
|
+
// ─── HTTP helpers ────────────────────────────────────────────────
|
|
409
|
+
/** Executes an HTTP request with a timeout. */
|
|
410
|
+
async FetchWithTimeout(url, method, headers) {
|
|
411
|
+
const controller = new AbortController();
|
|
412
|
+
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
413
|
+
try {
|
|
414
|
+
return await fetch(url, { method, headers, signal: controller.signal });
|
|
415
|
+
}
|
|
416
|
+
catch (err) {
|
|
417
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
418
|
+
throw new Error(`HubSpot API request timed out after ${REQUEST_TIMEOUT_MS / 1000}s: ${url}`);
|
|
419
|
+
}
|
|
420
|
+
throw err;
|
|
421
|
+
}
|
|
422
|
+
finally {
|
|
423
|
+
clearTimeout(timeoutId);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
/** Calculates retry delay from Retry-After header or exponential backoff. */
|
|
427
|
+
CalculateRetryDelay(response, attempt) {
|
|
428
|
+
const retryAfter = parseInt(response.headers.get('Retry-After') ?? '0', 10);
|
|
429
|
+
return retryAfter > 0 ? retryAfter * 1000 : Math.min(1000 * Math.pow(2, attempt), 30000);
|
|
430
|
+
}
|
|
431
|
+
/** Converts a fetch Response + parsed body into a RESTResponse. */
|
|
432
|
+
BuildRESTResponse(response, body) {
|
|
433
|
+
const headers = {};
|
|
434
|
+
response.headers.forEach((v, k) => { headers[k.toLowerCase()] = v; });
|
|
435
|
+
return { Status: response.status, Body: body, Headers: headers };
|
|
436
|
+
}
|
|
437
|
+
/** Returns a promise that resolves after the specified number of milliseconds. */
|
|
438
|
+
Sleep(ms) {
|
|
439
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
98
440
|
}
|
|
99
441
|
};
|
|
100
442
|
HubSpotConnector = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HubSpotConnector.js","sourceRoot":"","sources":["../src/HubSpotConnector.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HubSpotConnector.js","sourceRoot":"","sources":["../src/HubSpotConnector.ts"],"names":[],"mappings":"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"}
|