@xenterprises/fastify-xhubspot 1.0.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/CHANGELOG.md +295 -0
- package/LICENSE +15 -0
- package/SECURITY.md +1078 -0
- package/index.d.ts +829 -0
- package/package.json +85 -0
- package/src/index.js +3 -0
- package/src/services/companies.js +138 -0
- package/src/services/contacts.js +327 -0
- package/src/services/customObjects.js +51 -0
- package/src/services/deals.js +52 -0
- package/src/services/engagement.js +54 -0
- package/src/xHubspot.js +57 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,829 @@
|
|
|
1
|
+
// Type definitions for @xenterprises/fastify-xhubspot
|
|
2
|
+
// Project: xHubspot
|
|
3
|
+
// Definitions by: Tim Mushen
|
|
4
|
+
|
|
5
|
+
import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ============================================================================
|
|
9
|
+
* MAIN PLUGIN INTERFACE
|
|
10
|
+
* ============================================================================
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export interface XHubspotOptions {
|
|
14
|
+
/**
|
|
15
|
+
* HubSpot Private App Access Token
|
|
16
|
+
* Required. Get from: https://app.hubspotbeta.com/l/private-apps
|
|
17
|
+
* Must have scopes: crm.objects.contacts.read, .write, etc.
|
|
18
|
+
*/
|
|
19
|
+
apiKey: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Enable detailed request/response logging
|
|
23
|
+
* Default: false
|
|
24
|
+
*/
|
|
25
|
+
logRequests?: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Log sensitive data (email addresses, phone numbers, etc.)
|
|
29
|
+
* Default: false
|
|
30
|
+
* WARNING: Only enable in development
|
|
31
|
+
*/
|
|
32
|
+
logSensitiveData?: boolean;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* HubSpot API base URL (for custom implementations)
|
|
36
|
+
* Default: https://api.hubapi.com
|
|
37
|
+
*/
|
|
38
|
+
baseUrl?: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Request timeout in milliseconds
|
|
42
|
+
* Default: 30000
|
|
43
|
+
*/
|
|
44
|
+
requestTimeout?: number;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Maximum number of retries for failed requests
|
|
48
|
+
* Default: 3
|
|
49
|
+
*/
|
|
50
|
+
maxRetries?: number;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Delay between retries in milliseconds
|
|
54
|
+
* Default: 1000
|
|
55
|
+
*/
|
|
56
|
+
retryDelay?: number;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Rate limit (requests per second)
|
|
60
|
+
* Default: 10 (free tier)
|
|
61
|
+
*/
|
|
62
|
+
rateLimit?: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* ============================================================================
|
|
67
|
+
* CONTACT SERVICE TYPES
|
|
68
|
+
* ============================================================================
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
export interface ContactProperty {
|
|
72
|
+
[key: string]: string | number | boolean | null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface Contact {
|
|
76
|
+
id: string;
|
|
77
|
+
properties: ContactProperty;
|
|
78
|
+
associations?: AssociationResponse[];
|
|
79
|
+
createdAt?: string;
|
|
80
|
+
updatedAt?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ContactInput {
|
|
84
|
+
email?: string;
|
|
85
|
+
firstname?: string;
|
|
86
|
+
lastname?: string;
|
|
87
|
+
phone?: string;
|
|
88
|
+
hs_lead_status?: string;
|
|
89
|
+
lifecyclestage?: string;
|
|
90
|
+
[key: string]: any;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface ContactListOptions {
|
|
94
|
+
limit?: number;
|
|
95
|
+
after?: string;
|
|
96
|
+
properties?: string[];
|
|
97
|
+
searchFilter?: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface ContactListResponse {
|
|
101
|
+
results: Contact[];
|
|
102
|
+
paging?: {
|
|
103
|
+
next?: {
|
|
104
|
+
after: string;
|
|
105
|
+
link: string;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export interface ContactBatchInput {
|
|
111
|
+
id?: string;
|
|
112
|
+
properties: ContactProperty;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface ContactBatchResponse {
|
|
116
|
+
results: Contact[];
|
|
117
|
+
errors?: BatchError[];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface ContactSearchOptions {
|
|
121
|
+
property: string;
|
|
122
|
+
value: string;
|
|
123
|
+
limit?: number;
|
|
124
|
+
after?: string;
|
|
125
|
+
properties?: string[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface ContactsService {
|
|
129
|
+
/**
|
|
130
|
+
* Create a new contact in HubSpot
|
|
131
|
+
* @param contactData - Contact information to create
|
|
132
|
+
* @returns Created contact with ID and properties
|
|
133
|
+
* @throws HubSpot API errors
|
|
134
|
+
*/
|
|
135
|
+
create(contactData: ContactInput): Promise<Contact>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Retrieve contact by HubSpot contact ID
|
|
139
|
+
* @param contactId - HubSpot contact ID
|
|
140
|
+
* @param properties - Optional array of properties to retrieve
|
|
141
|
+
* @returns Contact with specified properties
|
|
142
|
+
* @throws Error if contact not found
|
|
143
|
+
*/
|
|
144
|
+
getById(contactId: string, properties?: string[]): Promise<Contact>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Retrieve contact by email address
|
|
148
|
+
* Uses email as idempotency key - perfect for third-party portals
|
|
149
|
+
* @param email - Contact email address
|
|
150
|
+
* @param properties - Optional array of properties to retrieve
|
|
151
|
+
* @returns Contact object with email included
|
|
152
|
+
* @throws Error if contact not found
|
|
153
|
+
*/
|
|
154
|
+
getByEmail(
|
|
155
|
+
email: string,
|
|
156
|
+
properties?: string[]
|
|
157
|
+
): Promise<Contact & { email: string }>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Update contact properties
|
|
161
|
+
* @param contactId - HubSpot contact ID
|
|
162
|
+
* @param properties - Properties to update
|
|
163
|
+
* @returns Updated contact object
|
|
164
|
+
* @throws Error if update fails
|
|
165
|
+
*/
|
|
166
|
+
update(contactId: string, properties: ContactProperty): Promise<Contact>;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Delete/archive a contact
|
|
170
|
+
* @param contactId - HubSpot contact ID
|
|
171
|
+
* @returns Success confirmation
|
|
172
|
+
* @throws Error if deletion fails
|
|
173
|
+
*/
|
|
174
|
+
delete(contactId: string): Promise<{ success: boolean }>;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* List all contacts with pagination
|
|
178
|
+
* @param options - Pagination and filtering options
|
|
179
|
+
* @returns Paginated contact list
|
|
180
|
+
*/
|
|
181
|
+
list(options?: ContactListOptions): Promise<ContactListResponse>;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Search contacts by property value
|
|
185
|
+
* @param property - Property name to search
|
|
186
|
+
* @param value - Property value to match
|
|
187
|
+
* @param options - Optional pagination options
|
|
188
|
+
* @returns Matching contacts
|
|
189
|
+
*/
|
|
190
|
+
search(
|
|
191
|
+
property: string,
|
|
192
|
+
value: string,
|
|
193
|
+
options?: ContactListOptions
|
|
194
|
+
): Promise<Contact[]>;
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Create multiple contacts in one API call (batch operation)
|
|
198
|
+
* Maximum 100 contacts per call
|
|
199
|
+
* @param contacts - Array of contact data (max 100)
|
|
200
|
+
* @returns Created contacts with IDs
|
|
201
|
+
* @throws Error if batch exceeds 100 or API fails
|
|
202
|
+
*/
|
|
203
|
+
batchCreate(contacts: ContactInput[]): Promise<ContactBatchResponse>;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Update multiple contacts in one API call (batch operation)
|
|
207
|
+
* Maximum 100 contacts per call
|
|
208
|
+
* @param contacts - Array of contact updates with IDs (max 100)
|
|
209
|
+
* @returns Updated contacts
|
|
210
|
+
* @throws Error if batch exceeds 100 or API fails
|
|
211
|
+
*/
|
|
212
|
+
batchUpdate(contacts: ContactBatchInput[]): Promise<ContactBatchResponse>;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get associated objects (companies, deals, etc.)
|
|
216
|
+
* @param contactId - HubSpot contact ID
|
|
217
|
+
* @param associationType - Type of association (companies, deals, etc.)
|
|
218
|
+
* @returns Array of associated object IDs
|
|
219
|
+
*/
|
|
220
|
+
getAssociations(
|
|
221
|
+
contactId: string,
|
|
222
|
+
associationType: "companies" | "deals" | string
|
|
223
|
+
): Promise<Association[]>;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Associate contact with another object (company, deal, etc.)
|
|
227
|
+
* @param contactId - HubSpot contact ID
|
|
228
|
+
* @param objectId - ID of object to associate
|
|
229
|
+
* @param associationType - Type of association
|
|
230
|
+
* @returns Success confirmation with association ID
|
|
231
|
+
*/
|
|
232
|
+
associate(
|
|
233
|
+
contactId: string,
|
|
234
|
+
objectId: string,
|
|
235
|
+
associationType: string
|
|
236
|
+
): Promise<{ success: boolean; associationId: string }>;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* ============================================================================
|
|
241
|
+
* COMPANY SERVICE TYPES
|
|
242
|
+
* ============================================================================
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
export interface CompanyProperty {
|
|
246
|
+
[key: string]: string | number | boolean | null;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface Company {
|
|
250
|
+
id: string;
|
|
251
|
+
properties: CompanyProperty;
|
|
252
|
+
associations?: AssociationResponse[];
|
|
253
|
+
createdAt?: string;
|
|
254
|
+
updatedAt?: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface CompanyInput {
|
|
258
|
+
name: string;
|
|
259
|
+
domain?: string;
|
|
260
|
+
industry?: string;
|
|
261
|
+
hs_lead_status?: string;
|
|
262
|
+
lifecyclestage?: string;
|
|
263
|
+
numberofemployees?: number;
|
|
264
|
+
[key: string]: any;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export interface CompanyListOptions {
|
|
268
|
+
limit?: number;
|
|
269
|
+
after?: string;
|
|
270
|
+
properties?: string[];
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export interface CompanyListResponse {
|
|
274
|
+
results: Company[];
|
|
275
|
+
paging?: {
|
|
276
|
+
next?: {
|
|
277
|
+
after: string;
|
|
278
|
+
link: string;
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export interface CompaniesService {
|
|
284
|
+
/**
|
|
285
|
+
* Create a new company in HubSpot
|
|
286
|
+
* @param companyData - Company information to create
|
|
287
|
+
* @returns Created company with ID and properties
|
|
288
|
+
*/
|
|
289
|
+
create(companyData: CompanyInput): Promise<Company>;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Retrieve company by HubSpot company ID
|
|
293
|
+
* @param companyId - HubSpot company ID
|
|
294
|
+
* @param properties - Optional array of properties to retrieve
|
|
295
|
+
* @returns Company object
|
|
296
|
+
*/
|
|
297
|
+
getById(companyId: string, properties?: string[]): Promise<Company>;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Retrieve company by domain name
|
|
301
|
+
* @param domain - Company domain (e.g., "example.com")
|
|
302
|
+
* @param properties - Optional array of properties to retrieve
|
|
303
|
+
* @returns Company object
|
|
304
|
+
*/
|
|
305
|
+
getByDomain(domain: string, properties?: string[]): Promise<Company>;
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Update company properties
|
|
309
|
+
* @param companyId - HubSpot company ID
|
|
310
|
+
* @param properties - Properties to update
|
|
311
|
+
* @returns Updated company object
|
|
312
|
+
*/
|
|
313
|
+
update(companyId: string, properties: CompanyProperty): Promise<Company>;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Delete/archive a company
|
|
317
|
+
* @param companyId - HubSpot company ID
|
|
318
|
+
* @returns Success confirmation
|
|
319
|
+
*/
|
|
320
|
+
delete(companyId: string): Promise<{ success: boolean }>;
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* List all companies with pagination
|
|
324
|
+
* @param options - Pagination and filtering options
|
|
325
|
+
* @returns Paginated company list
|
|
326
|
+
*/
|
|
327
|
+
list(options?: CompanyListOptions): Promise<CompanyListResponse>;
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Search companies by property value
|
|
331
|
+
* @param property - Property name to search
|
|
332
|
+
* @param value - Property value to match
|
|
333
|
+
* @returns Matching companies
|
|
334
|
+
*/
|
|
335
|
+
search(property: string, value: string): Promise<Company[]>;
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Create multiple companies in one API call
|
|
339
|
+
* @param companies - Array of company data (max 100)
|
|
340
|
+
* @returns Created companies with IDs
|
|
341
|
+
*/
|
|
342
|
+
batchCreate(companies: CompanyInput[]): Promise<ContactBatchResponse>;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Get associated contacts for a company
|
|
346
|
+
* @param companyId - HubSpot company ID
|
|
347
|
+
* @returns Array of associated contact IDs
|
|
348
|
+
*/
|
|
349
|
+
getAssociations(companyId: string): Promise<Association[]>;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* ============================================================================
|
|
354
|
+
* DEAL SERVICE TYPES
|
|
355
|
+
* ============================================================================
|
|
356
|
+
*/
|
|
357
|
+
|
|
358
|
+
export interface DealProperty {
|
|
359
|
+
[key: string]: string | number | boolean | null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
export interface Deal {
|
|
363
|
+
id: string;
|
|
364
|
+
properties: DealProperty;
|
|
365
|
+
associations?: AssociationResponse[];
|
|
366
|
+
createdAt?: string;
|
|
367
|
+
updatedAt?: string;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
export interface DealInput {
|
|
371
|
+
dealname: string;
|
|
372
|
+
dealstage: string;
|
|
373
|
+
amount?: number;
|
|
374
|
+
closedate?: string;
|
|
375
|
+
[key: string]: any;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
export interface DealListOptions {
|
|
379
|
+
limit?: number;
|
|
380
|
+
after?: string;
|
|
381
|
+
properties?: string[];
|
|
382
|
+
pipelineId?: string;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface DealListResponse {
|
|
386
|
+
results: Deal[];
|
|
387
|
+
paging?: {
|
|
388
|
+
next?: {
|
|
389
|
+
after: string;
|
|
390
|
+
link: string;
|
|
391
|
+
};
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export interface DealsService {
|
|
396
|
+
/**
|
|
397
|
+
* Create a new deal in HubSpot
|
|
398
|
+
* @param dealData - Deal information to create
|
|
399
|
+
* @returns Created deal with ID and properties
|
|
400
|
+
*/
|
|
401
|
+
create(dealData: DealInput): Promise<Deal>;
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Retrieve deal by HubSpot deal ID
|
|
405
|
+
* @param dealId - HubSpot deal ID
|
|
406
|
+
* @param properties - Optional array of properties to retrieve
|
|
407
|
+
* @returns Deal object
|
|
408
|
+
*/
|
|
409
|
+
getById(dealId: string, properties?: string[]): Promise<Deal>;
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Update deal properties
|
|
413
|
+
* @param dealId - HubSpot deal ID
|
|
414
|
+
* @param properties - Properties to update
|
|
415
|
+
* @returns Updated deal object
|
|
416
|
+
*/
|
|
417
|
+
update(dealId: string, properties: DealProperty): Promise<Deal>;
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Delete/archive a deal
|
|
421
|
+
* @param dealId - HubSpot deal ID
|
|
422
|
+
* @returns Success confirmation
|
|
423
|
+
*/
|
|
424
|
+
delete(dealId: string): Promise<{ success: boolean }>;
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* List all deals with pagination
|
|
428
|
+
* @param options - Pagination and filtering options
|
|
429
|
+
* @returns Paginated deal list
|
|
430
|
+
*/
|
|
431
|
+
list(options?: DealListOptions): Promise<DealListResponse>;
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Get associated contacts for a deal
|
|
435
|
+
* @param dealId - HubSpot deal ID
|
|
436
|
+
* @returns Array of associated contact IDs
|
|
437
|
+
*/
|
|
438
|
+
getAssociations(dealId: string): Promise<Association[]>;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* ============================================================================
|
|
443
|
+
* ENGAGEMENT SERVICE TYPES
|
|
444
|
+
* ============================================================================
|
|
445
|
+
*/
|
|
446
|
+
|
|
447
|
+
export interface EngagementBase {
|
|
448
|
+
id?: string;
|
|
449
|
+
type: "NOTE" | "TASK" | "CALL" | "EMAIL";
|
|
450
|
+
timestamp?: number;
|
|
451
|
+
ownerId?: string;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export interface NoteInput extends EngagementBase {
|
|
455
|
+
type: "NOTE";
|
|
456
|
+
body: string;
|
|
457
|
+
contactId: string;
|
|
458
|
+
ownerId?: string;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
export interface TaskInput extends EngagementBase {
|
|
462
|
+
type: "TASK";
|
|
463
|
+
title: string;
|
|
464
|
+
body?: string;
|
|
465
|
+
contactId: string;
|
|
466
|
+
ownerId?: string;
|
|
467
|
+
taskStatus?: "NOT_STARTED" | "IN_PROGRESS" | "COMPLETED" | "DEFERRED";
|
|
468
|
+
priority?: "LOW" | "MEDIUM" | "HIGH";
|
|
469
|
+
dueDate?: string;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
export interface CallInput extends EngagementBase {
|
|
473
|
+
type: "CALL";
|
|
474
|
+
contactId: string;
|
|
475
|
+
callDuration?: number;
|
|
476
|
+
callResult?: "COMPLETED" | "BUSY" | "NO_ANSWER" | "LEFT_MESSAGE";
|
|
477
|
+
body?: string;
|
|
478
|
+
ownerId?: string;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
export interface EmailInput extends EngagementBase {
|
|
482
|
+
type: "EMAIL";
|
|
483
|
+
contactId: string;
|
|
484
|
+
subject?: string;
|
|
485
|
+
body: string;
|
|
486
|
+
from?: string;
|
|
487
|
+
to?: string;
|
|
488
|
+
messageId?: string;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
export interface Engagement {
|
|
492
|
+
id: string;
|
|
493
|
+
type: string;
|
|
494
|
+
timestamp: number;
|
|
495
|
+
contactId: string;
|
|
496
|
+
ownerId?: string;
|
|
497
|
+
body?: string;
|
|
498
|
+
title?: string;
|
|
499
|
+
[key: string]: any;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export interface EngagementListOptions {
|
|
503
|
+
contactId: string;
|
|
504
|
+
limit?: number;
|
|
505
|
+
offset?: number;
|
|
506
|
+
type?: "NOTE" | "TASK" | "CALL" | "EMAIL";
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
export interface EngagementsService {
|
|
510
|
+
/**
|
|
511
|
+
* Create an engagement note on a contact
|
|
512
|
+
* Primary use case for third-party portal interaction tracking
|
|
513
|
+
* @param contactId - HubSpot contact ID
|
|
514
|
+
* @param body - Note content/text
|
|
515
|
+
* @param ownerId - Optional owner ID (defaults to API user)
|
|
516
|
+
* @returns Created note with ID and timestamp
|
|
517
|
+
*/
|
|
518
|
+
createNote(
|
|
519
|
+
contactId: string,
|
|
520
|
+
body: string,
|
|
521
|
+
ownerId?: string
|
|
522
|
+
): Promise<Engagement>;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Create an engagement task on a contact
|
|
526
|
+
* @param contactId - HubSpot contact ID
|
|
527
|
+
* @param title - Task title
|
|
528
|
+
* @param options - Optional task details (body, priority, dueDate, etc.)
|
|
529
|
+
* @returns Created task with ID
|
|
530
|
+
*/
|
|
531
|
+
createTask(
|
|
532
|
+
contactId: string,
|
|
533
|
+
title: string,
|
|
534
|
+
options?: Partial<TaskInput>
|
|
535
|
+
): Promise<Engagement>;
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Create a call engagement on a contact
|
|
539
|
+
* @param contactId - HubSpot contact ID
|
|
540
|
+
* @param callResult - Call outcome (COMPLETED, BUSY, NO_ANSWER, LEFT_MESSAGE)
|
|
541
|
+
* @param options - Optional call details (duration, body, etc.)
|
|
542
|
+
* @returns Created call engagement
|
|
543
|
+
*/
|
|
544
|
+
createCall(
|
|
545
|
+
contactId: string,
|
|
546
|
+
callResult: string,
|
|
547
|
+
options?: Partial<CallInput>
|
|
548
|
+
): Promise<Engagement>;
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Create an email engagement on a contact
|
|
552
|
+
* @param contactId - HubSpot contact ID
|
|
553
|
+
* @param subject - Email subject
|
|
554
|
+
* @param body - Email body content
|
|
555
|
+
* @param options - Optional email details (from, to, messageId, etc.)
|
|
556
|
+
* @returns Created email engagement
|
|
557
|
+
*/
|
|
558
|
+
createEmail(
|
|
559
|
+
contactId: string,
|
|
560
|
+
subject: string,
|
|
561
|
+
body: string,
|
|
562
|
+
options?: Partial<EmailInput>
|
|
563
|
+
): Promise<Engagement>;
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Retrieve engagements for a contact
|
|
567
|
+
* @param options - Contact ID and optional filtering
|
|
568
|
+
* @returns Array of engagement records
|
|
569
|
+
*/
|
|
570
|
+
getEngagements(options: EngagementListOptions): Promise<Engagement[]>;
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* List all notes for a contact
|
|
574
|
+
* @param contactId - HubSpot contact ID
|
|
575
|
+
* @param limit - Optional limit (default: 20)
|
|
576
|
+
* @returns Array of note engagements
|
|
577
|
+
*/
|
|
578
|
+
getNotes(contactId: string, limit?: number): Promise<Engagement[]>;
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* List all tasks for a contact
|
|
582
|
+
* @param contactId - HubSpot contact ID
|
|
583
|
+
* @param limit - Optional limit (default: 20)
|
|
584
|
+
* @returns Array of task engagements
|
|
585
|
+
*/
|
|
586
|
+
getTasks(contactId: string, limit?: number): Promise<Engagement[]>;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* ============================================================================
|
|
591
|
+
* CUSTOM OBJECTS SERVICE TYPES
|
|
592
|
+
* ============================================================================
|
|
593
|
+
*/
|
|
594
|
+
|
|
595
|
+
export interface CustomObjectProperty {
|
|
596
|
+
[key: string]: string | number | boolean | null;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
export interface CustomObject {
|
|
600
|
+
id: string;
|
|
601
|
+
objectType: string;
|
|
602
|
+
properties: CustomObjectProperty;
|
|
603
|
+
associations?: AssociationResponse[];
|
|
604
|
+
createdAt?: string;
|
|
605
|
+
updatedAt?: string;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
export interface CustomObjectInput {
|
|
609
|
+
objectType: string;
|
|
610
|
+
properties: CustomObjectProperty;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export interface CustomObjectListOptions {
|
|
614
|
+
objectType: string;
|
|
615
|
+
limit?: number;
|
|
616
|
+
after?: string;
|
|
617
|
+
properties?: string[];
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
export interface CustomObjectsService {
|
|
621
|
+
/**
|
|
622
|
+
* Create a custom object
|
|
623
|
+
* @param objectType - Type of custom object
|
|
624
|
+
* @param properties - Object properties
|
|
625
|
+
* @returns Created custom object with ID
|
|
626
|
+
*/
|
|
627
|
+
create(
|
|
628
|
+
objectType: string,
|
|
629
|
+
properties: CustomObjectProperty
|
|
630
|
+
): Promise<CustomObject>;
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Retrieve custom object by ID
|
|
634
|
+
* @param objectType - Type of custom object
|
|
635
|
+
* @param objectId - Custom object ID
|
|
636
|
+
* @param properties - Optional array of properties to retrieve
|
|
637
|
+
* @returns Custom object
|
|
638
|
+
*/
|
|
639
|
+
getById(
|
|
640
|
+
objectType: string,
|
|
641
|
+
objectId: string,
|
|
642
|
+
properties?: string[]
|
|
643
|
+
): Promise<CustomObject>;
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Update custom object properties
|
|
647
|
+
* @param objectType - Type of custom object
|
|
648
|
+
* @param objectId - Custom object ID
|
|
649
|
+
* @param properties - Properties to update
|
|
650
|
+
* @returns Updated custom object
|
|
651
|
+
*/
|
|
652
|
+
update(
|
|
653
|
+
objectType: string,
|
|
654
|
+
objectId: string,
|
|
655
|
+
properties: CustomObjectProperty
|
|
656
|
+
): Promise<CustomObject>;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Delete custom object
|
|
660
|
+
* @param objectType - Type of custom object
|
|
661
|
+
* @param objectId - Custom object ID
|
|
662
|
+
* @returns Success confirmation
|
|
663
|
+
*/
|
|
664
|
+
delete(objectType: string, objectId: string): Promise<{ success: boolean }>;
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* List custom objects
|
|
668
|
+
* @param options - Pagination and filtering options
|
|
669
|
+
* @returns Paginated custom object list
|
|
670
|
+
*/
|
|
671
|
+
list(options: CustomObjectListOptions): Promise<CustomObjectListResponse>;
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Get associated objects
|
|
675
|
+
* @param objectType - Type of custom object
|
|
676
|
+
* @param objectId - Custom object ID
|
|
677
|
+
* @returns Array of associations
|
|
678
|
+
*/
|
|
679
|
+
getAssociations(
|
|
680
|
+
objectType: string,
|
|
681
|
+
objectId: string
|
|
682
|
+
): Promise<Association[]>;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
export interface CustomObjectListResponse {
|
|
686
|
+
results: CustomObject[];
|
|
687
|
+
paging?: {
|
|
688
|
+
next?: {
|
|
689
|
+
after: string;
|
|
690
|
+
link: string;
|
|
691
|
+
};
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* ============================================================================
|
|
697
|
+
* ASSOCIATION TYPES
|
|
698
|
+
* ============================================================================
|
|
699
|
+
*/
|
|
700
|
+
|
|
701
|
+
export interface Association {
|
|
702
|
+
id: string;
|
|
703
|
+
type: string;
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export interface AssociationResponse {
|
|
707
|
+
id: string;
|
|
708
|
+
type: string;
|
|
709
|
+
label?: string;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* ============================================================================
|
|
714
|
+
* ERROR TYPES
|
|
715
|
+
* ============================================================================
|
|
716
|
+
*/
|
|
717
|
+
|
|
718
|
+
export interface BatchError {
|
|
719
|
+
status: number;
|
|
720
|
+
message: string;
|
|
721
|
+
correlationId?: string;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
export interface HubSpotError extends Error {
|
|
725
|
+
status?: number;
|
|
726
|
+
message: string;
|
|
727
|
+
correlationId?: string;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* ============================================================================
|
|
732
|
+
* FASTIFY MODULE AUGMENTATION
|
|
733
|
+
* ============================================================================
|
|
734
|
+
*/
|
|
735
|
+
|
|
736
|
+
declare module "fastify" {
|
|
737
|
+
interface FastifyInstance {
|
|
738
|
+
/**
|
|
739
|
+
* HubSpot API client instance
|
|
740
|
+
* Available when xHubspot plugin is registered
|
|
741
|
+
*/
|
|
742
|
+
hubspot: any;
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Contacts service - manage HubSpot contacts
|
|
746
|
+
* Methods: create, getById, getByEmail, update, delete, list, search,
|
|
747
|
+
* batchCreate, batchUpdate, getAssociations, associate
|
|
748
|
+
*/
|
|
749
|
+
contacts: ContactsService;
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Companies service - manage HubSpot companies
|
|
753
|
+
* Methods: create, getById, getByDomain, update, delete, list, search,
|
|
754
|
+
* batchCreate, getAssociations
|
|
755
|
+
*/
|
|
756
|
+
companies: CompaniesService;
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Deals service - manage HubSpot deals
|
|
760
|
+
* Methods: create, getById, update, delete, list, getAssociations
|
|
761
|
+
*/
|
|
762
|
+
deals: DealsService;
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Engagements service - create and retrieve contact engagements
|
|
766
|
+
* Methods: createNote, createTask, createCall, createEmail, getEngagements,
|
|
767
|
+
* getNotes, getTasks
|
|
768
|
+
*/
|
|
769
|
+
engagement: EngagementsService;
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Custom objects service - manage HubSpot custom objects
|
|
773
|
+
* Methods: create, getById, update, delete, list, getAssociations
|
|
774
|
+
*/
|
|
775
|
+
customObjects: CustomObjectsService;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/**
|
|
780
|
+
* ============================================================================
|
|
781
|
+
* PLUGIN EXPORT
|
|
782
|
+
* ============================================================================
|
|
783
|
+
*/
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* xHubspot - Fastify plugin for HubSpot CRM integration
|
|
787
|
+
*
|
|
788
|
+
* @param fastify - Fastify instance
|
|
789
|
+
* @param options - Plugin configuration (API key required)
|
|
790
|
+
*
|
|
791
|
+
* @example
|
|
792
|
+
* import Fastify from 'fastify';
|
|
793
|
+
* import xHubspot from '@xenterprises/fastify-xhubspot';
|
|
794
|
+
*
|
|
795
|
+
* const fastify = Fastify();
|
|
796
|
+
*
|
|
797
|
+
* await fastify.register(xHubspot, {
|
|
798
|
+
* apiKey: process.env.HUBSPOT_ACCESS_TOKEN,
|
|
799
|
+
* logRequests: false,
|
|
800
|
+
* logSensitiveData: false,
|
|
801
|
+
* });
|
|
802
|
+
*
|
|
803
|
+
* // Now available:
|
|
804
|
+
* // fastify.contacts - Contact management
|
|
805
|
+
* // fastify.companies - Company management
|
|
806
|
+
* // fastify.deals - Deal management
|
|
807
|
+
* // fastify.engagement - Engagement tracking (notes, tasks, calls, emails)
|
|
808
|
+
* // fastify.customObjects - Custom object management
|
|
809
|
+
*
|
|
810
|
+
* // Create a contact
|
|
811
|
+
* const contact = await fastify.contacts.create({
|
|
812
|
+
* email: 'john@example.com',
|
|
813
|
+
* firstname: 'John',
|
|
814
|
+
* lastname: 'Doe',
|
|
815
|
+
* });
|
|
816
|
+
*
|
|
817
|
+
* // Create an engagement note on contact
|
|
818
|
+
* const note = await fastify.engagement.createNote(
|
|
819
|
+
* contact.id,
|
|
820
|
+
* 'Important follow-up needed next week'
|
|
821
|
+
* );
|
|
822
|
+
*/
|
|
823
|
+
declare function xHubspot(
|
|
824
|
+
fastify: FastifyInstance,
|
|
825
|
+
options: XHubspotOptions
|
|
826
|
+
): Promise<void>;
|
|
827
|
+
|
|
828
|
+
export default xHubspot;
|
|
829
|
+
export { xHubspot };
|