はじめに
プロジェクト管理をしていると、「課題が割り当てられたのに気づかなかった」という経験はありませんか?
本記事では、タスク管理ツール「CAT」のAPIとSlackを連携させ、新しい課題が割り当てられた際に自動でSlack通知を送るシステムをn8nで構築する方法を紹介します。プログラミング経験がなくても、画面上でノードを繋ぐだけで実現できます。
こんな課題を抱えていませんか?
プロジェクト管理の現場でよくある悩みを紹介します。
- 気づきの遅れ: 上司から課題が割り当てられても、CATを開かないと気づきません
- リアルタイム性の欠如: メールでは通知が遅く、チャットツールに慣れた人には不便です
- 手動チェックの負担: 定期的にCATを開いて確認するのは非効率です
- 見落としのリスク: 重要な課題を見逃してしまう可能性があります
本記事で実現すること
n8n(ノーコード自動化ツール)を使用して、以下の自動化システムを構築します。
- 自動取得: CAT APIで自分に割り当てられた課題を定期的に取得
- スマートフィルタリング: 新規・差し戻しなど、通知すべき課題だけを抽出
- 即座に通知: Slackに課題の詳細情報を自動送信
- 完全自動化: 5分ごとに自動実行、人手不要
所要時間: 約1時間20分で完成します。
n8nとは
n8nの概要
n8n(エヌエイトエヌ)は、オープンソースのワークフロー自動化ツールです。「Zapier」や「Make(旧Integromat)」のようなツールで、プログラミング不要で様々なサービスやAPIを連携させることができます。画面上でノード(処理の単位)をドラッグ&ドロップで繋げていくだけで、複雑な自動化フローを作成できます。
n8nには3つの提供形態があります。
- クラウド版: n8nが運営するサイトにアクセスして使うタイプ(有料プランあり)
- セルフホスト(ローカル): 自分のパソコンにn8nをインストールして使うタイプ(完全無料)
- セルフホスト(サーバー): サーバーにn8nをインストールして使うタイプ(完全無料)
本記事では、セルフホスト(ローカル)版を使用します。Dockerで簡単に立ち上げられ、完全無料で使えます。
なぜn8nのセルフホスト版を選ぶのか?
他のツールと比較した際のn8nセルフホスト版の優位性:
| 項目 | n8n(セルフホスト) | n8n(クラウド) | Zapier | Make |
|---|---|---|---|---|
| 料金 | 完全無料 | 14日無料体験後、月€20〜 | 無料プランあり(月100タスク) 有料は月$19.99〜 |
無料プランあり(月1000操作) 有料は月$9〜 |
| データ管理 | 自分のPC/サーバー | n8nのクラウド | クラウド | クラウド |
| カスタマイズ性 | 高い(コード埋め込み可) | 高い(コード埋め込み可) | 低い(ノーコードのみ) | 中程度 |
| 実行回数制限 | なし | プランによる(月2500実行〜) | あり(無料は月100タスク) | あり(無料は月1000操作) |
| インストール | 必要 | 不要 | 不要 | 不要 |
特に企業での利用では、データを外部サービスに送らずに自社の環境で管理できる点が大きなメリットです。また、個人利用でも無料で制限なく使える点が魅力です。
n8nの5つの特徴
1. ビジュアルプログラミング
ノード(処理単位)をドラッグ&ドロップで繋げて自動化フローを作成します。プログラミング知識がなくても直感的に操作できます。
2. 豊富な連携先
400以上のサービスと連携できます。
- コミュニケーション: Slack、Microsoft Teams、Discord、LINE
- AI サービス: ChatGPT(OpenAI)、Claude(Anthropic)、Gemini(Google)
- データ管理: Google Sheets、Excel、Googleドライブ、Dropbox
- メール: Gmail、Outlook
- 汎用API: REST API、Webhook(どんなAPIでも連携可能)
3. 自己ホスティング
Dockerで簡単に立ち上げられ、データは自分のサーバーで管理できます。機密情報を扱う場合でも安心です。
4. 柔軟なカスタマイズ性
JavaScriptコードを埋め込んで複雑な処理も実装できます。標準機能で足りない部分は自由に拡張できます。
5. 完全無料
オープンソース(Apache 2.0ライセンス)で、機能制限はありません。商用利用も無料です。
n8nでできること
n8nを使うと、以下のような自動化が実現できます。
API連携
- REST API、Webhook、GraphQLなど様々なAPIと通信できます
- 認証(API Key、OAuth、Basic認証など)にも対応しています
データ加工
- JSONデータの変換、フィルタリング、集計ができます
- 複数データソースの結合・マージも可能です
定期実行
- Cronスケジュールで自動実行できます(例:5分ごと、毎日9時など)
- Webhookでリアルタイム実行もできます
条件分岐
- IF文で処理を分岐できます
- 複数の条件を組み合わせた複雑なロジックも実装できます
エラーハンドリング
- エラー時の自動再試行ができます
- エラー通知(Slack、メールなど)も設定できます
本記事で使うn8nの機能
今回のワークフローでは、以下のノードを使用します。
| ノード | 機能 | 用途 |
|---|---|---|
| HTTP Request | HTTP通信 | CAT APIからデータ取得、Slackへ通知送信 |
| Code | JavaScript実行 | JSONデータの整形・フィルタリング |
| IF | 条件分岐 | データの有無を判定 |
| Schedule Trigger | 定期実行 | 5分ごとに自動実行 |
これらを組み合わせることで、プログラミング不要で自動化システムを構築できます。
1. 環境構築
まずは、n8nをローカル環境で動かすための準備をします。Dockerを使うことで、わずか数分で環境が立ち上がります。
必要な環境
事前に以下がインストールされている必要があります。
- Docker Desktop: 公式サイトからダウンロード
- ターミナル: MacならTerminal、WindowsならPowerShell
1-1. プロジェクトディレクトリ作成
まず、プロジェクト用のディレクトリを作成します。
mkdir ~/n8n-cat-project cd ~/n8n-cat-project
このディレクトリには、以下のファイルが保存されます。
– compose.yaml: n8nの設定ファイル
– n8n_data/: n8nのデータ(ワークフロー、アカウント情報など)
1-2. compose.yaml 作成
n8nの設定ファイルを作成します。以下の内容でファイルを作成してください。
services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
# ========================================
# 基本設定
# ========================================
# タイムゾーン(日本時間に設定)
# デフォルト: America/New_York
- GENERIC_TIMEZONE=Asia/Tokyo
# ========================================
# データベース設定
# ========================================
# SQLiteの読み取り接続プールサイズ
# デフォルト: 0(プーリング無効)
# 0より大きい値でWALモードが有効になり、パフォーマンス向上
- DB_SQLITE_POOL_SIZE=2
# ========================================
# Task Runner(Codeノード実行環境)
# ========================================
# Task Runnerを有効化
# デフォルト: false
# Codeノードのコードを隔離された環境で安全に実行する
- N8N_RUNNERS_ENABLED=true
# ========================================
# セキュリティ設定
# ========================================
# Gitノードでベアリポジトリを無効化
# デフォルト: false
# trueに設定してセキュリティを強化
- N8N_GIT_NODE_DISABLE_BARE_REPOS=true
# 設定ファイルのパーミッションを0600に強制
# デフォルト: false
# trueに設定してセキュリティを強化
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
# ========================================
# プライバシー設定(任意)
# ========================================
# 匿名の利用統計をn8nに送信しない
- N8N_DIAGNOSTICS_ENABLED=false
# 新バージョンの通知を表示しない
- N8N_VERSION_NOTIFICATIONS_ENABLED=false
volumes:
# n8nのデータをローカルに永続化
# ./n8n_data: プロジェクトフォルダ内に保存(見える場所)
# /home/node/.n8n: コンテナ内のn8nデータ保存先
- ./n8n_data:/home/node/.n8n
compose.yaml 設定の解説
各設定項目について詳しく解説します。
基本設定
| 設定 | デフォルト値 | 本記事の設定値 | 説明 |
|---|---|---|---|
GENERIC_TIMEZONE |
America/New_York | Asia/Tokyo | タイムゾーンの設定です。Schedule Triggerの実行時刻やログの時刻表示に影響します。 |
データベース設定
| 設定 | デフォルト値 | 本記事の設定値 | 説明 |
|---|---|---|---|
DB_SQLITE_POOL_SIZE |
0 | 2 | SQLiteの読み取り接続プールサイズです。0より大きい値を設定するとWAL(Write-Ahead Logging)モードが有効になり、読み書きの同時実行性能が向上します。 |
Task Runner設定(重要)
| 設定 | デフォルト値 | 本記事の設定値 | 説明 |
|---|---|---|---|
N8N_RUNNERS_ENABLED |
false | true | Task Runnerの有効/無効を設定します。本記事ではCodeノードを使用するため、必ずtrueに設定してください。 |
Task Runnerとは:Codeノードに記述したJavaScript/Pythonコードを、n8n本体とは隔離された環境で実行する仕組みです。
たとえば、Codeノードに間違えて無限ループを書いてしまった場合を考えます。
| 状況 | 結果 |
|---|---|
| Task Runnerなし | n8n本体がフリーズ → 全ワークフローが止まる → 再起動が必要 |
| Task Runnerあり | 別プロセスがフリーズ → そのCodeノードだけタイムアウト → n8n本体は無事 |
つまり、Task Runnerは「Codeノードのコードを隔離部屋で実行する仕組み」です。間違ったコードを書いても、n8n全体が壊れないように守ってくれます。詳細は「4-4. ノード3: Code(データ整形)」内の補足で解説しています。
セキュリティ設定
| 設定 | デフォルト値 | 本記事の設定値 | 説明 |
|---|---|---|---|
N8N_GIT_NODE_DISABLE_BARE_REPOS |
false | true | Gitノードでベアリポジトリを無効化します。ベアリポジトリはGitフックを悪用される可能性があるため、使用しない場合は無効化することを推奨します。 |
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS |
false | true | 設定ファイルのパーミッションを0600に強制します。SSHの秘密鍵と同様に、設定ファイルを所有者のみが読み書きできるようにすることで、セキュリティを強化します。 |
補足:これらのセキュリティ設定は、本記事のワークフロー(CAT-Slack連携)では直接使用しない機能に対する設定です。ただし、セキュリティのベストプラクティスとして「使用しない機能は制限する」という考え方に基づき、trueに設定しています。
プライバシー設定
| 設定 | デフォルト値 | 本記事の設定値 | 説明 |
|---|---|---|---|
N8N_DIAGNOSTICS_ENABLED |
true | false | 匿名の利用統計をn8nに送信するかどうかを設定します。プライバシーを重視する場合はfalseに設定します。 |
N8N_VERSION_NOTIFICATIONS_ENABLED |
true | false | 新バージョンの通知を表示するかどうかを設定します。通知が不要な場合はfalseに設定します。 |
ボリューム設定(データ永続化)
volumes: - ./n8n_data:/home/node/.n8n
この設定は、n8nのデータをホストマシン(あなたのPC)に保存するためのものです。
| 項目 | 説明 |
|---|---|
./n8n_data |
ホストマシン側のディレクトリ(プロジェクトフォルダ内) |
/home/node/.n8n |
コンテナ内のn8nデータ保存先 |
この設定により、以下のメリットがあります。
- データの永続化:コンテナを削除・再作成しても、ワークフローやアカウント情報が消えません
- バックアップの容易さ:
n8n_dataフォルダをコピーするだけでバックアップできます - データの可視性:Finder/エクスプローラーでデータの存在を確認できます
1-3. n8nの起動
以下のコマンドでn8nを起動します。
# データ保存用ディレクトリを作成 mkdir -p n8n_data # n8nコンテナを起動 docker compose up -d
起動には数秒かかります。以下のメッセージが表示されれば成功です。
✔ Container n8n Started
1-4. n8nにアクセス
ブラウザで http://localhost:5678 にアクセスします。
初回アクセス時は、オーナーアカウント作成画面が表示されます。
- メールアドレス: 任意のメールアドレスを入力(実在しなくてもOK)
- パスワード: 8文字以上のパスワードを設定
- アカウント作成 ボタンをクリック
アカウント作成後、n8nのワークフロー編集画面が表示されます。これで環境構築は完了です!
2. CAT API連携
次に、CAT APIからデータを取得するための準備を行います。API連携では、まず認証情報(APIトークン)を取得し、その後、必要な情報を段階的に取得していきます。
2-1. APIトークンの取得
CATのAPIを使用するには、専用のトークンが必要です。以下の手順で取得してください。
- CATにログイン
- 画面右上のユーザーアイコンをクリック
- アカウント設定 を選択
- APIトークン タブを開く
- 新しいトークンを生成 ボタンをクリック
- 表示されたトークンをコピー(後で使うので保存しておく)
⚠️ 注意: APIトークンは一度しか表示されません。必ずコピーして安全な場所に保存してください。
2-2. 必要な情報を段階的に取得
CAT APIで課題を取得するには、以下の情報が必要です。
- userId: 自分のユーザーID
- projectId: プロジェクトID
- processId: プロセス(工程)ID
これらの情報は、ブラウザのURLからは正確に取得できないため、APIを使って段階的に取得していきます。
Step 1: サービス一覧を取得(userIdとprojectIdを確認)
まず、自分のユーザーIDと、アクセス可能なプロジェクトの一覧を取得します。以下のコマンドを実行してください。your-domain.catcloud.netは自社のCATドメイン、YOUR_API_TOKENは先ほど取得したAPIトークンに置き換えてください。
curl -X GET "https://your-domain.catcloud.net/api/rest/services" \ -H "accept: application/json" \ -H "X-CAT-API-KEY: YOUR_API_TOKEN"
実行すると、以下のようなレスポンスが返ってきます。
{
"userId": 25,
"userName": "山田 太郎",
"email": "yamada@example.com",
"projects": [
{
"projectId": 3,
"projectName": "サンプルプロジェクト"
}
]
}
ここから userId(25)と projectId(3)をメモしておきます。
Step 2: プロジェクト詳細を取得(processIdを確認)
次に、プロジェクト内のプロセス(工程)情報を取得します。projects/3の部分は、Step 1で取得したprojectIdに置き換えてください。
curl -X GET "https://your-domain.catcloud.net/api/rest/projects/3" \ -H "accept: application/json" \ -H "X-CAT-API-KEY: YOUR_API_TOKEN"
実行すると、以下のようなレスポンスが返ってきます。
{
"serviceId": 2,
"projectId": 3,
"projectName": "サンプルプロジェクト",
"currentProcessId": 8,
"processes": [
{
"processId": 8,
"processName": "単体テスト"
}
]
}
ここから processId(8)をメモしておきます。currentProcessIdは現在進行中の工程を示しています。
Step 3: 課題一覧を取得(最終目標)
必要な情報が揃ったので、いよいよ自分に割り当てられた課題を取得します。URLの各パラメータは、Step 1〜2で取得した値に置き換えてください。
curl -X GET "https://your-domain.catcloud.net/api/rest/projects/3/processes/8/issues?assigneeId=25" \ -H "accept: application/json" \ -H "X-CAT-API-KEY: YOUR_API_TOKEN"
URLの構造は以下の通りです。
/api/rest/projects/{projectId}/processes/{processId}/issues?assigneeId={userId}
↓ ↓ ↓
3 8 25
projects/3: Step 1で取得したprojectIdprocesses/8: Step 2で取得したprocessIdassigneeId=25: Step 1で取得したuserId(自分に割り当てられた課題のみ)
成功すると、課題データの一覧が返ってきます。このAPIエンドポイントを、後ほどn8nのワークフローで使用します。
2-3. ブラウザURLとAPIの関係
よくある疑問: 「ブラウザで開いているCATのURLをそのまま使えないの?」
ブラウザで開いているCATのURLは、以下のような形式です。
https://your-domain.catcloud.net/3/8/btsManagement/btsTop/view#list/143
一見、/3/8/の部分がprojectIdとprocessIdに見えますが、APIで必要なIDとは異なる場合があります。ブラウザURLからIDを推測するのではなく、APIを使って正確なIDを取得してください(Step 1〜2)。これにより、確実にデータを取得できます。
3. Slack Webhook設定
課題データを取得できるようになったので、次はSlackへの通知設定を行います。SlackのIncoming Webhookを使うことで、n8nからSlackへメッセージを送信できるようになります。
3-1. Slack App作成
Slackに通知を送るには、専用のアプリを作成する必要があります。以下の手順で作成してください。
- Slack API管理画面にアクセス
- https://api.slack.com/apps にアクセス
- Slackアカウントでログイン
- 新しいアプリを作成
- Create New App ボタンをクリック
- From scratch を選択
- アプリ情報を入力
- App Name: 任意の名前(例: CAT課題通知Bot)
- Pick a workspace: 通知を送りたいワークスペースを選択
- Create App ボタンをクリック
アプリが作成され、設定画面が表示されます。
3-2. Incoming Webhook有効化
作成したアプリにWebhook機能を追加します。以下の手順で設定してください。
- Incoming Webhooks機能を有効化
- 左サイドバーの Incoming Webhooks をクリック
- Activate Incoming Webhooks のトグルをONに切り替え
- Webhookを追加
- 画面下部の Add New Webhook to Workspace ボタンをクリック
- 通知先のチャンネルを選択(例: #general、#dev-notificationsなど)
- 許可する ボタンをクリック
- Webhook URLをコピー
- 画面に表示されたWebhook URLをコピー
- 以下のような形式です。
https://hooks.slack.com/services/T.../B.../...
⚠️ 注意: このURLは秘密情報です。第三者に漏らさないよう、安全に保管してください。
3-3. 通知テスト(任意)
Webhook URLが正しく動作するか、テストしてみましょう。
curl -X POST YOUR_WEBHOOK_URL \
-H "Content-Type: application/json" \
-d '{"text":"テスト通知です"}'
Slackの指定したチャンネルに「テスト通知です」というメッセージが届けば成功です。
4. n8nワークフロー構築
いよいよ、n8nでワークフローを構築します。ノードを1つずつ追加して、CAT APIから課題を取得し、Slackに通知する流れを作っていきます。
4-1. ワークフロー全体像
まず、今回作成するワークフローの全体像を把握しましょう。完成すると以下のようになります。

処理の流れは以下の通りです。
┌──────────────────┐
│ 手動実行トリガー │ ← 最初はテスト用に手動実行
└────────┬─────────┘
↓
┌──────────────────┐
│ CAT課題取得API │ ← HTTP RequestノードでAPIを呼び出し
└────────┬─────────┘
↓
┌──────────────────┐
│ 課題データ整形 │ ← CodeノードでJSONを整形
└────────┬─────────┘
↓
┌──────────────────┐
│ 課題があるか判定 │ ← IFノードで条件分岐
└────┬────┴────┬───┘
│ true │ false
↓ ↓
┌─────────┐ (終了)
│Slack通知│
└─────────┘
各ノードの役割は以下の通りです。
- 手動実行トリガー: ワークフローの実行開始
- CAT課題取得API: HTTP RequestでCAT APIから課題データを取得
- 課題情報の抽出と整形: JavaScriptコードでデータを読みやすく変換
- 課題があるか判定: IFノードで課題の有無をチェック
- Slack通知送信: 課題があればSlackに詳細を送信
それでは、1つずつノードを作成していきましょう。
4-2. ノード1: Manual Trigger(手動実行トリガー)
最初のノードは、ワークフローを実行するトリガーです。まずはテスト用に手動実行できるようにします。
以下の手順でノードを追加してください。
- n8n画面中央の 「+」ボタン をクリック
- 検索ボックスに「Manual」と入力
- Manual Trigger を選択
- 設定はそのままでOK(デフォルトのまま)
このノードは、画面上の「Test workflow」ボタンをクリックしたときにワークフローを実行する役割を持ちます。開発・テスト段階で便利です(後で定期実行に変更します)。
4-3. ノード2: HTTP Request(CAT API呼び出し)
次に、CAT APIから課題データを取得するノードを作成します。
以下の手順でノードを追加してください。
- Manual Triggerノードの右側の 「+」ボタン をクリック
- 検索ボックスに「HTTP」と入力
- HTTP Request を選択
ノードが追加されたら、以下の内容を設定します。
| 項目 | 値 |
|---|---|
| Method | GET |
| URL | `https://your-domain.catcloud.net/api/rest/projects/3/processes/8/issues?assigneeId=25` |
| Authentication | None |
Authenticationは None を選択します。CAT APIは、Authenticationの設定ではなく、Headersで認証を行うためです(後述)。
次に、Headers(認証情報)を設定します。
画面下部の Add Header をクリックして、以下を追加:
| Name | Value |
|---|---|
X-CAT-API-KEY |
YOUR_API_TOKEN(Step 2-1で取得したトークン) |
URLとヘッダーに含まれる以下のパラメータは、自分の環境に合わせて置き換えてください。
your-domain.catcloud.net: 自社のCATドメインprojects/3: Step 2-2で取得したprojectIdprocesses/8: Step 2-2で取得したprocessIdassigneeId=25: Step 2-2で取得したuserIdYOUR_API_TOKEN: Step 2-1で取得したAPIトークン
設定が完了したら、動作を確認します。
画面上部の 「Test workflow」 ボタンをクリックします。
成功すると、ノードに緑のチェックマークが表示され、課題データが取得されます。データは画面右側のパネルで確認できます。
4-4. ノード3: Code(データ整形)
CAT APIから取得したデータは複雑な構造なので、Slackに送る前に読みやすく整形します。
以下の手順でノードを追加してください。
- HTTP Requestノードの右側の 「+」ボタン をクリック
- 検索ボックスに「Code」と入力
- Code を選択
コードを書く前に、n8n特有の変数について理解しておきましょう。
| 変数 | 説明 | 使用例 |
|---|---|---|
$input |
前のノードから受け取ったデータ全体 | $input.all() で全データ取得 |
$json |
現在処理中のデータ(JSONオブジェクト) | $json.id でidフィールドを参照 |
$item |
現在処理中のアイテム全体 | $item.json でJSONデータにアクセス |
$input はn8nが自動的に提供する組み込みオブジェクトで、前のノード(この場合はHTTP Request)から渡されたデータを保持しています。$input.all() で全データを配列として取得できます。
以下のJavaScriptコードをコピーして、エディタに貼り付けてください。
// ========================================
// APIレスポンスからデータを取得
// ========================================
// $input: n8nの組み込みオブジェクト。前のノードから渡されたデータを保持
// $input.all(): 前のノードの全データを配列で取得
const items = $input.all();
// データが空の場合は空配列を返す(エラー回避)
if (!items || items.length === 0) {
return [];
}
// ========================================
// CAT APIのレスポンスから課題リストを抽出
// ========================================
// items[0].json: 1件目のデータのJSONオブジェクト
// .data: CAT APIの課題リストは通常dataフィールドに格納されている
const issues = items[0].json.data || items[0].json || [];
// 課題が存在しない場合は空配列を返す
if (!Array.isArray(issues) || issues.length === 0) {
return [];
}
// ========================================
// ヘルパー関数: CATのフィールドから値を取得
// ========================================
// CAT APIの課題データは issueFields という配列にフィールド情報が格納されている
// 例: [{ name: 'ID', displayValue: '123' }, { name: 'タイトル', displayValue: 'バグ修正' }]
function getFieldValue(issueFields, fieldName) {
// 指定されたフィールド名で検索
const field = issueFields.find(f => f.name === fieldName);
// 見つかったらdisplayValueを返す、なければnull
return field ? field.displayValue : null;
}
// ========================================
// 各課題を整形して返す
// ========================================
// issues.map(): 配列の各要素を変換
return issues.map(issue => {
return {
json: { // n8nでは必ずjsonフィールドにデータを格納する
id: getFieldValue(issue.issueFields, 'ID') || issue.issueId,
title: getFieldValue(issue.issueFields, 'タイトル') || 'タイトルなし',
type: getFieldValue(issue.issueFields, '種別') || '未設定',
status: getFieldValue(issue.issueFields, 'ステータス') || '未設定',
priority: getFieldValue(issue.issueFields, '優先度') || '未設定',
importance: getFieldValue(issue.issueFields, '重要度') || '未設定',
function: getFieldValue(issue.issueFields, '機能') || '未設定',
updated_at: getFieldValue(issue.issueFields, '更新時間') || ''
}
};
});
このコードは以下の処理を行います。
- データの取り出し:
$input.all()でCAT APIのレスポンスを取得 - 空チェック: データがない場合は空配列を返す(後のIFノードで分岐)
- フィールド変換: CAT独自の形式から、シンプルなJSON形式に変換
- 各フィールドを整形: ID、タイトル、ステータスなどを読みやすい形に
再び 「Test workflow」 をクリックして動作を確認します。
Codeノードの出力を見ると、以下のようなシンプルな形式に整形されているはずです。
{
"id": "143",
"title": "ログイン機能のバグ修正",
"type": "バグ",
"status": "新規",
"priority": "高",
"importance": "高",
"function": "認証",
"updated_at": "2025-11-16 10:30"
}
補足: Codeノードの実行環境(Task Runner)
n8nでは、Codeノードに書いたJavaScript/Pythonコードは「Task Runner」という仕組みで実行されます。
Task Runnerとは?
n8nは「オフィス」、Codeノードに書いたコードは「外部から持ち込まれた荷物」だと考えてください。
| 方法 | 説明 |
|---|---|
| Task Runnerなし | 荷物をそのままオフィス内で開ける → 危険物があったらオフィス全体が被害を受ける |
| Task Runnerあり | 荷物を別室(検査室)で開ける → 危険物があっても本体のオフィスは無事 |
具体例
Codeノードにこんなコードを書いてしまったとします。
// 無限ループ(ミス)
while (true) {
console.log("終わらない処理");
}
| 状況 | 結果 |
|---|---|
| Task Runnerなし | n8n本体がフリーズ → 全ワークフローが止まる → 再起動が必要 |
| Task Runnerあり | 別プロセスがフリーズ → そのCodeノードだけタイムアウト → n8n本体は無事 |
つまり、Task Runnerは「Codeノードのコードを隔離部屋で実行する仕組み」です。間違ったコードを書いても、n8n全体が壊れないように守ってくれます。
compose.yamlでN8N_RUNNERS_ENABLED=trueを設定することで、Task Runnerが有効になります。
| 設定 | デフォルト値 | 説明 |
|---|---|---|
N8N_RUNNERS_ENABLED |
false | Task Runnerの有効/無効 |
N8N_RUNNERS_MODE |
internal | 実行モード(internal / external) |
デフォルトはfalse(無効)なので、明示的にtrueを設定する必要があります。本記事ではInternal Mode(同じコンテナ内で別プロセスとして実行)を使用しています。
Task Runnerには以下の2つの動作モードがあります。
| モード | 説明 | 用途 |
|---|---|---|
| Internal Mode | n8nと同じコンテナ内で、別プロセスとして実行 | 個人利用、開発環境(本記事の設定) |
| External Mode | 完全に別のコンテナ(サイドカー)で実行 | 本番環境、高セキュリティが必要な場合 |
4-5. ノード4: IF(条件分岐)
課題が存在する場合のみSlackに通知するため、条件分岐を追加します。
以下の手順でノードを追加してください。
- Codeノードの右側の 「+」ボタン をクリック
- 検索ボックスに「IF」と入力
- IF を選択
ノードが追加されたら、以下の内容を設定します。
| 項目 | 値 |
|---|---|
| Condition Type | Object |
| Condition | is not empty |
| Value | {{ $json }} |
{{ }} はn8nの変数参照記法(テンプレート記法)です。$json は前のノード(Code)から渡された現在のJSONデータを指し、この場合は整形後の課題データ(id, title, statusなど)を参照しています。
このノードでは、Codeノードからデータが渡された場合(課題がある場合)はtrue分岐に進み、データがない場合(課題がない場合)はfalse分岐で何もせず終了します。
「Test workflow」 をクリックして、IFノードが true 分岐になることを確認します。
4-6. ノード5: HTTP Request(Slack通知)
最後に、Slackに通知を送るノードを作成します。
以下の手順でノードを追加してください。
- IFノードの true(緑色) の出力から 「+」ボタン をクリック
- 検索ボックスに「HTTP」と入力
- HTTP Request を選択
ノードが追加されたら、以下の内容を設定します。
| 項目 | 値 |
|---|---|
| Method | POST |
| URL | YOUR_SLACK_WEBHOOK_URL(Step 3-2で取得したURL) |
| Body Content Type | JSON |
次に、画面下部の Body セクションで Specify Body をクリックし、以下のJSONを入力してください。
{
"text": "🆕 新しい課題が割り当てられました\n\n【ID】{{$json.id}}\n【タイトル】{{$json.title}}\n【種別】{{$json.type}}\n【ステータス】{{$json.status}}\n【優先度】{{$json.priority}}\n【機能】{{$json.function}}\n【重要度】{{$json.importance}}\n【更新時間】{{$json.updated_at}}"
}
このJSONの各部分について詳しく説明します。
{
// "text": Slackのメッセージ本文
"text": "🆕 新しい課題が割り当てられました\n\n【ID】{{$json.id}}\n【タイトル】{{$json.title}}\n【種別】{{$json.type}}\n【ステータス】{{$json.status}}\n【優先度】{{$json.priority}}\n【機能】{{$json.function}}\n【重要度】{{$json.importance}}\n【更新時間】{{$json.updated_at}}"
// \n: 改行コード(Slackのメッセージで改行される)
// \n\n: 2つ改行(空行を作る)
// {{$json.id}}: n8nのテンプレート記法
// → 前のノード(Code)から渡されたJSONデータのidフィールドを参照
// → 実行時に実際の値(例: "143")に置き換えられる
// 同様に:
// {{$json.title}} → 課題のタイトル(例: "ログイン機能のバグ修正")
// {{$json.type}} → 課題の種別(例: "バグ")
// {{$json.status}} → ステータス(例: "新規")
// など、全てのフィールドが動的に置き換えられる
}
n8nのテンプレート記法では、{{ }} で囲まれた部分が実行時に実際の値に置き換えられます。
| 記法 | 説明 | 置き換え例 |
|---|---|---|
{{$json.id}} |
前のノードのJSONデータのidフィールド |
143 |
{{$json.title}} |
前のノードのJSONデータのtitleフィールド |
ログイン機能のバグ修正 |
{{$json.status}} |
前のノードのJSONデータのstatusフィールド |
新規 |
実際にSlackに送信されるメッセージは、以下のようになります。
🆕 新しい課題が割り当てられました 【ID】143 【タイトル】ログイン機能のバグ修正 【種別】バグ 【ステータス】新規 【優先度】高 【機能】認証 【重要度】高 【更新時間】2025-11-16 10:30
最後に、全体の動作を確認しましょう。
- 画面上部の 「Test workflow」 をクリック
- 全ノードが緑色のチェックマークになることを確認
- Slackのチャンネルに通知が届くことを確認
通知が届けば、基本的なワークフローは完成です!
5. 本番運用向け拡張
基本的なワークフローができたので、実用的な機能を追加していきます。
5-1. フィルタリング機能追加
全ての課題ではなく、新規・差し戻しの課題だけ、5分以内に更新されたものだけを通知するようにします。
先ほど作成したCodeノードのコードを、以下の内容に置き換えてください。
// APIレスポンスからデータを取得
const items = $input.all();
if (!items || items.length === 0) {
return [];
}
// dataフィールドから課題を取得
const issues = items[0].json.data || items[0].json || [];
if (!Array.isArray(issues) || issues.length === 0) {
return [];
}
// フィールドから値を取得するヘルパー関数
function getFieldValue(issueFields, fieldName) {
const field = issueFields.find(f => f.name === fieldName);
return field ? field.displayValue : null;
}
// ========== ここから追加 ==========
// 5分前のタイムスタンプ
// Date.now(): 現在時刻(ミリ秒)
// 5 * 60 * 1000: 5分をミリ秒に変換
const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
// 通知対象のステータス
// この配列に含まれるステータスの課題のみ通知する
const targetStatuses = ['新規', '差し戻し'];
// フィルタリング
const filteredIssues = issues
.filter(issue => {
// ステータスと更新時間を取得
const status = getFieldValue(issue.issueFields, 'ステータス');
const updatedAtStr = getFieldValue(issue.issueFields, '更新時間');
// 条件1: ステータスが「新規」または「差し戻し」
const isTargetStatus = targetStatuses.includes(status);
// 条件2: 5分以内に更新された
let isRecent = false;
if (updatedAtStr) {
// 日付文字列をDateオブジェクトに変換
const updatedAt = new Date(updatedAtStr.replace(/\//g, '-'));
// 5分前より後に更新されたか判定
isRecent = updatedAt > fiveMinutesAgo;
}
// 両方の条件を満たす場合のみtrue(AND条件)
return isTargetStatus && isRecent;
})
.map(issue => {
return {
json: {
id: getFieldValue(issue.issueFields, 'ID') || issue.issueId,
title: getFieldValue(issue.issueFields, 'タイトル') || 'タイトルなし',
type: getFieldValue(issue.issueFields, '種別') || '未設定',
status: getFieldValue(issue.issueFields, 'ステータス') || '未設定',
priority: getFieldValue(issue.issueFields, '優先度') || '未設定',
importance: getFieldValue(issue.issueFields, '重要度') || '未設定',
function: getFieldValue(issue.issueFields, '機能') || '未設定',
updated_at: getFieldValue(issue.issueFields, '更新時間') || ''
}
};
});
return filteredIssues;
このコードでは以下の2つのフィルタを追加しています。
- ステータスフィルタ: 「新規」「差し戻し」の課題のみ通知
- 時間フィルタ: 5分以内に更新された課題のみ通知
これにより、本当に通知すべき課題だけがSlackに送られるようになります。
フィルタ条件は自由に変更できます。例えば以下のようにカスタマイズ可能です。
// 10分以内に変更する場合 const tenMinutesAgo = new Date(Date.now() - 10 * 60 * 1000); // 通知対象を増やす場合 const targetStatuses = ['新規', '差し戻し', '対応中'];
5-2. 定期実行(自動化)
手動実行から、5分ごとの自動実行に変更します。以下の手順でManual TriggerをSchedule Triggerに変更してください。
- Manual Triggerノードを削除
- Manual Triggerノードをクリック
- キーボードの Delete キーを押す
- Schedule Triggerを追加
- 画面左上の 「+」ボタン をクリック
- 検索ボックスに「Schedule」と入力
- Schedule Trigger を選択
- Schedule Triggerの設定(Trigger Interval: Minutes、Minutes Between Triggers: 5)
-
HTTP Requestノードと接続
- Schedule Triggerノードの右端の点をドラッグ
- HTTP Requestノードの左端の点に接続
- ワークフローをアクティブ化
- 画面右上の トグルスイッチ をONにする
- スイッチが青色になれば、自動実行が開始されます
これで、5分ごとに自動的にCAT APIをチェックし、新しい課題があればSlackに通知されるようになります。
なお、n8nコンテナが起動している間は常に実行され続けます。停止したい場合は、トグルスイッチをOFFにしてください。
6. トラブルシューティング
実際に運用する中で起こりやすい問題と、その解決方法をまとめました。
6-1. APIレスポンスが空・エラーが出る
HTTP Requestノードが赤くなる、エラーメッセージが表示される、データが取得できないといった場合、以下の原因が考えられます。
① IDが間違っている
以下のコマンドで、正しいIDを再取得してください。
# Step 1: userIdとprojectIdを確認 curl -X GET "https://your-domain.catcloud.net/api/rest/services" \ -H "X-CAT-API-KEY: YOUR_API_TOKEN" # Step 2: processIdを確認 curl -X GET "https://your-domain.catcloud.net/api/rest/projects/PROJECT_ID" \ -H "X-CAT-API-KEY: YOUR_API_TOKEN" # Step 3: 正しいIDで課題取得 curl -X GET "https://your-domain.catcloud.net/api/rest/projects/PROJECT_ID/processes/PROCESS_ID/issues?assigneeId=USER_ID" \ -H "X-CAT-API-KEY: YOUR_API_TOKEN"
ターミナルでデータが取得できたら、そのURLをn8nのHTTP RequestノードのURLフィールドにコピーします。
② APIトークンが無効
CATでAPIトークンを再生成し、n8nのHTTP RequestノードのHeadersを更新してください。
③ ドメイン名が間違っている
ブラウザで開いているCATのURLを確認し、`https://your-domain.catcloud.net` の部分を正確にコピーしてください。
6-2. Slack通知が届かない
ワークフローは緑色(成功)になるがSlackに通知が来ない、またはHTTP Request(Slack)ノードがエラーになる場合、以下の原因が考えられます。
① Webhook URLが間違っている
Slack App設定ページを開き、作成したアプリを選択して Incoming Webhooks でURLを再確認してください。n8nのHTTP RequestノードのURLフィールドに正確にコピーします。
② Incoming Webhookが無効になっている
Slack App設定ページで Incoming Webhooks を開き、Activate Incoming Webhooks がONになっているか確認してください。
③ チャンネルの権限不足
Slack App設定ページで、別のチャンネルにWebhookを追加してテストしてください。自分が投稿権限を持っているチャンネルを選びます。
④ JSONの記法が間違っている
以下のシンプルなJSONでテストしてみてください。
{
"text": "テスト通知"
}
これで通知が届けば、JSON記法が間違っていた可能性があります。{{ }} の中身を確認してください。
6-3. フィルタで課題が除外される
APIでは課題が取得できているのにSlackに通知が来ない、またはCodeノードの出力が空配列になる場合、フィルタ条件を満たす課題がない可能性があります。
テスト時はフィルタを外す
Codeノードのフィルタ部分を一時的にコメントアウトして、全課題が通知されるようにします。
// const filteredIssues = issues.filter(issue => { ... });
// return filteredIssues;
// フィルタなしで全課題を返す
return issues.map(issue => { ... });
これで全課題が通知されるようになります。動作確認後、フィルタを元に戻してください。
CATで課題を更新する
フィルタ条件をテストする場合は、以下の手順を試してください。
- CATで課題を新規作成、または既存の課題を「新規」ステータスに変更
- n8nで 「Test workflow」 を実行
- 通知が届くことを確認
6-4. 定期実行が動かない
Schedule Triggerに変更したが自動実行されない場合、以下のポイントを確認してください。
- ワークフローがアクティブか: 画面右上のトグルスイッチが青色(ON)になっているか確認
-
n8nコンテナが起動しているか: 以下のコマンドで確認します。
docker ps | grep n8n
コンテナが表示されない場合は、以下のコマンドで起動してください。
docker compose up -d
- 実行履歴を確認: n8n画面左サイドバーの Executions をクリックし、5分ごとに実行履歴が記録されているか確認してください。
7. プロジェクト構成
完成したプロジェクトの構成を確認しましょう。
ディレクトリ構造
n8n-cat-project/
├── compose.yaml # n8nのDocker設定
├── .gitignore # Git管理除外設定
├── README.md # プロジェクト説明
├── n8n_data/ # n8nのデータ(Git管理外)
│ ├── database.sqlite # ワークフロー、アカウント情報
│ ├── config # n8n設定
│ └── nodes/ # カスタムノード(今回は未使用)
└── workflows/ # ワークフローエクスポート用
└── cat-notification.json
.gitignoreの設定
プロジェクトをGitで管理する場合、以下の内容で.gitignoreファイルを作成します:
# n8n data directory n8n_data/ # Node modules node_modules/ # Environment files .env .env.local # OS files .DS_Store
重要: n8n_data/ はGit管理から除外してください。個人のアカウント情報やワークフローが含まれるため、リポジトリに含めるべきではありません。
ワークフローのエクスポート
ワークフローをチームで共有したい場合は、JSON形式でエクスポートできます。
- n8nのワークフロー画面右上の 「︙」(メニュー) をクリック
- Download を選択
workflows/cat-notification.jsonとして保存
このJSONファイルはGitで管理できます。他のメンバーは、このファイルをn8nにインポートすることで同じワークフローを使用できます。
8. まとめ
お疲れ様でした!これで、CAT課題管理システムとSlackを連携した自動通知システムが完成しました。
実現できたこと
今回構築したシステムで実現できたことを振り返ります。
✅ CAT APIとの連携
- APIトークンを使った安全な認証
- 段階的なID取得(サービス → プロジェクト → 課題)
- 自分に割り当てられた課題だけを取得
✅ Slackへの自動通知
- Incoming Webhookを使った通知送信
- 課題の詳細情報(ID、タイトル、ステータスなど)を整形して表示
- リアルタイムでチャンネルに通知
✅ 条件に応じたフィルタリング
- ステータスでフィルタ(新規、差し戻しのみ)
- 時間でフィルタ(5分以内に更新されたもののみ)
- 通知の過多を防ぐスマートな仕組み
✅ 定期実行による自動化
- 5分ごとに自動チェック
- 人手不要の完全自動化
- n8nが起動している限り、常に監視
参考リンク
さらに学びたい方向けの参考情報です。
- n8n公式ドキュメント: https://docs.n8n.io/
- 基本的な使い方から高度なテクニックまで解説されています
- n8nコミュニティフォーラム: https://community.n8n.io/
- 質問・情報交換ができます
- CAT API リファレンス: https://www.catcloud.net/manual/api/014/index.html
- Slack Incoming Webhooks: https://api.slack.com/messaging/webhooks
- Webhookの詳細仕様が記載されています
所要時間
実際の作業時間の目安です。
| 作業内容 | 所要時間 |
|---|---|
| 環境構築(Docker起動、n8nセットアップ) | 10分 |
| CAT API調査・ID取得 | 20分 |
| Slack Webhook設定 | 10分 |
| n8nワークフロー作成 | 30分 |
| テスト・調整 | 20分 |
| 合計 | 約1時間20分 |
初めての方でも、本記事の手順に従えば2時間以内に完成できるはずです。
最後に
n8nを使った自動化は、今回のCAT-Slack連携だけでなく、様々な業務に応用できます。例えば以下のような活用方法があります。
- フォーム回答の自動通知: Googleフォームで問い合わせがあったら、Slackやメールで自動通知
- 定期レポート送信: 毎週月曜日に、特定のデータをメールで自動送信
- チャットボット連携: Slackのメンションに自動返信したり、簡単な質問に答えるbot作成
- 複数ツールの連携: 例えば「スプレッドシートに行が追加されたら、その内容をSlackに通知し、同時にメール送信」といった複数の処理を一度に実行
今回のCAT-Slack連携と同じように、「あるツールで何かが起きたら(トリガー)→ データを加工して → 別のツールに送る(アクション)」という流れで、多くの作業を自動化できます。
「この作業、毎回手動でやるの面倒だな…」と思ったら、ぜひn8nを試してみてください。
本記事が、皆さんの業務効率化の一助になれば幸いです。