Webhookサポートを積極的に拡大中です。新機能: 指数バックオフを使用した自動再試行 — 失敗した配信は30分以内に最大5回再試行されます。近日公開予定:
- チーム全体のデフォルトWebhook URL
- ペイロード検証のための暗号署名
早期アクセスをご希望ですか? info@olostep.com までご連絡いただくか、Slackコミュニティに参加してください。
Webhooksは、長時間実行される操作が完了したときに、リアルタイムのHTTP POST通知をサーバーに送信します。ステータスをポーリングする代わりに、アプリケーションは即座に更新を受け取ります。
使用例
非同期処理
バッチやクロールが完了したときに通知を受け取ることでポーリングを避ける
パイプライントリガー
データが準備できたときに自動的に下流処理をトリガーする
アラート
完了時にSlack、メール、その他のシステムにアラートを送信する
データ同期
Olostepの結果とデータベースを同期させる
サポートされているイベント
バッチの処理が終了したときに発生します(すべてのアイテムが完了または失敗した場合)。{
"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"
}
}
クロールが終了し、発見されたすべてのページが処理されたときに発生します。{
"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"
}
}
Webhooksの設定
リソースを作成する際にwebhookを渡します。このURLが完了通知を受け取ります。
パラメータ名: 標準のパラメータはwebhookです。後方互換性のために、webhook_urlもエイリアスとして受け入れられます。
import requests
# バッチの例
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"
}
)
# クロールの例
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"
}
)
// バッチの例
const batchResponse = await fetch('https://api.olostep.com/v1/batches', {
method: 'POST',
headers: {
'Authorization': 'Bearer <YOUR_API_KEY>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
items: [
{ url: 'https://example.com/page1', custom_id: "1" },
{ url: 'https://example.com/page2', custom_id: "2" }
],
webhook: 'https://your-server.com/webhooks/olostep'
})
});
// クロールの例
const crawlResponse = await fetch('https://api.olostep.com/v1/crawls', {
method: 'POST',
headers: {
'Authorization': 'Bearer <YOUR_API_KEY>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
start_url: 'https://example.com',
max_pages: 50,
webhook: 'https://your-server.com/webhooks/olostep'
})
});
# バッチの例
curl -X POST "https://api.olostep.com/v1/batches" \
-H "Authorization: Bearer $OLOSTEP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"url": "https://example.com/page1", "custom_id": "1"},
{"url": "https://example.com/page2", "custom_id": "2"}
],
"webhook": "https://your-server.com/webhooks/olostep"
}'
# クロールの例
curl -X POST "https://api.olostep.com/v1/crawls" \
-H "Authorization: Bearer $OLOSTEP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"start_url": "https://example.com",
"max_pages": 50,
"webhook": "https://your-server.com/webhooks/olostep"
}'
Webhookペイロード
すべてのWebhookペイロードは統一されたエンベロープ構造に従います:
{
"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
}
}
エンベロープフィールド
| フィールド | 説明 |
|---|
id | イベントID — すべての再試行で同じ |
object | イベントタイプ(例:event.batch.completed) |
timestamp | この配信試行が送信された時刻(エポックミリ秒) |
delivery_attempt | 現在の試行 / 最大試行回数(例:1/5, 3/5) |
data | 実際のリソースデータ(APIレスポンスと同じ形式) |
idフィールドを使用して、受信側でWebhook配信を重複排除します。同じイベントIDがすべての再試行に表示されます。
再試行の動作
失敗したWebhook配信は、30分間のウィンドウで指数バックオフを使用して自動的に再試行されます:
| 試行 | 次の試行までの遅延 | 累積時間 |
|---|
| 1 | 即時 | 0分 |
| 2 | 約2分 | 約2分 |
| 3 | 約4分 | 約6分 |
| 4 | 約7分 | 約13分 |
| 5 | 約15分 | 約28分 |
合計再試行ウィンドウ: 30分
リクエストごとのタイムアウト: 30秒
成功と見なされる条件
エンドポイントは30秒以内に2xxステータスコードを返す必要があります。それ以外の応答は再試行をトリガーします。
| 応答 | 結果 |
|---|
200 OK | ✅ 配信済み |
201 Created | ✅ 配信済み |
301 Redirect | ❌ 再試行(リダイレクトは追跡しません) |
400 Bad Request | ❌ 再試行 |
500 Server Error | ❌ 再試行 |
| タイムアウト(>30s) | ❌ 再試行 |
| 接続拒否 | ❌ 再試行 |
ベストプラクティス
200 OKを即座に返し、Webhookを非同期で処理します。処理が30秒以上かかる場合、再試行が行われ、重複配信が発生します。from queue import Queue
import threading
webhook_queue = Queue()
@app.route('/webhooks/olostep', methods=['POST'])
def handle_webhook():
# 非同期処理のためのキュー
webhook_queue.put(request.json)
# 即座に返す
return 'OK', 200
def process_webhooks():
while True:
event = webhook_queue.get()
# ここで遅い処理が行われます
process_event(event)
threading.Thread(target=process_webhooks, daemon=True).start()
idフィールドを使用して重複を排除します。処理済みのイベントIDを保存し、重複をスキップします。processed_events = set() # 本番環境ではRedis/DBを使用
def handle_event(event):
if event['id'] in processed_events:
return # すでに処理済み
# イベントを処理
process_batch_completed(event['data'])
# 処理済みとしてマーク
processed_events.add(event['id'])
デバッグのためにすべてのWebhook受信をログに記録します。イベントID、タイムスタンプ、処理結果を含めます。import logging
@app.route('/webhooks/olostep', methods=['POST'])
def handle_webhook():
event = request.json
logging.info(f"Webhook received: id={event['id']} type={event['object']} attempt={event['delivery_attempt']}")
try:
process_event(event)
logging.info(f"Webhook processed: id={event['id']}")
except Exception as e:
logging.error(f"Webhook failed: id={event['id']} error={e}")
raise
return 'OK', 200
Webhookエンドポイントには常にHTTPSを使用してください。HTTPエンドポイントは盗聴や中間者攻撃に対して脆弱です。
トラブルシューティング
- リクエストに
webhookパラメータが含まれていることを確認する
- エンドポイントが公開アクセス可能であることを確認する(localhostではない)
- サーバーログで受信リクエストを確認する
2xxステータスコードを返していることを確認する
これは再試行中に予想される動作です。idフィールドを使用して冪等性のある処理を実装してください:def handle_event(event):
if already_processed(event['id']):
return # 重複をスキップ
process_event(event)
mark_processed(event['id'])
エンドポイントは30秒以内に応答する必要があります。Webhookを非同期で処理してください:@app.route('/webhooks', methods=['POST'])
def webhook():
queue.enqueue(process_webhook, request.json)
return 'OK', 200 # 即座に応答
近日公開予定
チームデフォルトURL
アカウント設定でデフォルトのWebhook URLを設定します。すべてのリクエストはこのURLを使用しますが、上書きすることも可能です。
署名検証
OlostepからのWebhookペイロードを検証するための暗号署名(HMAC-SHA256)。