Vai al contenuto principale
Stiamo espandendo attivamente il supporto per i webhook.Appena arrivato: tentativi automatici con backoff esponenziale — le consegne fallite vengono ora ritentate fino a 5 volte in 30 minuti.Prossimamente:
  • URL webhook predefiniti per tutto il team
  • Firme crittografiche per la verifica del payload
Vuoi accesso anticipato? Contattaci a info@olostep.com o unisciti alla nostra comunità Slack.

Panoramica

I webhook inviano notifiche HTTP POST in tempo reale al tuo server quando le operazioni di lunga durata sono completate. Invece di effettuare polling per lo stato, la tua applicazione riceve aggiornamenti istantanei.

Casi d’uso

Elaborazione asincrona

Ricevi notifiche quando i batch o i crawl sono completati invece di effettuare polling

Trigger della pipeline

Attiva automaticamente l’elaborazione a valle quando i dati sono pronti

Allerta

Invia avvisi a Slack, email o altri sistemi al completamento

Sincronizzazione dati

Mantieni il tuo database sincronizzato con i risultati di Olostep

Eventi supportati

Attivato quando un batch termina l’elaborazione (tutti gli elementi completati o falliti).
{
  "id": "event_a1b2c3d4e5f6g7h8",
  "object": "event.batch.completed",
  "timestamp": 1737570000000,
  "delivery_attempt": "1/5",
  "data": {
    "id": "batch_xyz123",
    "object": "batch",
    "status": "completed",
    "items_total": 100,
    "items_completed": 98,
    "items_failed": 2,
    "created_at": "2024-01-15T10:00:00Z",
    "completed_at": "2024-01-15T10:05:32Z"
  }
}
Attivato quando un crawl termina e tutte le pagine scoperte sono state elaborate.
{
  "id": "event_x9y8z7w6v5u4t3s2",
  "object": "event.crawl.completed",
  "timestamp": 1737570000000,
  "delivery_attempt": "1/5",
  "data": {
    "id": "crawl_abc789",
    "object": "crawl",
    "status": "completed",
    "start_url": "https://example.com",
    "urls_count": 87,
    "max_pages": 100,
    "max_depth": 3,
    "actual_max_depth": 3,
    "start_epoch": 1737569500000,
    "start_date": "2024-01-15"
  }
}

Configurazione dei Webhooks

Passa webhook quando crei una risorsa. Questo URL riceve la notifica di completamento.
Nome del parametro: Il parametro canonico è webhook. Per compatibilità retroattiva, webhook_url è accettato come alias.
import requests

# Esempio di batch
response = requests.post(
    "https://api.olostep.com/v1/batches",
    headers={"Authorization": "Bearer <YOUR_API_KEY>"},
    json={
        "items": [
            {"url": "https://example.com/page1", "custom_id": "1"},
            {"url": "https://example.com/page2", "custom_id": "2"}
        ],
        "webhook": "https://your-server.com/webhooks/olostep"
    }
)

# Esempio di crawl
response = requests.post(
    "https://api.olostep.com/v1/crawls",
    headers={"Authorization": "Bearer <YOUR_API_KEY>"},
    json={
        "start_url": "https://example.com",
        "max_pages": 50,
        "webhook": "https://your-server.com/webhooks/olostep"
    }
)

Payload del Webhook

Tutti i payload dei webhook seguono una struttura unificata:
{
  "id": "event_a1b2c3d4e5f6g7h8",
  "object": "event.batch.completed",
  "timestamp": 1737570000000,
  "delivery_attempt": "1/5",
  "data": {
    "id": "batch_xyz123",
    "object": "batch",
    "status": "completed",
    "items_total": 100,
    "items_completed": 98,
    "items_failed": 2
  }
}

Campi dell’involucro

CampoDescrizione
idID dell’evento — stesso in tutti i tentativi di ritrasmissione
objectTipo di evento (es. event.batch.completed)
timestampQuando è stato inviato questo tentativo di consegna (epoch ms)
delivery_attemptTentativo corrente / tentativi massimi (es. 1/5, 3/5)
dataI dati effettivi della risorsa (stesso formato della risposta API)
Usa il campo id per deduplicare le consegne dei webhook nel tuo ricevitore. Lo stesso ID evento appare in tutti i tentativi di ritrasmissione.

Comportamento di Ritrasmissione

Le consegne dei webhook fallite vengono automaticamente ritentate con backoff esponenziale in una finestra di 30 minuti:
TentativoRitardo prima del tentativoTempo cumulativo
1Immediato0 min
2~2 min~2 min
3~4 min~6 min
4~7 min~13 min
5~15 min~28 min
Finestra totale di ritrasmissione: 30 minuti
Timeout per richiesta: 30 secondi

Cosa Conta come Successo

Il tuo endpoint deve restituire un codice di stato 2xx entro 30 secondi. Qualsiasi altra risposta attiva un ritentativo.
RispostaRisultato
200 OK✅ Consegnato
201 Created✅ Consegnato
301 Redirect❌ Ritenta (non seguiamo i redirect)
400 Bad Request❌ Ritenta
500 Server Error❌ Ritenta
Timeout (>30s)❌ Ritenta
Connessione rifiutata❌ Ritenta

Migliori Pratiche

Restituisci 200 OK immediatamente ed elabora il webhook in modo asincrono. Se la tua elaborazione richiede più di 30 secondi, ritenteremo — causando consegne duplicate.
from queue import Queue
import threading

webhook_queue = Queue()

@app.route('/webhooks/olostep', methods=['POST'])
def handle_webhook():
    # Metti in coda per l'elaborazione asincrona
    webhook_queue.put(request.json)
    
    # Restituisci immediatamente
    return 'OK', 200

def process_webhooks():
    while True:
        event = webhook_queue.get()
        # L'elaborazione lenta avviene qui
        process_event(event)

threading.Thread(target=process_webhooks, daemon=True).start()
Usa il campo id per deduplicare. Memorizza gli ID degli eventi elaborati e salta i duplicati.
processed_events = set()  # Usa Redis/DB in produzione

def handle_event(event):
    if event['id'] in processed_events:
        return  # Già elaborato
    
    # Elabora l'evento
    process_batch_completed(event['data'])
    
    # Segna come elaborato
    processed_events.add(event['id'])
Registra tutte le ricevute dei webhook per il debug. Includi l’ID dell’evento, il timestamp e il risultato dell’elaborazione.
import logging

@app.route('/webhooks/olostep', methods=['POST'])
def handle_webhook():
    event = request.json
    logging.info(f"Webhook ricevuto: id={event['id']} tipo={event['object']} tentativo={event['delivery_attempt']}")
    
    try:
        process_event(event)
        logging.info(f"Webhook elaborato: id={event['id']}")
    except Exception as e:
        logging.error(f"Webhook fallito: id={event['id']} errore={e}")
        raise
    
    return 'OK', 200
Usa sempre HTTPS per gli endpoint dei webhook. Gli endpoint HTTP sono vulnerabili a intercettazioni e attacchi man-in-the-middle.

Risoluzione dei Problemi

  1. Verifica che il parametro webhook sia stato incluso nella tua richiesta
  2. Verifica che il tuo endpoint sia pubblicamente accessibile (non localhost)
  3. Controlla i log del tuo server per le richieste in arrivo
  4. Assicurati di restituire un codice di stato 2xx
Questo è previsto durante i ritentativi. Implementa una gestione idempotente usando il campo id:
def handle_event(event):
    if already_processed(event['id']):
        return  # Salta il duplicato
    
    process_event(event)
    mark_processed(event['id'])
Il tuo endpoint deve rispondere entro 30 secondi. Elabora i webhooks in modo asincrono:
@app.route('/webhooks', methods=['POST'])
def webhook():
    queue.enqueue(process_webhook, request.json)
    return 'OK', 200  # Rispondi immediatamente

Prossimamente

URL predefinito per il team

Configura un URL webhook predefinito nelle impostazioni del tuo account. Tutte le richieste utilizzeranno questo URL a meno che non venga sovrascritto.

Verifica della firma

Firme crittografiche (HMAC-SHA256) per verificare che i payload dei webhook provengano da Olostep.
Vuoi accesso anticipato a queste funzionalità? Contattaci a info@olostep.com o unisciti alla nostra comunità Slack.