@useairfoil/producer-hubspot 0.0.0-stage → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +151 -2
  2. package/dist/index.d.mts +1296 -0
  3. package/dist/index.mjs +3 -0
  4. package/dist/main.d.mts +1 -0
  5. package/dist/main.mjs +1323 -0
  6. package/dist/main.mjs.map +1 -0
  7. package/dist/manifest.d.mts +114 -0
  8. package/dist/manifest.mjs +160 -0
  9. package/dist/manifest.mjs.map +1 -0
  10. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  11. package/dist/src-NlJCpnba.mjs +1539 -0
  12. package/dist/src-NlJCpnba.mjs.map +1 -0
  13. package/package.json +48 -4
  14. package/src/client/client.ts +179 -0
  15. package/src/connector.ts +89 -0
  16. package/src/create-table.ts +5 -0
  17. package/src/demo/activity.ts +195 -0
  18. package/src/demo/companies.ts +255 -0
  19. package/src/demo/deals.ts +165 -0
  20. package/src/demo/index.ts +99 -0
  21. package/src/demo/setup.ts +326 -0
  22. package/src/demo/shared.ts +173 -0
  23. package/src/index.ts +74 -0
  24. package/src/main.ts +22 -0
  25. package/src/manifest.ts +59 -0
  26. package/src/resources/crm/read.ts +169 -0
  27. package/src/resources/crm/resource.ts +37 -0
  28. package/src/resources/crm/search.ts +118 -0
  29. package/src/resources/crm/sources.ts +266 -0
  30. package/src/resources/crm/spec.ts +36 -0
  31. package/src/resources/crm/webhook.ts +48 -0
  32. package/src/resources/custom-objects.ts +228 -0
  33. package/src/resources/lists.ts +76 -0
  34. package/src/resources/object-types.ts +18 -0
  35. package/src/resources/objects.ts +195 -0
  36. package/src/resources/owners.ts +75 -0
  37. package/src/resources/pipelines.ts +83 -0
  38. package/src/resources/properties.ts +96 -0
  39. package/src/resources/teams.ts +88 -0
  40. package/src/sandbox.ts +35 -0
  41. package/src/schemas/api.ts +51 -0
  42. package/src/schemas/crm.ts +255 -0
  43. package/src/schemas/events.ts +29 -0
  44. package/src/schemas/lists.ts +41 -0
  45. package/src/schemas/owners.ts +44 -0
  46. package/src/schemas/pipelines.ts +62 -0
  47. package/src/schemas/properties.ts +66 -0
  48. package/src/schemas/shared.ts +45 -0
  49. package/src/schemas/teams.ts +29 -0
  50. package/src/start.ts +47 -0
  51. package/src/tables.ts +73 -0
  52. package/src/webhook/route.ts +127 -0
  53. package/src/webhook/signature.ts +41 -0
package/README.md CHANGED
@@ -1,3 +1,152 @@
1
- # Temporary Holding Version
1
+ # HubSpot producer
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Syncs HubSpot CRM records, custom objects, owners, teams, pipelines, lists, and
4
+ property definitions from one HubSpot account. It backfills each resource, then
5
+ polls CRM records and custom objects every 5 minutes and the rest every hour.
6
+ With an app client secret, it also takes webhooks at `POST /webhooks/hubspot`.
7
+
8
+ | Resource | What |
9
+ | -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
10
+ | `contacts`, `companies`, `deals`, `tickets` | Core CRM records |
11
+ | `calls`, `emails`, `meetings`, `notes`, `tasks`, `communications`, `postal_mail` | Activities |
12
+ | `feedback_submissions` | Answers to feedback surveys |
13
+ | `line_items`, `products`, `quotes`, `discounts`, `fees`, `taxes` | Products and quotes |
14
+ | `leads` | Leads |
15
+ | `invoices`, `orders`, `carts`, `commerce_payments`, `subscriptions` | Commerce |
16
+ | `goal_targets`, `deal_split` | Goals and deal splits |
17
+ | `users` | HubSpot users with their user properties |
18
+ | `custom_objects` | Records of every custom object type |
19
+ | `owners`, `teams` | Record owners and their teams |
20
+ | `pipelines` | Pipelines and their stages |
21
+ | `lists` | Lists (segments), without members |
22
+ | `properties` | Property definitions, to name `properties` keys and values |
23
+
24
+ ## Config
25
+
26
+ | Variable | Required | Default |
27
+ | ----------------------- | -------- | ------- |
28
+ | `HUBSPOT_ACCESS_TOKEN` | yes | none |
29
+ | `HUBSPOT_CLIENT_SECRET` | no | none |
30
+
31
+ Without `HUBSPOT_CLIENT_SECRET`, webhooks are off and every change comes from
32
+ polling.
33
+
34
+ ## Setup
35
+
36
+ For polling only, create a service key under **Development → Keys → Service
37
+ keys** with these read scopes:
38
+
39
+ - `crm.objects.contacts.read`, `crm.schemas.contacts.read`
40
+ - `crm.objects.companies.read`, `crm.schemas.companies.read`
41
+ - `crm.objects.deals.read`, `crm.schemas.deals.read`
42
+ - `crm.objects.tickets.read`, `crm.schemas.tickets.read`
43
+ - `crm.objects.line_items.read`, `crm.schemas.line_items.read`
44
+ - `crm.objects.products.read`
45
+ - `crm.objects.owners.read`
46
+ - `sales-email-read`
47
+ - `crm.objects.quotes.read`, `crm.objects.leads.read`
48
+ - `crm.objects.feedback_submissions.read`, `crm.objects.goals.read`,
49
+ `crm.objects.users.read`
50
+ - `crm.objects.invoices.read`, `crm.objects.orders.read`,
51
+ `crm.objects.carts.read`, `crm.objects.commercepayments.read`,
52
+ `crm.objects.subscriptions.read`
53
+ - `crm.objects.custom.read`, `crm.schemas.custom.read`
54
+ - `crm.lists.read`, `settings.users.teams.read`
55
+
56
+ Communications, postal mail, discounts, fees, taxes, and deal splits need no
57
+ extra scope.
58
+
59
+ Use the key as `HUBSPOT_ACCESS_TOKEN`.
60
+
61
+ Service keys can't receive webhooks. For webhooks, upload the app in
62
+ `hubspot-app/` with the HubSpot CLI instead:
63
+
64
+ 1. Set `targetUrl` in `hubspot-app/src/app/webhooks/webhooks-hsmeta.json` to
65
+ `<connector>/webhooks/hubspot`.
66
+ 2. Run `hs account auth`, then `hs project upload` from `hubspot-app/`.
67
+ 3. Install the app from **Development → Projects → airfoil-connector →
68
+ Distribution**.
69
+ 4. Use the access token from the Distribution tab as `HUBSPOT_ACCESS_TOKEN` and
70
+ the client secret from the Auth tab as `HUBSPOT_CLIENT_SECRET`.
71
+
72
+ The app asks for every scope above, and apps with static auth can't make a
73
+ scope optional. On an account without a feature, such as custom objects, leads,
74
+ or Commerce Hub, remove its scopes from `hubspot-app/src/app/app-hsmeta.json`
75
+ and its subscriptions from `webhooks-hsmeta.json` before uploading.
76
+
77
+ For custom object webhooks, add `object.creation`, `object.deletion`, and
78
+ `object.restore` subscriptions with the object's name, such as `vehicle`, as
79
+ `objectType`. The app can't list each account's custom objects for you.
80
+
81
+ One token reads one account, so run one connector per account.
82
+
83
+ ## API version
84
+
85
+ The connector uses the `2026-09` API paths, such as
86
+ `/crm/objects/2026-09/contacts`.
87
+
88
+ ## Data
89
+
90
+ - CRM tables keep every non-empty property in `properties`, by internal name,
91
+ as strings. New custom properties show up on their own. Sensitive properties
92
+ are left out.
93
+ - Contacts, deals, tickets, activities, quotes, leads, commerce records, line
94
+ items, deal splits, and custom objects have lists of associated record IDs.
95
+ - `custom_objects` holds every custom object type. `object_type_id` (such as
96
+ `2-123`) and `object_type` (its name) say which, and `key` is
97
+ `<object_type_id>:<id>`. Rows of a deleted type stay.
98
+ - `properties` names the keys in `properties` and the values of dropdowns.
99
+ Pipeline stages are in `pipelines`.
100
+ - `users` has user properties. `owners` maps users to the owner IDs on records.
101
+ - A deleted record gets `_deleted`. So do records merged into another one.
102
+ - Owners, pipelines, and property definitions stay with `archived = true` when
103
+ removed. Removed teams and lists stay as they were.
104
+ - CRM record tables, custom objects included, hold customer data such as
105
+ names, emails, phone numbers, message bodies, and form answers. Treat them
106
+ as customer data.
107
+
108
+ ## Limits
109
+
110
+ - Calculated properties and association lists can be a day old, or a week for
111
+ activities, line items, and products. Webhooks bring association changes
112
+ right away.
113
+ - Without webhooks, these deletes are missed: GDPR deletes, and deleted emails,
114
+ meetings, communications, invoices, payments, subscriptions, users, and deal
115
+ splits. HubSpot can't list them.
116
+ - An account without a feature, such as leads or custom objects, or a token
117
+ without its scope, leaves that table in error. The other tables keep syncing.
118
+ - Deal splits have no webhooks, so they only come from polling. Custom object
119
+ association lists also only update by polling, at most a day late.
120
+ - A new custom object type shows up within an hour.
121
+ - A record restored from the recycle bin comes back on its next read: a
122
+ webhook, a search hit, or the full re-read.
123
+ - Searches, polls of deleted records, and full re-reads share the account's
124
+ daily API limit with its other apps.
125
+
126
+ ## Demo data
127
+
128
+ `pnpm demo --size 128MiB` writes made-up HubSpot data without HubSpot
129
+ credentials. See the Connector Kit README for the flags and the variables it
130
+ needs.
131
+
132
+ Each company has contacts, deals with line items, quotes, and splits, tickets,
133
+ sales activity, leads, and, once a deal is won, a subscription, an order,
134
+ invoices, payments, and an onboarding project in `custom_objects`. Properties
135
+ use HubSpot's internal names. The account setup is written once and doesn't
136
+ grow with the size: owners, users, teams, pipelines, properties, lists,
137
+ products, discounts, fees, taxes, and goals.
138
+
139
+ ## Local development
140
+
141
+ ```bash
142
+ cd connectors/producer-hubspot
143
+ pnpm sandbox
144
+ ```
145
+
146
+ To record VCR, put a test account's service key in `.env`, delete
147
+ `test/__cassettes__/api.vcr.test.cassette`, and run `pnpm test:ci`. Recording
148
+ takes a few minutes. Check the new cassette for personal data before committing
149
+ it.
150
+
151
+ `pnpm start` runs the hosted connector. It needs the Wings and PostgreSQL
152
+ variables from the Connector Kit README.