uVersion
日本語
ダウンロード →

Wiki

Webhook

リポジトリごとの送信通知(Discord・Slack・Teams・custom)。チェックイン、チェックアウト、アクティビティ要約に対応。作成、メッセージ形式、テンプレート変数、SSRF ガード。

はじめに

Webhook は、リポジトリでイベントが発生するたびに、外部サービス(Discord・Slack・Microsoft Teams、 または任意の URL)へ送信通知を行います。イベントとはチェックイン、チェックアウト、 または定期的なアクティビティ要約です。クライアントを開かずにチームへ状況を伝える最も簡単な方法であり、 誰かが作業を提出すると、あなたのチャンネルにメッセージが届きます。

Webhook はリポジトリごとに、デスクトップクライアントの管理パネルの Webhooks タブで設定します。1 つのリポジトリに複数の Webhook を設定できます(例: チーム全体向けに Discord へ 1 つ、リード向けにプライベートな Slack へ 1 つ)。

アクセスとロール

Webhook の管理はリポジトリ管理者に限定されます: 任意のリポジトリでのスーパー管理者admin ロール)、または自身が管理するリポジトリでの project_admin です。 その他のロールにはこのタブは表示されません。

ワンポイント Webhooks タブはマルチ Webhook 方式(リポジトリごとに複数エントリ)を使います。単一 URL の古い Discord 通知は互換性のためサーバー側にまだ存在しますが、この新しいタブには公開されていません: ここで説明する Webhook を使ってください。

Webhook を作成する

Add Webhook フォーム: Name、URL、Type(discord/slack/teams/custom)、Events チェックボックス、Enabled トグル。
  1. 管理パネルを開き、リポジトリを選択してから Webhooks タブを開きます。
  2. Add Webhook をクリックします。
  3. 各フィールドを入力し、Create を押します。
フィールド
Name後で見分けるためのラベル(例: Discord équipe)。必須。
URL対象サービスが提供する Webhook の URL。必須。拒否される URL についてはセキュリティを参照。
Typediscordslackteams、または custom
Eventscheckincheckoutactivity_summary のうち 1 つ以上。少なくとも 1 つは必須。
Enabled有効化トグル(編集時、および一覧から表示)。

Discord 側で URL を取得するには: チャンネルの設定 → 連携サービス → ウェブフック → 新しいウェブフック → ウェブフック URL をコピー。Slack 側では、Slack アプリの設定で Incoming Webhook を作成します。 Teams 側では、チャンネルで コネクタ → Incoming Webhook

チュートリアル: Discord Webhook

これは最も一般的なケースです。「URL を取得する」部分は Discord 内で一度だけ行います。

Discord 側: URL を取得する

  1. Discord を開いてサーバーに移動します。通知を受け取るテキストチャンネルを選ぶ(または作成する)。例: #uversion
  2. チャンネル名にマウスを合わせ、歯車アイコン(「チャンネルの編集」)をクリックします。
  3. 左側のメニューで 連携サービス タブを開きます。
  4. ウェブフック をクリックし、新しいウェブフック をクリックします。Discord がこのチャンネルに紐づく Webhook を自動で作成します。
  5. 作成された Webhook をクリックして開きます。名前(例: uVersion)を付け、対象のチャンネルが正しいことを確認します。アバター画像は任意です。
  6. ウェブフック URL をコピー をクリックします。URL は次のような形式です: https://discord.com/api/webhooks/123456789/AbCdEf...
この URL は秘密にしてください URL を持つ人は誰でもあなたのチャンネルにメッセージを投稿できます。リポジトリにコミットせず、 公開の場で共有しないでください。漏洩した場合は Discord 側で Webhook を削除し、新しく作り直してください。

uVersion 側: URL を接続する

  1. デスクトップクライアントで管理パネルを開き、リポジトリを選択してから Webhooks タブを開きます。
  2. Add Webhook をクリックします。
  3. Name: 自分用のラベル(例: Discord équipe)。
  4. URL: Discord からコピーした URL を貼り付けます。
  5. Type: discord を選びます(メッセージを Discord の埋め込み形式にするために不可欠)。
  6. Events: 必要なイベントにチェックを入れます。例: checkin
  7. Create をクリックします。
  8. Webhook の行で Send test をクリックします: 数秒以内にテストメッセージが Discord チャンネルに表示されるはずです。

テストが HTTP 401 または 404 で失敗する場合、URL が誤っているか、Discord 側で Webhook が削除されています: URL を再度コピーしてください。テストが緑なのに何も届かない場合は、正しいチャンネルを 見ているか、Discord で Webhook が無効化されていないかを確認してください。

タイプと形式

Type は、uVersion が送信前にメッセージをどう整形するかを決めます。URL が指すサービスに 合ったものを選んでください。そうしないとメッセージが崩れて届く(またはサービス側で拒否される)ことがあります。

Type送信される形式
discordDiscord の埋め込み(タイトル、色、フィールド)。
slackSlack ペイロード(メッセージブロック)。
teamsMicrosoft Teams カード(MessageCard)。
customあなたが完全に定義する JSON ボディ: カスタム Webhook を参照。

イベント

イベント発火する条件…
checkinユーザーがリポジトリにコミットを提出したとき。
checkoutユーザーが 1 つ以上のファイルをロック(チェックアウト)したとき。
activity_summaryサーバーのスケジューラが定期的なアクティビティ要約を生成したとき(日次 / 週次)。

チャンネルに必要なものだけをチェックしてください。大規模スタジオでは checkout は騒がしくなりがちです: 多くのチームは checkinactivity_summary だけを残します。

カスタム Webhook

custom タイプでは、追加で 2 つのフィールドが表示されます: Custom Headers (JSON)Custom Template (JSON)。これにより、JSON の POST を受け付ける任意のサービスと連携できます。

Template

テンプレートは送信される JSON ボディです。uVersion は二重波括弧で囲まれた変数を、イベントの値に置き換えます。 例:

{"text": "{{event_type}} par {{username}} dans {{repository}}"}

利用できる変数:

変数内容
{{event_type}}イベントの種類(checkincheckoutactivity_summary)。
{{repository}}リポジトリ名。
{{username}}イベントを発生させたユーザー。
{{message}}コミットメッセージ(チェックインの場合)。
{{file_count}}対象ファイル数。
{{commit_hash}}コミットハッシュ。
{{timestamp}}イベントのタイムスタンプ。

Headers

リクエストに付与する HTTP ヘッダーの JSON オブジェクトです。例えば認証トークン:

{"Authorization": "Bearer VOTRE_JETON"}

既定は {}(ヘッダーなし)です。トランスポート用に予約されたヘッダー (hostcontent-lengthtransfer-encodingconnection) は自動的に取り除かれ、上書きできません。

有効な JSON が必須 Headers と Template のフィールドは保存時に検証されます。無効な JSON は明示的なメッセージ (「Invalid JSON in headers」/「… template」)とともに保存をブロックします。波括弧と引用符を確認してください。

テスト・有効化・削除

「Send test」ボタンのある Webhook の行と、できれば Discord で受信したテストメッセージ。

一覧の各 Webhook では次の操作ができます:

  • Send test(飛行機アイコン): サービスにテスト通知を送信し、 インラインで結果(緑のチェックまたはバツ)を表示します。頼りにする前に URL とタイプを確認するのに便利です。
  • トグル: Webhook を削除せずに有効 / 無効を切り替えます。
  • Edit: 任意のフィールドを編集します。
  • Delete: 完全に削除します(確認あり)。
テストはレスポンスボディを返しません 失敗時、uVersion はサービスが返した HTTP ステータス(例: 「Webhook returned HTTP 404」)のみを示し、 レスポンスの内容は決して返しません。これは意図的です(セキュリティを参照)。テストが失敗したら、まず URL と タイプを確認し、次にサービス側での Webhook の権限を確認してください。

セキュリティ: SSRF ガード

Webhook は HTTP リクエストをサーバーに発行させます。悪意ある URL が サーバーの内部ネットワークを探る(SSRF 攻撃)ために使われるのを防ぐため、uVersion は作成時、 変更時、およびテスト時に厳格なガードを適用します:

  • スキームは http または https でなければなりません。それ以外のスキームは拒否されます。
  • ホスト名は DNS で解決され、得られたすべての IP アドレスが検査されます。いずれかが 非公開アドレスを指す場合、Webhook は拒否されます: ループバック、プライベートネットワーク(RFC1918)、リンクローカル、 ブロードキャスト、CGNAT 範囲 100.64.0.0/10、クラウドメタデータ 169.254.169.254、 ULA / IPv6 リンクローカル、およびそれらの IPv4-mapped-IPv6 相当。
  • HTTP リダイレクトは追従されません(したがって内部ホストへの 307 でガードを回避できません)。
  • 上流のレスポンスボディはクライアントに一切返されません(SSRF オラクルなし)。

実際には: Webhook の URL は公開サービス(Discord、Slack、Teams、または インターネットから到達可能な自前のエンドポイント)を指す必要があります。localhost、プライベート IP (10.x192.168.x172.16-31.x)、または内部サービスへの URL は 「Webhook URL refused: …」というメッセージで拒否されます。

よくある落とし穴

タイプがサービスと一致しない

Discord 形式を Slack の URL に送る(またはその逆)と、崩れたメッセージになるか、サービス側で拒否されます。 Type フィールドは URL と一致していなければなりません。迷ったら Send test を実行してください。

イベントが 1 つもチェックされていない

イベントのない Webhook は決して発火しません。イベントが 1 つも選択されていない限り、クライアントは保存を ブロックします(「At least one event is required」)。

内部 URL が拒否される

自分のマシンや LAN 上のサービスに対してテストすると、SSRF ガードが拒否します。Webhook の対象として使うには、 そのサービスを公開 URL(またはトンネル)で公開してください。

無効化された Webhook の見落とし

無効化された Webhook は一覧に残りますが、何も送信しません。通知が途絶えた場合は、URL を疑う前に、まず 有効化トグルを確認してください。