コンテンツにスキップ

Webhook(Slack・外部システムへの通知)

課題の追加・更新、コメントの追加、Wiki の作成・更新を、プロジェクトごとに外部へ通知できます。Slack のチャンネルにメッセージとして届けるほか、自前のシステムで JSON を受け取ることもできます。

画面の表記 イベント名 送られるとき
課題の追加 issue.created 課題を追加したとき
課題の更新 issue.updated 課題の項目を変更したとき(何も変えずに保存したときは送りません)
コメントの追加 comment.created 課題にコメントを追加したとき
Wiki の作成・更新 wiki.updated Wiki のページを作成・更新したとき(何も変えずに保存したときは送りません)
テスト送信 ping 「テスト送信」を押したとき
  • 画面からの操作だけでなく、APIキーや AI エージェントから行った操作でも送られます。
  • Backlog からの移行で取り込んだ課題・コメント・Wiki は送られません。

1. Slack で Incoming Webhook の URL を取得する

Section titled “1. Slack で Incoming Webhook の URL を取得する”

Slack 側の操作です(Slack のワークスペースでアプリを追加できる権限が必要です)。

  1. Slack の アプリ管理ページ を開き、通知用のアプリを作成します(既存のアプリでも構いません)。
  2. アプリの設定で「Incoming Webhooks」を ON にします。
  3. 「Add New Webhook to Workspace」を押し、通知先のチャンネルを選んで許可します。
  4. 発行された URL(https://hooks.slack.com/services/…)をコピーします。
  1. 通知したいプロジェクトの「設定」タブを開きます。
  2. 「Webhook」の欄で「Webhook を追加」を押します。
  3. 「名前」を入力します(例: Slack #web-リニューアル)。
  4. 「送信先URL」に、Slack でコピーした URL を貼り付けます。
  5. 「形式」で「Slack」を選びます。
  6. 「通知するイベント」で、通知したいものを選びます(初期状態ではすべて選ばれています)。
  7. 「有効にする」にチェックが入っていることを確認し、「追加」を押します。
  8. 追加された Webhook の「テスト送信」を押し、チャンネルにメッセージが届くことを確認します。

Webhook の追加フォーム(名前・送信先URL・形式・通知するイベント・有効にする)

テスト送信では「KadaiLog からのテスト送信です(プロジェクト名 / プロジェクトキー)」というメッセージが届きます。

課題キー・件名と「開く」リンクに続けて、誰が何をしたかが表示されます。

[WEB-2 お問い合わせフォームで送信エラーが出る] 開く
山田 太郎 さんが ステータス: 未対応 → 処理中 に変更

  • 課題の追加: 「〇〇 さんが課題を追加(ステータス: …・担当: …)」
  • 課題の更新: 変更した項目が1つなら「〇〇 さんが ステータス: 未対応 → 処理中 に変更」、複数なら1項目ずつ箇条書きで表示されます。
  • コメントの追加: 「〇〇 さんがコメント:」に続けて、コメントの先頭200文字ほどを引用で表示します。
  • Wiki の作成・更新: 「[Wiki] ページ名」と「〇〇 さんが Wiki を作成(更新)」を表示します。

Slack のチャンネルに届いた KadaiLog の通知の例(課題の追加・ステータスの変更・コメント)

登録した Webhook には、次の操作ができます。

  • 「テスト送信」: 今の設定で試しに送ります。「有効にする」を OFF にしている Webhook でも送れます。
  • 「編集」: 名前・送信先URL・形式・通知するイベント・有効/無効を変更します。「有効にする」を OFF にしている間は、イベントが起きても送りません。
  • 削除(ゴミ箱のアイコン): Webhook を削除します。通知が止まり、送信履歴も消えます。

各 Webhook の「送信履歴」を開くと、最近の送信結果を確認できます。

列 内容
日時 イベントが起きた日時
イベント 「課題の更新」など
結果 「送信待ち」「再試行待ち」「成功」「失敗」
HTTP 送信先が返した HTTP ステータス
試行 送った回数
詳細 失敗したときの理由(例: HTTP 404、10秒以内に応答がありませんでした)

送信が終わった履歴は、1つの Webhook につき新しいものから20件まで残ります。

Webhook の送信履歴(日時・イベント・結果・HTTP・試行)

  • 送信先が 2xx 以外を返したとき、または10秒以内に応答がなかったときは失敗とみなし、1分後・5分後・30分後に送り直します(最大4回)。4回とも失敗すると、結果が「失敗」になります。
  • リダイレクト(3xx)には従わず、失敗として扱います。
  • 「テスト送信」は送り直しません。
  • 送り直しを待っている間に「有効にする」を OFF にすると、その送信は中止されます。
  • 送信先が応答しない状態が続き、送信待ち・再試行待ちが100件を超えると、それ以降の通知は送らずに「失敗」として記録します。

「形式」で「JSON(汎用)」を選ぶと、イベントの内容を JSON で送ります。登録の手順は Slack と同じです。

  • https:// で始まる URL だけ使えます。
  • ポート番号は指定できません(443番のみ)。
  • IP アドレスでの指定はできません。ホスト名で指定してください。
  • localhost や .local・.internal で終わるホスト名、「.」を含まないホスト名など、社内ネットワーク向けのアドレスは使えません。
  • URL にユーザー名・パスワードは含められません。

KadaiLog は送信先に POST でリクエストを送ります。

ヘッダー 内容
Content-Type application/json
User-Agent KadaiLog-Webhook/1
X-KadaiLog-Event イベント名(issue.updated など)
X-KadaiLog-Delivery 送信ごとの ID。送り直しのときも同じ値なので、重複の判定に使えます
X-KadaiLog-Timestamp 送信した時刻(UNIX 時間・秒)
X-KadaiLog-Signature 署名(sha256= に続く16進数の文字列)。署名を検証するを参照

本文の例(課題の更新):

{
"event": "issue.updated",
"deliveredAt": "2026-10-11T03:00:00.000Z",
"space": { "slug": "demo", "name": "デモ" },
"project": { "key": "DEMO", "name": "デモプロジェクト" },
"actor": { "name": "山田 太郎" },
"issue": {
"key": "DEMO-12",
"title": "ログイン画面の文言修正",
"status": "処理中",
"type": "タスク",
"priority": "medium",
"assignee": "山田 太郎",
"dueDate": "2026-10-31",
"url": "https://app.kadailog.com/demo/issues/DEMO-12"
},
"changes": [{ "field": "ステータス", "from": "未対応", "to": "処理中" }]
}
項目 内容
event イベント名
deliveredAt 送信した日時(ISO 8601 形式・UTC)。送り直したときはその回の日時です
space スペースの URL 名(slug)と名前
project プロジェクトキーとプロジェクト名
actor 操作した人の表示名
issue 課題の内容(課題・コメントのイベントで付きます)。priority は high / medium / low、assignee と dueDate は未設定なら null
changes 変更した項目と変更前後の値(issue.updated で付きます)。課題の変更履歴と同じ内容です。本文の変更は field が 本文 になり、from / to はありません
comment comment.created で付きます。body(コメントの先頭500文字)と url(コメントへの直リンク)
wiki wiki.updated で付きます。title(ページ名)・url・action(作成は created、更新は updated)
  • 担当者・操作した人は表示名で送ります。メールアドレスは含みません。
  • ping(テスト送信)では、event・deliveredAt・space・project・actor だけを送ります。

リクエストが KadaiLog から送られたものかどうかは、X-KadaiLog-Signature ヘッダーで確かめられます。署名は、Webhook ごとの「署名用シークレット」を鍵にして、X-KadaiLog-Timestamp の値・.(ピリオド)・リクエスト本文をつなげた文字列を HMAC-SHA256 で計算したものです。

署名用シークレットは、プロジェクト設定の各 Webhook で確認します。

  1. プロジェクトの「設定」タブを開きます。
  2. 「Webhook」の欄で、対象の Webhook の「署名用シークレット」の「表示」を押します。
  3. 表示された whsec_ で始まる文字列を「コピー」します。

Webhook の「署名用シークレット」の欄(表示・再生成)

Node.js での検証の例:

import crypto from "node:crypto";
// body は受け取った本文そのままの文字列(JSON.parse する前のもの)
function verify(headers, body, secret) {
const timestamp = headers["x-kadailog-timestamp"];
const signature = headers["x-kadailog-signature"] ?? "";
if (!/^\d+$/.test(timestamp ?? "")) return false;
// 5分以上前のものは、再送された古いリクエストとみなして受け付けない
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(`${timestamp}.${body}`).digest("hex");
const a = Buffer.from(signature);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Python での検証の例:

import hashlib
import hmac
import time
# body は受け取った本文そのままのバイト列
def verify(headers, body: bytes, secret: str) -> bool:
timestamp = headers.get("X-KadaiLog-Timestamp", "")
signature = headers.get("X-KadaiLog-Signature", "")
if not (timestamp.isascii() and timestamp.isdigit()) or abs(time.time() - int(timestamp)) > 300:
return False
expected = "sha256=" + hmac.new(
secret.encode(), timestamp.encode() + b"." + body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature.encode(), expected.encode())

受け取る側は、2xx のステータスをすぐに返してください。10秒以内に応答がないと失敗とみなされ、送り直しになります。同じイベントが重複して届いたときは、X-KadaiLog-Delivery の値で見分けられます。

  • 1つのプロジェクトに登録できる Webhook は5件までです。
  • 名前は50文字までです。