Documentation Index
Fetch the complete documentation index at: https://docs.olostep.com/llms.txt
Use this file to discover all available pages before exploring further.
我们正在积极扩展 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"
}
)
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 | 此传递尝试发送的时间(epoch 毫秒) |
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 秒内响应。异步处理 webhooks:@app.route('/webhooks', methods=['POST'])
def webhook():
queue.enqueue(process_webhook, request.json)
return 'OK', 200 # 立即响应
即将推出
团队默认 URL
在您的账户设置中配置默认 webhook URL。所有请求将使用此 URL,除非被覆盖。
签名验证
使用加密签名(HMAC-SHA256)验证 webhook 有效载荷来自 Olostep。