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.

Terminal
$ 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
publish.ymlGitHub Action
# .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: export

Welk recept past bij jou?

Je hebt…GebruikCode nodig
een CSV of zip op een webadres, SFTP-server of S3-bucketGeplande importnee
een map waar exports in terechtkomenobx watchnee
een server of pc die 's nachts taken draaitcron of Taakplanneréén regel
je exports in een Git-repositoryGitHub Actionéén YAML-bestand
n8n, Make of ZapierHTTP-stappennee (visueel)
een ontwikkelaar die je PIM of ERP koppeltDe API directeen 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.

products.csv (ingekort)
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,2000100101025
Bestandsnamen van foto's
images/
  KO-1001_NVY_1.jpg     ← style KO-1001, colour NVY, position 1 (front)
  KO-1001_NVY_2.jpg
  KO-1001_NVY_3.jpg

Het volledige importformaat

Wat 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 errors

Exitcode 0 = alles goed, 2 = klaar maar sommige regels hadden fouten (die worden getoond), 1 = mislukt.

obx downloaden · obx-go

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/outbox
Docker
docker run -d --restart unless-stopped \
  -e OBX_URL -e OBX_TOKEN \
  -v /data/outbox:/outbox \
  ghcr.io/openbrandexchange/obx watch /outbox

3. cron of Windows Taakplanner

Linux of macOS
# 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
Windows (PowerShell, eenmalig)
$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/images

5. 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.

Artikel (bijvoorbeeld als het in je PIM wijzigt)
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}]}]}
Kleur en maat, met de EAN
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"}
Foto: eerst de gegevens, dan het bestand zelf
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.

Iets offline halen
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.

Foto's overslaan die het portaal al heeft, dan één batch versturen
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"
Een CSV en een zip met foto's in één keer
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