Webhookエンドポイントとは?
Webhookエンドポイント(endpoint)は、ノート・要約・ドキュメントが変わった瞬間に Tiro が HTTP POST リクエストを送信する、お客様のアプリケーションの URL です。Tiro Platformにエンドポイントを一度登録しておくと、Tiro がすべてのイベントをリアルタイムでその宛先へ送信します。API をポーリングする必要はありません。
Webhook とは
Webhook を利用しますと、ワークスペースでイベントが発生した際に、アプリケーションがリアルタイムで通知を受け取れます。API をポーリングする代わりに、何かが起こるたびに Tiro がお客様の endpoint へ HTTP POST リクエストを送信します。
Webhook の仕組み
- 設定する: アプリケーションに webhook の endpoint を用意します
- 登録する: 受け取りたいイベントを処理するために、endpoint を追加します
- 受信する: イベントが発生すると即座に通知が届きます
- 処理する: アプリケーションでイベントのデータを処理します
イベントとリソースの構造
Webhook は イベント(Events) と リソース(Resources) を中心に構成されています。
イベント
イベントは、ワークスペースで発生したアクションを表します。詳しくは Note Events、Note Document Events、Note Summary Events、FolderNote Events をご覧ください。
Webhook イベントは metadata のみを含めることで、サイズが数百 KB 未満に収まるよう設計されています。transcript や script などの大きなコンテンツは、webhook の信頼性とパフォーマンスを確保するため、別の API を通じてアクセスします。
リソース
リソースは、イベントの対象となる主要なエンティティを表します。現在サポートしているのは以下のとおりです。
Note: 個々のノートのリソース
NoteDocument: ノートから生成されるテンプレートベースのドキュメント
NoteSummary: ノートに対して AI が生成する要約
FolderNoteRelation: フォルダとノートの関係
Webhook の payload 構造
すべての webhook イベントは、標準の Event Structure 構造に従います。
セキュリティ
Webhook リクエストは、Authorization ヘッダーに設定された secret key で認証されます。
Authorization: Bearer {secret_key}
secret key は webhook の endpoint を設定する際に発行され、受信するリクエストの真正性を検証するために使用します。設定済みの secret と受信した secret を比較するだけで、真正性を確認できます。
検証の例
function verifyWebhookAuth(authHeader, expectedSecret) {
const token = authHeader.replace('Bearer ', '');
return token === expectedSecret;
}
// Usage in your webhook endpoint
app.post('/ja/developers/webhooks/tiro', (req, res) => {
const authHeader = req.headers.authorization;
if (!verifyWebhookAuth(authHeader, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Unauthorized');
}
// Process webhook event
const event = req.body;
handleWebhookEvent(event);
res.status(200).send('OK');
});
import os
from flask import Flask, request
def verify_webhook_auth(auth_header, expected_secret):
if not auth_header or not auth_header.startswith('Bearer '):
return False
token = auth_header.replace('Bearer ', '')
return token == expected_secret
# Usage in your webhook endpoint
@app.route('/ja/developers/webhooks/tiro', methods=['POST'])
def handle_webhook():
auth_header = request.headers.get('Authorization')
if not verify_webhook_auth(auth_header, os.getenv('WEBHOOK_SECRET')):
return 'Unauthorized', 401
# Process webhook event
event = request.get_json()
handle_webhook_event(event)
return 'OK', 200
import (
"encoding/json"
"net/http"
"os"
"strings"
)
func verifyWebhookAuth(authHeader, expectedSecret string) bool {
if !strings.HasPrefix(authHeader, "Bearer ") {
return false
}
token := strings.TrimPrefix(authHeader, "Bearer ")
return token == expectedSecret
}
// Usage in your webhook endpoint
func handleWebhook(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if !verifyWebhookAuth(authHeader, os.Getenv("WEBHOOK_SECRET")) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
// Process webhook event
var event WebhookEvent
json.NewDecoder(r.Body).Decode(&event)
handleWebhookEvent(event)
w.WriteHeader(http.StatusOK)
}
@RestController
class WebhookController {
@Value("\${webhook.secret}")
private lateinit var webhookSecret: String
private fun verifyWebhookAuth(authHeader: String?, expectedSecret: String): Boolean {
if (authHeader?.startsWith("Bearer ") != true) {
return false
}
val token = authHeader.removePrefix("Bearer ")
return token == expectedSecret
}
// Usage in your webhook endpoint
@PostMapping("/ja/developers/webhooks/tiro")
fun handleWebhook(
@RequestHeader("Authorization") authHeader: String?,
@RequestBody event: WebhookEvent
): ResponseEntity<String> {
if (!verifyWebhookAuth(authHeader, webhookSecret)) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized")
}
// Process webhook event
handleWebhookEvent(event)
return ResponseEntity.ok("OK")
}
}
配信とリトライ
- Method: HTTP POST
- Content-Type:
application/json
- Timeout: 60 秒
- Retries: 最大 5 回のリトライ(合計 6 回の試行)。exponential backoff で実施します
- Success: 2xx の HTTP ステータスコードであれば成功とみなします
リトライのスケジュール
- 15 秒後
- 30 秒後
- 5 分後
- 30 分後
- 2 時間後
はじめに
- endpoint を用意する: POST リクエストを受信できる HTTP の endpoint を作成します
- webhook を設定する: Tiro Platform で webhook の endpoint を登録します
- イベントを処理する: アプリケーションで受信した webhook の payload を処理します
webhook の endpoint は Tiro Platform で設定できます。
Webhook の endpoint はワークスペース単位で登録・管理されます。Platform で endpoint を追加すると、現在のワークスペースのイベントがその endpoint に配信されます。複数のワークスペースを運用する場合は、ワークスペースごとに endpoint を登録し、payload 最上位の workspaceGuid でイベントの送信元ワークスペースを判別してください。
endpoint を登録したら、受信する Event Structure を把握しましょう。そのうえで、本番運用を始める前に Best Practices を読み、リトライ・冪等性・署名検証への対応をご確認ください。