Automatiseren
Werk gewoon door zoals je nu werkt.
Je PIM, ERP, DAM of een gedeelde map heeft de data en de foto's al. Kies het eerste recept dat past: ze werken met elk Open Brand Exchange-portaal.
$ obx push ./export
Publishing to brands.kestrel.example (Kestrel, Kestrel Trail)
images: 27 checked, 3 uploaded (4.2 MB) in 3s
Done: rows: 40, images: 27 → new: 2 · updated: 3 · unchanged: 35# .github/workflows/publish.yml
on:
push:
paths: ["export/**"]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: openbrandexchange/obx-go/push-action@v0
with:
url: ${{ secrets.OBX_URL }}
token: ${{ secrets.OBX_TOKEN }}
folder: exportWelk recept past bij jou?
| Je hebt… | Gebruik | Code nodig |
|---|---|---|
| een CSV of zip op een webadres, SFTP-server of S3-bucket | Geplande import | nee |
| een map waar exports in terechtkomen | obx watch | nee |
| een server of pc die 's nachts taken draait | cron of Taakplanner | één regel |
| je exports in een Git-repository | GitHub Action | één YAML-bestand |
| n8n, Make of Zapier | HTTP-stappen | nee (visueel) |
| een ontwikkelaar die je PIM of ERP koppelt | De API direct | een beetje |
Eén formaat voor alles
Elke manier van publiceren leest hetzelfde: een products.csv met één regel per maat, en foto's met de naam {style}_{color}_{position}.jpg (stijl, kleur, positie). Heb je dat, dan werkt elk recept hieronder.
brand,style_number,name:en,name:nl,item_type,season,materials,color_code,color_name:en,size,gtin
Kestrel,KO-1001,Merino Crew Sweater,Merino trui met ronde hals,sweater,AW26,main: 100% merino_wool,NVY,Navy,S,2000100101018
Kestrel,KO-1001,Merino Crew Sweater,Merino trui met ronde hals,sweater,AW26,main: 100% merino_wool,NVY,Navy,M,2000100101025images/
KO-1001_NVY_1.jpg ← style KO-1001, colour NVY, position 1 (front)
KO-1001_NVY_2.jpg
KO-1001_NVY_3.jpgWat je nodig hebt
Ga in je beheeromgeving naar Automatisch uploaden → Toegangssleutels en maak een nieuwe sleutel aan. Je hebt dan twee waarden: het adres van je portaal (OBX_URL) en de sleutel zelf (OBX_TOKEN). De sleutel wordt maar één keer getoond.
export OBX_URL=https://brands.kestrel.example
export OBX_TOKEN=obxi_… # admin → Automatic upload → Access keys (shown once)Geef elk systeem een eigen sleutel. Dan kun je er één intrekken zonder de rest te breken.
1. Geplande import (zonder code)
In je beheeromgeving: Automatisch uploaden → Geplande imports → Geplande import toevoegen. Kies de bron en hoe vaak hij moet draaien.
- Webadres (HTTPS): het adres van een products.csv, of van een zip met products.csv en foto's. Inloggegevens worden versleuteld bewaard.
- SFTP: server, gebruiker, wachtwoord of sleutel, en de map met de export.
- S3-bucket: AWS S3, Cloudflare R2, MinIO of Backblaze: endpoint, bucket, map en een alleen-lezen sleutel.
Kies "Alleen toevoegen en bijwerken" of "Ontbrekende artikelen ook offline halen". De tweede haalt ook offline wat uit het bestand verdween, maar stopt als meer dan de helft van een merk zou verdwijnen, zodat een kapotte export nooit je catalogus leegmaakt. Met "Verbinding testen" zie je welke bestanden hij zou lezen.
De obx-tool
obx is één programma voor Windows, macOS en Linux. Het leest OBX_URL en OBX_TOKEN uit de omgeving, uploadt alleen nieuwe of gewijzigde foto's, maakt waar nodig de webversies en wacht tot je portaal alles heeft verwerkt. Draai het zo vaak als je wilt: ongewijzigde artikelen kosten niets.
obx info # check the token, see limits and brands
obx push --csv products.csv --images ./images # publish a CSV and a folder (or zip) of images
obx push --package export.zip # the same, as one zip
obx push --csv products.csv --images ./images --mirror # also take offline what is no longer in the file
obx push --csv products.csv --images ./images --dry-run # only check, change nothing
obx watch ./outbox # keep publishing whatever lands in a folder
obx status # recent jobs and their errorsExitcode 0 = alles goed, 2 = klaar maar sommige regels hadden fouten (die worden getoond), 1 = mislukt.
2. Een map die zichzelf publiceert: obx watch
Laat je PIM, ERP of een collega exports in een map zetten. obx watch publiceert zodra er iets verandert en slaat foto's over die hetzelfde bleven. Laat het draaien als dienst, of met Docker:
obx watch /data/outboxdocker run -d --restart unless-stopped \
-e OBX_URL -e OBX_TOKEN \
-v /data/outbox:/outbox \
ghcr.io/openbrandexchange/obx watch /outbox3. cron of Windows Taakplanner
# crontab -e: every night at 02:30
30 2 * * * OBX_URL=https://brands.kestrel.example OBX_TOKEN=obxi_… /usr/local/bin/obx push --csv /exports/products.csv --images /exports/images >> /var/log/obx.log 2>&1$action = New-ScheduledTaskAction -Execute "C:\Tools\obx.exe" -Argument "push --csv D:\Export\products.csv --images D:\Export\images"
$trigger = New-ScheduledTaskTrigger -Daily -At 2:30am
[Environment]::SetEnvironmentVariable("OBX_URL", "https://brands.kestrel.example", "Machine")
[Environment]::SetEnvironmentVariable("OBX_TOKEN", "obxi_…", "Machine")
Register-ScheduledTask -TaskName "Publish to OBX" -Action $action -Trigger $trigger -User "SYSTEM"4. GitHub Action
Zet OBX_URL en OBX_TOKEN als repository secrets. Hetzelfde werkt in GitLab CI, Bitbucket of Azure DevOps: installeer obx en draai obx push.
# .github/workflows/publish.yml (secrets: OBX_URL, OBX_TOKEN)
name: Publish product content
on:
push:
branches: [main]
paths: ["export/**"]
schedule:
- cron: "30 2 * * *"
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install obx
run: |
curl -fsSL https://github.com/openbrandexchange/obx-go/releases/latest/download/obx_linux_amd64.tar.gz | tar -xz obx
sudo mv obx /usr/local/bin/
- name: Publish
env:
OBX_URL: ${{ secrets.OBX_URL }}
OBX_TOKEN: ${{ secrets.OBX_TOKEN }}
run: obx push --csv export/products.csv --assets-csv export/assets.csv --images export/images5. n8n, Make of Zapier
Gebruik een gewone HTTP Request-stap met de header Authorization: Bearer gevolgd door je sleutel. Elke stap mag je herhalen: dezelfde data twee keer sturen verandert niets.
PUT {OBX_URL}/obx/v1/ingest/products/KO-1001
Authorization: Bearer obxi_…
Content-Type: application/json
{"style_number": "KO-1001",
"name": {"en": "Merino Crew Sweater", "nl": "Merino trui met ronde hals"},
"item_type": "sweater", "season": "AW26",
"materials": [{"part": "main", "fibers": [{"fiber": "merino_wool", "percentage": 100}]}]}PUT {OBX_URL}/obx/v1/ingest/variants/2000100101025
Authorization: Bearer obxi_…
Content-Type: application/json
{"product_external_id": "KO-1001", "gtin": "2000100101025",
"color": {"code": "NVY", "name": {"en": "Navy"}}, "size": "M"}PUT {OBX_URL}/obx/v1/ingest/assets/KO-1001_NVY_1
Authorization: Bearer obxi_…
Content-Type: application/json
{"product_external_id": "KO-1001", "color_code": "NVY",
"role": "packshot", "view": "front", "position": 1}
PUT {OBX_URL}/obx/v1/ingest/assets/KO-1001_NVY_1/files/original
Authorization: Bearer obxi_…
Content-Type: image/jpeg
<the image file as binary body>Het Portaal voor Cloudflare maakt zelf geen webversies van foto's. Publiceer daar met obx of via "Imports" in je beheeromgeving: die maken ze voor je. Foto's die op een andere manier binnenkomen, zoals via een geplande import, worden tot dan op origineel formaat getoond.
PATCH {OBX_URL}/obx/v1/ingest/products/KO-1001
Authorization: Bearer obxi_…
Content-Type: application/merge-patch+json
{"status": "unpublished"}Wil je een seintje als er iets gebeurt? Zet in je beheeromgeving een melding (webhook) op een afgeronde import of een nieuwe toegangsaanvraag, en laat die een trigger in n8n, Make of Zapier starten.
6. De API direct (voor ontwikkelaars)
Een koppeling onthoudt wat hij de vorige keer stuurde en stuurt alleen wijzigingen, in batches. Of stuur de CSV zoals hij is en laat het portaal hem lezen.
URL="$OBX_URL/obx/v1/ingest"; AUTH="Authorization: Bearer $OBX_TOKEN"
# 1. Upload only the images the node does not have yet (addressed by sha256).
for f in images/*.jpg; do
sha=$(shasum -a 256 "$f" | cut -d' ' -f1)
curl -sf -I -H "$AUTH" "$URL/blobs/$sha" >/dev/null || \
curl -sf -X PUT -H "$AUTH" -H 'Content-Type: image/jpeg' --data-binary @"$f" "$URL/blobs/$sha"
done
# 2. One batch of up to 1000 operations (NDJSON), processed in order.
cat > batch.ndjson <<'EOF'
{"op":"upsert","kind":"product","external_id":"KO-1001","data":{"style_number":"KO-1001","name":{"en":"Merino Crew Sweater"}}}
{"op":"upsert","kind":"variant","external_id":"2000100101025","data":{"product_external_id":"KO-1001","gtin":"2000100101025","color":{"code":"NVY"},"size":"M"}}
{"op":"unpublish","kind":"product","external_id":"KO-0999"}
EOF
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/x-ndjson' \
-H "Idempotency-Key: nightly-$(date +%F)" --data-binary @batch.ndjson "$URL/batch"curl -s -X POST -H "Authorization: Bearer $OBX_TOKEN" \
-F [email protected] -F [email protected] \
-F 'options={"mode":"upsert"};type=application/json' \
"$OBX_URL/obx/v1/ingest/imports" # returns a job; poll $OBX_URL/obx/v1/ingest/jobs/<id>Alle details staan in de specificatie:Ingest API ·automatiseringsrecepten ·Go-SDK ·Ontwikkelaars