strapi-plugin-hubspot 0.16.8 → 0.16.9
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 +14 -0
- package/dist/server/index.js +14 -18
- package/dist/server/index.mjs +14 -18
- package/dist/server/src/hsforms.d.ts +12 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.16.9 — 2026-10-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Brand-new leads silently lost their timeline note and company
|
|
9
|
+
association** after a Forms API conversion: the contact id was resolved
|
|
10
|
+
through the Search API, whose index lags by seconds to minutes on freshly
|
|
11
|
+
created records — so the contact the conversion itself just created was
|
|
12
|
+
invisible, and the note/association steps were skipped without a warning.
|
|
13
|
+
The lookup now uses the direct object endpoint
|
|
14
|
+
(`GET /crm/v3/objects/contacts/{email}?idProperty=email`), which reads the
|
|
15
|
+
object store (no index lag), with a short 404 retry (~1.6 s budget) since
|
|
16
|
+
the conversion is processed asynchronously. Existing contacts are
|
|
17
|
+
unaffected; any non-404 error still gives up immediately.
|
|
18
|
+
|
|
5
19
|
## 0.16.8 — 2026-09-24
|
|
6
20
|
|
|
7
21
|
### Added
|
package/dist/server/index.js
CHANGED
|
@@ -2167,24 +2167,20 @@ async function loadFormShape(apiKey, formGuid) {
|
|
|
2167
2167
|
return null;
|
|
2168
2168
|
}
|
|
2169
2169
|
}
|
|
2170
|
-
async function findContactIdByEmail(apiKey, email) {
|
|
2171
|
-
const
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
});
|
|
2185
|
-
const body = await res.json().catch(() => ({}));
|
|
2186
|
-
if (!res.ok) return void 0;
|
|
2187
|
-
return body.results?.[0]?.id;
|
|
2170
|
+
async function findContactIdByEmail(apiKey, email, retryDelaysMs = [400, 1200]) {
|
|
2171
|
+
for (const delay of [0, ...retryDelaysMs]) {
|
|
2172
|
+
if (delay > 0) await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2173
|
+
const res = await fetch(
|
|
2174
|
+
`https://api.hubapi.com/crm/v3/objects/contacts/${encodeURIComponent(email)}?idProperty=email`,
|
|
2175
|
+
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
2176
|
+
);
|
|
2177
|
+
if (res.ok) {
|
|
2178
|
+
const body = await res.json().catch(() => ({}));
|
|
2179
|
+
return body.id || void 0;
|
|
2180
|
+
}
|
|
2181
|
+
if (res.status !== 404) return void 0;
|
|
2182
|
+
}
|
|
2183
|
+
return void 0;
|
|
2188
2184
|
}
|
|
2189
2185
|
function contextPayload(ctx) {
|
|
2190
2186
|
const out = {};
|
package/dist/server/index.mjs
CHANGED
|
@@ -2166,24 +2166,20 @@ async function loadFormShape(apiKey, formGuid) {
|
|
|
2166
2166
|
return null;
|
|
2167
2167
|
}
|
|
2168
2168
|
}
|
|
2169
|
-
async function findContactIdByEmail(apiKey, email) {
|
|
2170
|
-
const
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
});
|
|
2184
|
-
const body = await res.json().catch(() => ({}));
|
|
2185
|
-
if (!res.ok) return void 0;
|
|
2186
|
-
return body.results?.[0]?.id;
|
|
2169
|
+
async function findContactIdByEmail(apiKey, email, retryDelaysMs = [400, 1200]) {
|
|
2170
|
+
for (const delay of [0, ...retryDelaysMs]) {
|
|
2171
|
+
if (delay > 0) await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2172
|
+
const res = await fetch(
|
|
2173
|
+
`https://api.hubapi.com/crm/v3/objects/contacts/${encodeURIComponent(email)}?idProperty=email`,
|
|
2174
|
+
{ headers: { Authorization: `Bearer ${apiKey}` } }
|
|
2175
|
+
);
|
|
2176
|
+
if (res.ok) {
|
|
2177
|
+
const body = await res.json().catch(() => ({}));
|
|
2178
|
+
return body.id || void 0;
|
|
2179
|
+
}
|
|
2180
|
+
if (res.status !== 404) return void 0;
|
|
2181
|
+
}
|
|
2182
|
+
return void 0;
|
|
2187
2183
|
}
|
|
2188
2184
|
function contextPayload(ctx) {
|
|
2189
2185
|
const out = {};
|
|
@@ -133,7 +133,18 @@ export interface FormSubmitInput {
|
|
|
133
133
|
}
|
|
134
134
|
export declare function clearFormShapeCache(formGuid?: string): void;
|
|
135
135
|
export declare function loadFormShape(apiKey: string, formGuid: string): Promise<FormShape | null>;
|
|
136
|
-
|
|
136
|
+
/**
|
|
137
|
+
* The contact's id right after a Forms API conversion, via the DIRECT object
|
|
138
|
+
* lookup (`idProperty=email`) — never the Search API: the search index lags by
|
|
139
|
+
* seconds to minutes on freshly created records, so a contact the conversion
|
|
140
|
+
* itself just created was invisible, silently costing brand-new leads their
|
|
141
|
+
* timeline note and company association. The object store has no such lag.
|
|
142
|
+
*
|
|
143
|
+
* The conversion is processed asynchronously on HubSpot's side, so a 404 is
|
|
144
|
+
* retried briefly (the delays are injectable for tests). Any other error
|
|
145
|
+
* (auth, 5xx) gives up immediately — retrying wouldn't change it.
|
|
146
|
+
*/
|
|
147
|
+
export declare function findContactIdByEmail(apiKey: string, email: string, retryDelaysMs?: readonly number[]): Promise<string | undefined>;
|
|
137
148
|
/**
|
|
138
149
|
* Submit a marketing form. Extra fields HubSpot doesn't know on that form
|
|
139
150
|
* 400 the whole request, so callers should filter first. A GDPR block on the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-hubspot",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.9",
|
|
4
4
|
"description": "The form builder for HubSpot in Strapi — multi-step forms with conditional fields mapped to real CRM properties, a public submit pipeline with retries, and save-time mapping validation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"strapi",
|