strapi-plugin-hubspot 0.13.0 → 0.13.1
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 +11 -0
- package/README.md +27 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.mjs +8 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.13.1 — 2026-09-21
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **GDPR proof on submissions.** `meta.consent` / `meta.consentedAt` sent by
|
|
9
|
+
the frontend are stored on the submission row and written on the HubSpot
|
|
10
|
+
timeline note. They are not CRM properties — an unknown HubSpot key would
|
|
11
|
+
fail the whole upsert. Rebuild HubSpot's native legal-consent block as a
|
|
12
|
+
required checkbox named `consent` (see README).
|
|
13
|
+
|
|
3
14
|
## 0.13.0 — 2026-08-31
|
|
4
15
|
|
|
5
16
|
### Added
|
package/README.md
CHANGED
|
@@ -66,6 +66,33 @@ Every submission is stored in **HubSpot form submissions** (Content Manager),
|
|
|
66
66
|
synced or not, with the CRM ids when the sync succeeded — the source of truth
|
|
67
67
|
lives in your database, not in HubSpot's availability.
|
|
68
68
|
|
|
69
|
+
### GDPR consent
|
|
70
|
+
|
|
71
|
+
HubSpot's native *legal consent* block is **not** a CRM field. Importing a
|
|
72
|
+
HubSpot form skips it (you'll see "rebuild it as a field") because this
|
|
73
|
+
builder maps answers onto Contact/Company properties, and an unknown property
|
|
74
|
+
makes HubSpot reject the whole upsert.
|
|
75
|
+
|
|
76
|
+
To connect consent so the CRM and Strapi both keep a proof:
|
|
77
|
+
|
|
78
|
+
1. **In HubSpot** (Settings → Properties → Contact), create a checkbox
|
|
79
|
+
property, e.g. `rgpd_consent`. Optionally a datetime `rgpd_consented_at`.
|
|
80
|
+
2. **In the form builder** (Admin → HubSpot Forms), last step: add a
|
|
81
|
+
**Checkbox**, name it `consent` (that name is what the site recognizes —
|
|
82
|
+
it will not inject a second box), mark it **required**.
|
|
83
|
+
3. **Map it**: Object = Contact, property = `rgpd_consent`. The visitor's tick
|
|
84
|
+
then lands on the contact. Leave `consentedAt` unmapped; the frontend
|
|
85
|
+
sends it in `meta.consentedAt`, stored on the submission and on the
|
|
86
|
+
timeline note.
|
|
87
|
+
4. **Publish** the form. The public submit pipeline already refuses a payload
|
|
88
|
+
without consent when the site is in front (Nuxt BFF). Direct calls to
|
|
89
|
+
`/api/hubspot/forms/:slug/submit` still accept a form that has no consent
|
|
90
|
+
field — add the checkbox so required-field validation covers them too.
|
|
91
|
+
|
|
92
|
+
The newsletter block on the site is **not** a HubSpot form: it upserts the
|
|
93
|
+
email as a contact and writes a timeline note with the consent timestamp.
|
|
94
|
+
No form to create in the builder for that one.
|
|
95
|
+
|
|
69
96
|
### Browsing submissions
|
|
70
97
|
|
|
71
98
|
The **Submissions** button on the forms list (also reachable from a form's
|
package/dist/server/index.js
CHANGED
|
@@ -1710,6 +1710,10 @@ function createFormsService(strapi, _opts = {}) {
|
|
|
1710
1710
|
const path = opts.meta.originPath ? ` (${escapeHtml(String(opts.meta.originPath))})` : "";
|
|
1711
1711
|
lines.push(`<strong>Sujet</strong> : ${escapeHtml(String(opts.meta.originLabel))}${path}`);
|
|
1712
1712
|
}
|
|
1713
|
+
if (opts.meta.consent === true) {
|
|
1714
|
+
const when = typeof opts.meta.consentedAt === "string" && opts.meta.consentedAt ? ` (${escapeHtml(opts.meta.consentedAt)})` : "";
|
|
1715
|
+
lines.push(`<strong>Consentement RGPD</strong> : oui${when}`);
|
|
1716
|
+
}
|
|
1713
1717
|
for (const record of opts.companies ?? []) {
|
|
1714
1718
|
if (!record.name && !record.siret) continue;
|
|
1715
1719
|
const bits = [record.name, record.siret ? `SIRET ${record.siret}` : ""].filter(Boolean);
|
|
@@ -2893,6 +2897,10 @@ const controllers = {
|
|
|
2893
2897
|
const v = rawMeta[key];
|
|
2894
2898
|
if (typeof v === "string" && v) meta[key] = v.slice(0, 500);
|
|
2895
2899
|
}
|
|
2900
|
+
if (rawMeta.consent === true) meta.consent = true;
|
|
2901
|
+
if (typeof rawMeta.consentedAt === "string" && rawMeta.consentedAt.trim()) {
|
|
2902
|
+
meta.consentedAt = rawMeta.consentedAt.trim().slice(0, 40);
|
|
2903
|
+
}
|
|
2896
2904
|
const outcome = await strapi.plugin("hubspot").service("forms").submit(entry, values, meta);
|
|
2897
2905
|
if (!outcome.ok) {
|
|
2898
2906
|
ctx.status = 422;
|
package/dist/server/index.mjs
CHANGED
|
@@ -1709,6 +1709,10 @@ function createFormsService(strapi, _opts = {}) {
|
|
|
1709
1709
|
const path = opts.meta.originPath ? ` (${escapeHtml(String(opts.meta.originPath))})` : "";
|
|
1710
1710
|
lines.push(`<strong>Sujet</strong> : ${escapeHtml(String(opts.meta.originLabel))}${path}`);
|
|
1711
1711
|
}
|
|
1712
|
+
if (opts.meta.consent === true) {
|
|
1713
|
+
const when = typeof opts.meta.consentedAt === "string" && opts.meta.consentedAt ? ` (${escapeHtml(opts.meta.consentedAt)})` : "";
|
|
1714
|
+
lines.push(`<strong>Consentement RGPD</strong> : oui${when}`);
|
|
1715
|
+
}
|
|
1712
1716
|
for (const record of opts.companies ?? []) {
|
|
1713
1717
|
if (!record.name && !record.siret) continue;
|
|
1714
1718
|
const bits = [record.name, record.siret ? `SIRET ${record.siret}` : ""].filter(Boolean);
|
|
@@ -2892,6 +2896,10 @@ const controllers = {
|
|
|
2892
2896
|
const v = rawMeta[key];
|
|
2893
2897
|
if (typeof v === "string" && v) meta[key] = v.slice(0, 500);
|
|
2894
2898
|
}
|
|
2899
|
+
if (rawMeta.consent === true) meta.consent = true;
|
|
2900
|
+
if (typeof rawMeta.consentedAt === "string" && rawMeta.consentedAt.trim()) {
|
|
2901
|
+
meta.consentedAt = rawMeta.consentedAt.trim().slice(0, 40);
|
|
2902
|
+
}
|
|
2895
2903
|
const outcome = await strapi.plugin("hubspot").service("forms").submit(entry, values, meta);
|
|
2896
2904
|
if (!outcome.ok) {
|
|
2897
2905
|
ctx.status = 422;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-hubspot",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1",
|
|
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",
|