A Google Cloud Function that enforces structural consistency of the B2B_Segmentation_Matrix table attribute across locales in Akeneo PIM, triggered by the Akeneo Event Platform.
The B2B_Segmentation_Matrix is a table attribute used to define segmentation data per market. The en_US locale is the source of truth for the row structure. This function ensures every other locale always mirrors that structure — locale managers are only responsible for filling in their own columns, not for managing which rows exist.
When en_US is updated:
- Rows added in
en_US→ skeleton rows (key column only) are appended to all other locales - Rows deleted from
en_US→ same rows are removed from all other locales - Existing sub-locale data for unchanged rows is always preserved
- Row order follows
en_US
When a sub-locale is updated:
- Extra rows not present in
en_US→ removed - Rows present in
en_USbut missing → re-added as skeleton rows - Sub-locale row order and all column values are otherwise untouched
Akeneo PIM
│ product.updated.delta (CloudEvent)
▼
Akeneo Event Platform
│ HTTPS webhook (HMAC-SHA256 signed)
▼
Google Cloud Function (europe-west1)
│ PATCH /api/rest/v1/products-uuid/{uuid}
▼
Akeneo PIM (corrected locale values written back)
.
├── b2b-segmentation-matrix-sync.js # Cloud Function entry point
├── register-event-subscription.js # One-time Event Platform setup script
├── deploy.sh # GCP deployment script
├── package.json
├── env.yaml.template # Environment variables template
└── README.md
- Node.js ≥ 22
- gcloud CLI installed and authenticated
- An Akeneo PIM connection with API credentials
- A Google Cloud project with Cloud Functions enabled
npm installcp env.yaml.template env.yamlEdit env.yaml and fill in all values:
| Variable | Description |
|---|---|
AKENEO_HOST |
PIM base URL, e.g. https://your-pim.cloud.akeneo.com |
AKENEO_CLIENT_ID |
OAuth2 client ID |
AKENEO_CLIENT_SECRET |
OAuth2 client secret |
AKENEO_USERNAME |
PIM user login |
AKENEO_PASSWORD |
PIM user password |
AKENEO_WEBHOOK_SECRET |
HMAC-SHA256 secret (see below) |
AKENEO_MATRIX_ATTRIBUTE |
(optional) Table attribute code — default: B2B_Segmentation_Matrix |
AKENEO_MASTER_LOCALE |
(optional) Source-of-truth locale — default: en_US |
AKENEO_MATRIX_KEY_COLUMN |
(optional) Column code used as row identifier — default: first column of first en_US row |
Generate a webhook secret:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
⚠️ Never commitenv.yamlto source control — it contains secrets. It is listed in.gitignore.
chmod +x deploy.sh
./deploy.shThe script deploys to the project and region configured at the top of deploy.sh and prints the function URL on completion.
Run this once after the first deployment to connect Akeneo's Event Platform to your function:
node register-event-subscription.js <FUNCTION_URL>Example:
node register-event-subscription.js https://b2b-segmentation-matrix-sync-xxxx-ew.a.run.appUse --dry-run to preview without making changes:
node register-event-subscription.js <FUNCTION_URL> --dry-runThe script is idempotent for the Subscriber (reuses an existing one), but creates a new Subscription each time. Check the Event Platform console to manage existing subscriptions.
Re-running deploy.sh updates the existing function in place — no downtime, no duplicate created.
npm install # regenerate package-lock.json if dependencies changed
./deploy.shThe Event Platform subscription does not need to be re-registered after a redeployment, as the function URL stays the same.
View live logs in the Google Cloud Console:
https://console.cloud.google.com/functions/details/europe-west1/b2b-segmentation-matrix-sync
Or stream them from the terminal:
gcloud functions logs read b2b-segmentation-matrix-sync \
--gen2 \
--region=europe-west1 \
--project=<YOUR_PROJECT_ID> \
--limit=50| Status | Meaning |
|---|---|
processed |
Function ran and patched one or more locales |
skipped |
Event was ignored (wrong attribute, no genuine change, empty master) |
error (401) |
HMAC signature invalid |
error (400) |
Malformed CloudEvent payload |
error (500) |
Unexpected internal error |
All incoming requests are verified against the HMAC-SHA256 signature in the X-AKENEO-SIGNATURE-PRIMARY header before any processing occurs. Requests with an invalid or missing signature are rejected with HTTP 401.
The core sync functions are exported from the main file for unit testing:
const {
syncFromMaster,
validateSubLocale,
resolveKeyColumn,
rowKey,
} = require('./b2b-segmentation-matrix-sync');syncFromMaster(masterRows, subRows, keyColumn)— returns corrected rows when master changed, ornullif already in syncvalidateSubLocale(masterRows, subRows, keyColumn)— returns corrected rows when sub-locale changed, ornullif already valid