コンテンツにスキップ

Threads Webhook 通知:キーワードと人気投稿をリアルタイムで受信

Webhook を使えば、API を何度もポーリングする必要はありません。ルールを設定しておくと、条件に合う投稿が Threads に現れたときに、Throk が投稿データを指定の URL へ POST します。よくある使い方は次のとおりです。

  • ブランドや商品が言及され、盛り上がり始めたときに、Slack、LINE、社内システムへ通知する
  • 話題の中で、いいね数、返信数、閲覧数がしきい値を超えた投稿をモニタリングする
  • 今まさにバズっている投稿を、データベースや CRM へ自動で取り込む

Webhook は 2 つの要素で構成されます。

  • エンドポイント(Endpoint):通知を受け取る URL。例:https://example.com/throk-webhook。エンドポイントごとに専用の署名シークレットがあります。
  • ルール(Rule):どの投稿を送信するかを決める条件。各ルールは 1 つのエンドポイントに属し、1 つのエンドポイントに複数のルールを設定できます。

Throk は 3 分ごとにすべてのルールをチェックします。条件に合う投稿は、投稿 1 件につき 1 イベントとしてエンドポイントに送信されます。同じ投稿が同じルールで送信されるのは 1 回だけです。

投稿にキーワードが含まれ、かつ設定したしきい値に達したときに送信します。

  • キーワードは 1 つのルールにつき 1 つです。照合方法はキーワード検索と同じで、中国語は文字単位、英語は単語単位で照合します。
  • チェック対象は、直近 24 時間以内に投稿されたものです。
  • しきい値は少なくとも 1 つ設定してください。最低値は、いいね数 ≥ 10、返信数 ≥ 5、閲覧数 ≥ 20,000 です。

キーワードを設定せず、指定した期間内に投稿され、しきい値に達した投稿を送信します。今まさにバズっているコンテンツを見つけるのに向いています。

  • チェック対象は、過去 1〜72 時間以内に投稿されたものです(lookbackHours で設定)。
  • しきい値は少なくとも 1 つ設定してください。最低値は、いいね数 ≥ 500、返信数 ≥ 100、閲覧数 ≥ 20,000 です。
  • 同じルール内のしきい値は「かつ」の関係です。 例:いいね数 ≥ 100 かつ返信数 ≥ 10。
  • 異なるルールは互いに影響しません。 1 件の投稿が 2 つのルールに合致した場合は、2 つのイベントが送信されます。
  • 地域で絞り込めます。 chinese(中国語圏すべて、デフォルト)、twhkcnjapanesekorean を指定でき、定義は地域と言語と同じです。
  • 返信も対象です。 返信がルールに合致して送信されることもあります。イベントの is_reply フィールドで区別できます。
  • 閲覧数のしきい値は遅れて発火します。 投稿の閲覧数は通常、投稿から数時間後にデータが反映されます。そのため、閲覧数のしきい値を設定したルールは、いいね数や返信数だけを見るルールより送信が遅れます。

開発者プラットフォームで設定する

Section titled “開発者プラットフォームで設定する”
  1. 開発者プラットフォームにログインし、エンドポイントとルールを開きます。
  2. エンドポイントを追加を押し、URL を入力して作成を押します。
  3. エンドポイントの下にある + ルールを追加 を押し、キーワードまたは人気しきい値を選びます。言語としきい値を設定し(人気しきい値の場合は「過去…時間」も設定します)、追加を押します。
  4. エンドポイントのテストを押して、サーバーがイベントを受信できることを確認します。テストイベントではクレジットを消費しません。
  5. エンドポイントを展開すると Signing Secret が表示されます。これを使って署名を検証します。

開発者プラットフォームの Webhooks ページ:エンドポイントにキーワードルールを追加し、言語と、いいね数・返信数・閲覧数のしきい値を設定する

送信したすべてのイベントと、受信側のレスポンスステータスは送信履歴ページで確認できます。失敗したイベントは再送信できます。

エンドポイントとルールは API でも管理できます。どのリクエストにも API キーが必要です。

メソッドとパス 用途
GET /webhook/endpoints エンドポイント、署名シークレット(secret)、ルールの一覧を取得
POST /webhook/endpoints エンドポイントを作成
DELETE /webhook/endpoints/{endpoint_id} エンドポイントを削除(配下のすべてのルールも削除)
POST /webhook/endpoints/{endpoint_id}/rules エンドポイントにルールを作成
DELETE /webhook/rules/{rule_id} ルールを削除
POST /webhook/endpoints/{endpoint_id}/test テストイベントを 1 件送信(無料)

エンドポイントを作成する:

ターミナルウィンドウ
curl -X POST 'https://premium-api.throk.ai/webhook/endpoints' \
-H 'Authorization: Bearer sk-throk-...' \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/throk-webhook"}'

キーワードルールを作成する(いいね数 ≥ 100 の台湾の投稿):

ターミナルウィンドウ
curl -X POST 'https://premium-api.throk.ai/webhook/endpoints/{endpoint_id}/rules' \
-H 'Authorization: Bearer sk-throk-...' \
-H 'Content-Type: application/json' \
-d '{"keyword": "珍珠奶茶", "likeCount": 100, "language": "tw"}'

人気しきい値ルールを作成する(過去 6 時間以内、いいね数 ≥ 1,000 の投稿):

ターミナルウィンドウ
curl -X POST 'https://premium-api.throk.ai/webhook/endpoints/{endpoint_id}/rules' \
-H 'Authorization: Bearer sk-throk-...' \
-H 'Content-Type: application/json' \
-d '{"likeCount": 1000, "lookbackHours": 6}'

ルールのフィールド:

フィールド 説明
keyword キーワード。空欄にすると人気しきい値ルールになります
likeCountreplyCountviewCount いいね数、返信数、閲覧数のしきい値。少なくとも 1 つ指定します
lookbackHours 過去何時間以内に投稿されたものをチェックするか。1〜72。人気しきい値ルールでは必須です
language 地域。デフォルトは chinese

ルールは変更できません。調整したい場合は、削除してから作り直してください(開発者プラットフォームでは直接編集できます)。

各イベントは POST でエンドポイントに送信され、本文は JSON です。

{
"post": {
"url": "https://threads.com/post/DXZoK1VlEvT",
"code": "DXZoK1VlEvT",
"caption": "串文內容……",
"is_reply": false,
"like_count": 1700,
"reply_count": 293,
"repost_count": 40,
"reshare_count": 180,
"impression_count": 254300,
"post_timestamp": 1776760127,
"media_url": ["https://media01.throk.ai/media/..."]
},
"user": {
"username": "throk.ai",
"full_name": "Throk|定義 Threads 數據新標準",
"profile_picture": "https://media01.throk.ai/profile/77928681697.jpg"
}
}
  • 数値は送信時点のスナップショットです。その後投稿の数値が伸びても、更新は送信されません。
  • repost_count にはリポストと引用が含まれます。impression_count は、閲覧数のデータがまだない場合は null になります。
  • イベントにはルールの情報は含まれません。どのルールで送信されたかを区別したい場合は、ルールごとに別のエンドポイントを作成してください。例:URL にパラメータを付けて https://example.com/throk-webhook?rule=bubble-tea とする。

すべてのイベントには署名が付いています。これにより、リクエストが確かに Throk から送られたもので、内容が改ざんされていないことを確認できます。

  • 署名のシークレットは、エンドポイントの Signing Secret です(開発者プラットフォームでエンドポイントを展開すると表示されます。GET /webhook/endpoints のレスポンスの secret フィールドでも確認できます)。
  • 署名はリクエストヘッダー X-Convoy-Signature に含まれ、形式は t=<UNIX タイムスタンプ>,v1=<署名> です。
  • 検証方法:Signing Secret をキーとして <タイムスタンプ>,<生のリクエストボディ> の HMAC-SHA256(16 進数)を計算し、v1 と照合します。あわせて、リプレイ攻撃を防ぐため、タイムスタンプが数分以内であることも確認してください。

Node.js の例:

import crypto from 'node:crypto';
// rawBody: 生のリクエストボディ(文字列)、header: X-Convoy-Signature の値
function verify(rawBody, header, secret) {
const fields = header.split(',').map((p) => p.split('='));
const t = Number(fields.find(([k]) => k === 't')?.[1]);
if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false; // 5 分以内のリクエストのみ受け付ける
const expected = Buffer.from(
crypto.createHmac('sha256', secret).update(`${t},${rawBody}`).digest('hex'),
);
// シークレットの切り替え中は v1 が複数含まれることがあるので、いずれか 1 つと一致すれば OK
return fields
.filter(([k]) => k === 'v1')
.some(([, sig]) => {
const got = Buffer.from(sig);
return got.length === expected.length && crypto.timingSafeEqual(got, expected);
});
}

署名は生のリクエストボディ(raw body)で計算してください。いったん JSON としてパースしてから文字列に戻したものは使わないでください。

  • できるだけ早く HTTP 2xx を返してください。時間のかかる処理はバックグラウンドで実行してください。
  • 失敗したイベントは自動で再試行されます。開発者プラットフォームの送信履歴から手動で再送信することもできます。
  • 再試行で同じイベントを二重に処理しないよう、投稿の code で重複を排除してください。
  • イベントを 1 件送信するごとに 20 クレジットを消費します。クレジットは API の呼び出しと同じアカウントのものを共有します。同じ投稿が同じルールで課金されるのは 1 回だけです。課金はイベントの送信時点で発生し、受信側の応答結果には左右されません。エンドポイントが正常に受信できる状態にしておいてください。
  • エンドポイントとルールの作成・削除、テストイベントではクレジットを消費しません
  • クレジットが不足すると、イベントの送信は一時停止されます。クレジットを補充すると、まだチェック対象期間内にある投稿は次回のチェックで送信されます。
  • Webhook を含まないプランにダウングレードした場合、既存のルールは残りますが、発火しなくなります。
  • Webhook の消費は Credits 使用履歴に表示され、API の種類は webhook です。

Webhook には一時停止のスイッチはありません。送信を止めるには、ルールまたはエンドポイントを削除してください。エンドポイントを削除すると、配下のすべてのルールも削除されます。