Vai al contenuto principale
Stiamo espandendo attivamente il supporto ai webhook.Appena arrivato: ritentativi 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 fare polling per lo stato, la tua applicazione riceve aggiornamenti istantanei.

Casi d’Uso

Elaborazione Asincrona

Ricevi notifiche quando batch o crawl sono completati invece di fare polling

Trigger 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 di busta 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 della Busta

CampoDescrizione
idID dell’evento — lo stesso in tutti i tentativi di ritentativo
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 ritentativo.

Comportamento di Ritentativo

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 ritentativo: 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❌ Ritentativo (non seguiamo i redirect)
400 Bad Request❌ Ritentativo
500 Server Error❌ Ritentativo
Timeout (>30s)❌ Ritentativo
Connessione rifiutata❌ Ritentativo

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():
    # 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 webhook in modo asincrono:
@app.route('/webhooks', methods=['POST'])
def webhook():
    queue.enqueue(process_webhook, request.json)
    return 'OK', 200  # Rispondi immediatamente

Prossimamente

URL Predefinito del 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.