> ## Documentation Index
> Fetch the complete documentation index at: https://help.craftstadium.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook とアクセストークンで外部とつなぐ

> 応募・キャンセルを外部のツールに知らせる Webhook と、Claude などから Organize を操作するためのアクセストークンの使い方です。

<Info>
  **この操作をする場所**

  * Webhook の設定：ハッカソンの作成・編集画面の **Step 11**（Pro プラン）
  * Webhook の一覧：左下の **組織設定** → **Webhook** タブ
  * アクセストークン：左下の **組織設定** → **アクセストークン** タブ（発行は組織の管理者のみ）
</Info>

## Webhook：応募・キャンセルを外部に知らせる

Webhook を設定すると、参加者が応募したときやキャンセルしたときに、指定した URL へ参加者の情報を自動で送ります。Google Apps Script（GAS）や Zapier で受け取れば、次のようなことを自動にできます。

* 応募があったら、運営のスプレッドシートに1行足す
* 応募した人に、Discord のロールを付ける
* キャンセルが出たら、運営の Slack に知らせる

Webhook は [Pro プラン](/guides/plans) の機能です。

### 設定する

<Steps>
  <Step title="Step 11 を開く">
    ハッカソンの作成・編集画面で **Step 11** を開き、いちばん下の **Webhook通知設定（任意）** までスクロールします。
  </Step>

  <Step title="Webhook を有効にする">
    **Webhookを有効にする** をオンにします。
  </Step>

  <Step title="URL とシークレットを入れる">
    * **Webhook URL**（必須）：受け取る側の URL です。`http` か `https` で始まる URL を入れます。例：GAS のウェブアプリの URL（`https://script.google.com/macros/s/…/exec`）
    * **署名シークレット（任意）**：入れると、送るデータに署名が付きます。受け取る側で、CraftStadium から届いたものかを確かめられます（[署名を確かめる](#署名を確かめる)）
  </Step>

  <Step title="保存する">
    ハッカソンを保存すると、次の応募から送られます。
  </Step>
</Steps>

**組織設定** → **Webhook** タブでは、公開中のハッカソンごとに Webhook が「設定済み」か「未設定」か、有効か無効かを一覧で確認できます。**編集** / **設定する** を押すと、そのハッカソンの画面に移ります。

<Tip>
  ハッカソンを複製すると、Webhook の設定も引き継がれます。同じ URL に複数のハッカソンの通知が届くときは、受け取る側で `hackathon.numberId` を見て分けてください。
</Tip>

### 送られるタイミング

| イベント名 | 送られるとき |
| - | - |
| `hackathon.registration` | 参加者が応募したとき。キャンセルした人が応募し直したときや、参加者が参加の仕方（チームを作る・マッチング・ソロ）を変えたときにも送られます |
| `hackathon.cancellation` | 参加者が自分でキャンセルしたとき、運営が [運営キャンセル](/guides/applicants) したとき |

当落の確定、チームの編成、成果物の提出では送られません。

### 送られるデータ

JSON で POST します。

```json 応募したとき theme={null}
{
  "event": "hackathon.registration",
  "timestamp": "2026-01-27T10:30:00Z",
  "hackathon": {
    "numberId": 123,
    "displayId": "your-hackathon-id",
    "title": "ハッカソン名"
  },
  "participant": {
    "playerId": "user123",
    "fullName": "山田 太郎",
    "email": "user@example.com",
    "registeredAt": "2026-01-27T10:30:00Z",
    "participationType": "matching",
    "allowMatching": true
  }
}
```

* `participationType`：参加の仕方です。`team_creation`（チームを作る）、`matching`（マッチング）、`solo`（ソロ）のいずれかです。チームの組み方を参加者が選ばないハッカソンでは入りません
* `allowMatching`：マッチングを受け入れるかどうかです。入らないこともあります
* キャンセルのときは `event` が `hackathon.cancellation` になり、`participant` には `registeredAt` などの代わりに `cancelledAt`（キャンセルした日時）が入ります

### 署名を確かめる

署名シークレットを入れると、リクエストのヘッダーに次の値が付きます。

| ヘッダー | 中身 |
| - | - |
| `X-Webhook-Timestamp` | 送った時刻（Unix 時間・秒） |
| `X-Webhook-Signature` | `sha256=` に続けて、署名（16進数） |

署名は、`X-Webhook-Timestamp` の値と `.` と、受け取ったデータ（リクエストの本文そのまま）をつないだ文字列を、署名シークレットを鍵にして HMAC-SHA256 で計算したものです。受け取る側で同じ計算をして、一致するかを確かめてください。

```js Node.js の例 theme={null}
const crypto = require("crypto")

function isValid(rawBody, timestamp, signatureHeader, secret) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex")
  return (
    expected.length === signatureHeader.length &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader))
  )
}
```

<Note>
  GAS のウェブアプリでは、受け取ったリクエストのヘッダーを読めないため、署名は確かめられません。GAS で受ける場合は、URL を運営の中だけで共有してください。
</Note>

### 気をつけること

<Warning>
  * **届かなかった通知は送り直されません。** 受け取る側が5秒以内に応答しなかったり、エラーを返したりすると、その通知はそれきりです。Organize の画面にも失敗は表示されません。漏れがあっては困る集計は、[参加者リストのスプレッドシート連携](/guides/export) を正としてください
  * 受け取る URL には、社内ネットワークの中のアドレスや `localhost` は使えません。インターネットから届く URL にしてください
  * データには参加者の氏名とメールアドレスが入ります。受け取ったデータの置き場所と、見られる人を決めておいてください
</Warning>

### GAS で受け取る例

応募があるたびに、スプレッドシートに1行足す例です。スプレッドシートの **拡張機能** → **Apps Script** に貼り付け、**デプロイ** → **新しいデプロイ** で種類を「ウェブアプリ」、アクセスできるユーザーを「全員」にしてデプロイし、表示された URL を Webhook URL に入れます。

```js Apps Script theme={null}
// 「=」などで始まる値が数式として扱われないようにする
const safe = (v) => (typeof v === "string" && /^[=+\-@]/.test(v) ? "'" + v : v)

function doPost(e) {
  const data = JSON.parse(e.postData.contents)
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("応募") // 先に「応募」シートを作っておく
  sheet.appendRow([
    data.timestamp,
    data.event,
    safe(data.hackathon.title),
    safe(data.participant.fullName),
    safe(data.participant.email),
    data.participant.participationType || "",
  ])
  return ContentService.createTextOutput("ok")
}
```

## アクセストークン：Claude などから Organize を操作する

アクセストークンを発行すると、Claude（Claude Desktop・Claude Code）などのツールから、画面を開かずに Organize を操作できます。今できるのは次の操作です。

* 組織の情報、主催者の一覧、企画の一覧、企画の中のハッカソンの一覧を見る
* 企画を作る
* ハッカソンを下書きで作る（公開の設定や日程は Organize の画面で入れます）

アクセストークンは、料金プランに関係なく使えます。

### 発行する

<Steps>
  <Step title="発行画面を開く">
    **組織設定** → **アクセストークン** タブで、**トークンを発行する** を押します。組織の管理者にだけ表示されます。
  </Step>

  <Step title="名前・有効期限・権限を選ぶ">
    * **トークン名**（必須）：何に使うかがわかる名前。例：「事務局の Claude 用」
    * **有効期限**：90日（最初の選択）、180日、無期限から選びます
    * **権限**：**読み書き可能（発行者と同じ権限）** か **読み取り専用** を選びます。読み取り専用にすると、見るだけで、作成・更新・削除はできません
  </Step>

  <Step title="トークンをコピーする">
    **発行する** を押すと、`cs_pat_` で始まるトークンが表示されます。**この画面を閉じると、二度と表示できません。** コピーして、パスワードと同じように安全な場所に保管してから、**コピーしました。閉じる** を押します。
  </Step>
</Steps>

トークンは、発行した人のアカウントとして動きます。運営の中で共有せず、使う人ごとに発行してください。

### Claude から使う

Claude Desktop の場合は、**設定** → **Developer** → **Edit Config** で開く設定ファイルに、次を足して保存し、Claude Desktop を完全に終了してから起動し直します。`cs_pat_...` は発行したトークンに置き換えます。

```json claude_desktop_config.json theme={null}
{
  "mcpServers": {
    "craft-stadium": {
      "command": "npx",
      "args": ["craft-stadium-mcp"],
      "env": {
        "CRAFTSTADIUM_TOKEN": "cs_pat_..."
      }
    }
  }
}
```

Claude Code の場合は、ターミナルで次を実行します。

```bash theme={null}
claude mcp add craft-stadium -e CRAFTSTADIUM_TOKEN=cs_pat_... -- npx craft-stadium-mcp
```

どちらも、パソコンに Node.js（18 以上）が入っている必要があります。つながると、Claude に「CraftStadium の企画の一覧を見せて」のように頼めるようになります。

<Note>
  発行した画面には CLI（`craft-stadium auth login`）でログインするコマンドも表示されますが、CLI は今のところ一般には配布していません。Claude から使ってください。
</Note>

### 一覧の見方と失効

**アクセストークン** タブには、発行したトークンが並びます。トークンの先頭の数文字、権限、最後に使った日時、有効期限、ステータス（有効 / 期限切れ / 失効済み）が表示されます。

使わなくなったトークンや、漏れたかもしれないトークンは、行の **失効** を押して止めます。止めたトークンを使っているツールは、すぐに使えなくなります。管理者はすべてのトークンを、それ以外のメンバーは自分が発行したトークンだけを失効できます。

<Warning>
  トークンをメールやチャットに貼ったり、Git にコミットしたりしないでください。漏れたかもしれないと思ったら、すぐに失効して、新しく発行し直してください。必要がなければ **読み取り専用** と有効期限付きで発行すると、漏れたときの影響を小さくできます。
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.