Automatización

Sigue trabajando como hasta ahora.

Tu PIM, ERP, DAM o una carpeta compartida ya tiene los datos y las fotos. Elige la primera receta que encaje: todas funcionan con cualquier portal de Open Brand Exchange.

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

¿Qué receta te encaja?

Tienes…UsaCódigo necesario
un CSV o zip en una dirección web, un servidor SFTP o un bucket S3Importación programadaninguno
una carpeta donde llegan las exportacionesobx watchninguno
un servidor o PC que ejecuta tareas por la nochecron o Programador de tareasuna línea
tus exportaciones en un repositorio GitGitHub Actionun archivo YAML
n8n, Make o ZapierPasos HTTPninguno (visual)
un desarrollador que conecta tu PIM o ERPLa API directamenteun poco

Un formato para todo

Todas las formas de publicar leen lo mismo: un products.csv con una fila por talla y fotos llamadas {style}_{color}_{position}.jpg (referencia, color, posición). Con eso, todas las recetas de abajo funcionan.

products.csv (abreviado)
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
Nombres de archivo de las fotos
images/
  KO-1001_NVY_1.jpg     ← style KO-1001, colour NVY, position 1 (front)
  KO-1001_NVY_2.jpg
  KO-1001_NVY_3.jpg

El formato de importación completo

Lo que necesitas

En tu administración, ve a Subida automática → Claves de acceso y crea una clave nueva. Tendrás dos valores: la dirección de tu portal (OBX_URL) y la propia clave (OBX_TOKEN). La clave solo se muestra una vez.

export OBX_URL=https://brands.kestrel.example
export OBX_TOKEN=obxi_…   # admin → Automatic upload → Access keys (shown once)

Da a cada sistema su propia clave. Así puedes revocar una sin romper las demás.

1. Importación programada (sin código)

En tu administración: Subida automática → Importaciones programadas → Añadir importación programada. Elige el origen y la frecuencia.

  • Dirección web (HTTPS): la dirección de un products.csv, o de un zip con products.csv y fotos. Los datos de acceso se guardan cifrados.
  • SFTP: servidor, usuario, contraseña o clave, y la carpeta con la exportación.
  • Bucket S3: AWS S3, Cloudflare R2, MinIO o Backblaze: endpoint, bucket, carpeta y una clave de solo lectura.

Elige «Solo añadir y actualizar» o «Retirar también los artículos que falten». La segunda opción retira también lo que desapareció del archivo, pero se detiene si fuera a desaparecer más de la mitad de una marca, para que una exportación defectuosa nunca vacíe tu catálogo. «Probar conexión» muestra qué archivos leería.

La herramienta obx

obx es un único programa para Windows, macOS y Linux. Lee OBX_URL y OBX_TOKEN del entorno, sube solo las fotos nuevas o modificadas, crea las versiones web cuando hace falta y espera a que tu portal lo haya procesado todo. Ejecútalo tantas veces como quieras: los artículos sin cambios no cuestan nada.

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

Código de salida 0 = todo bien, 2 = terminado pero algunas filas tenían errores (se muestran), 1 = fallo.

Descargar obx · obx-go

2. Una carpeta que se publica sola: obx watch

Deja que tu PIM, tu ERP o un compañero guarde exportaciones en una carpeta. obx watch publica en cuanto algo cambia y omite las fotos que siguen igual. Ejecútalo como servicio o con 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 o Programador de tareas de Windows

Linux o 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, una vez)
$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

Guarda OBX_URL y OBX_TOKEN como secretos del repositorio. Lo mismo funciona en GitLab CI, Bitbucket o Azure DevOps: instala obx y ejecuta 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 o Zapier

Usa un paso HTTP Request normal con la cabecera Authorization: Bearer seguida de tu clave. Cada paso se puede repetir sin riesgo: enviar los mismos datos dos veces no cambia nada.

Artículo (por ejemplo, cuando cambia en tu PIM)
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}]}]}
Color y talla, con su 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: primero los datos, luego el archivo
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>

El Portal para Cloudflare no crea por sí mismo versiones web de las fotos. Publica allí con obx o desde «Importaciones» en tu administración: ellos las crean por ti. Las fotos que llegan de otra forma, por ejemplo con una importación programada, se muestran hasta entonces a su tamaño original.

Retirar algo
PATCH {OBX_URL}/obx/v1/ingest/products/KO-1001
Authorization: Bearer obxi_…
Content-Type: application/merge-patch+json

{"status": "unpublished"}

¿Quieres un aviso cuando pase algo? En tu administración, añade una notificación (webhook) para una importación terminada o una nueva solicitud de acceso, y haz que active un disparador en n8n, Make o Zapier.

6. La API directamente (para desarrolladores)

Una integración recuerda lo que envió la última vez y solo envía los cambios, por lotes. O envía el CSV tal cual y deja que el portal lo lea.

Omitir las fotos que el portal ya tiene y enviar un lote
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"
Un CSV y un zip de fotos de una vez
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>

Todos los detalles están en la especificación:Ingest API ·recetas de automatización ·SDK de Go ·Desarrolladores