はじめに

プロジェクト管理をしていると、「課題が割り当てられたのに気づかなかった」という経験はありませんか?

本記事では、タスク管理ツール「CAT」のAPIとSlackを連携させ、新しい課題が割り当てられた際に自動でSlack通知を送るシステムをn8nで構築する方法を紹介します。プログラミング経験がなくても、画面上でノードを繋ぐだけで実現できます。

こんな課題を抱えていませんか?

プロジェクト管理の現場でよくある悩みを紹介します。

  • 気づきの遅れ: 上司から課題が割り当てられても、CATを開かないと気づきません
  • リアルタイム性の欠如: メールでは通知が遅く、チャットツールに慣れた人には不便です
  • 手動チェックの負担: 定期的にCATを開いて確認するのは非効率です
  • 見落としのリスク: 重要な課題を見逃してしまう可能性があります

本記事で実現すること

n8n(ノーコード自動化ツール)を使用して、以下の自動化システムを構築します。

  1. 自動取得: CAT APIで自分に割り当てられた課題を定期的に取得
  2. スマートフィルタリング: 新規・差し戻しなど、通知すべき課題だけを抽出
  3. 即座に通知: Slackに課題の詳細情報を自動送信
  4. 完全自動化: 5分ごとに自動実行、人手不要

所要時間: 約1時間20分で完成します。

n8nとは

n8nの概要

n8n(エヌエイトエヌ)は、オープンソースのワークフロー自動化ツールです。「Zapier」や「Make(旧Integromat)」のようなツールで、プログラミング不要で様々なサービスやAPIを連携させることができます。画面上でノード(処理の単位)をドラッグ&ドロップで繋げていくだけで、複雑な自動化フローを作成できます。

n8nには3つの提供形態があります。

  1. クラウド版: n8nが運営するサイトにアクセスして使うタイプ(有料プランあり)
  2. セルフホスト(ローカル): 自分のパソコンにn8nをインストールして使うタイプ(完全無料)
  3. セルフホスト(サーバー): サーバーに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 にアクセスします。

初回アクセス時は、オーナーアカウント作成画面が表示されます。

  1. メールアドレス: 任意のメールアドレスを入力(実在しなくてもOK)
  2. パスワード: 8文字以上のパスワードを設定
  3. アカウント作成 ボタンをクリック

アカウント作成後、n8nのワークフロー編集画面が表示されます。これで環境構築は完了です!

2. CAT API連携

次に、CAT APIからデータを取得するための準備を行います。API連携では、まず認証情報(APIトークン)を取得し、その後、必要な情報を段階的に取得していきます。

2-1. APIトークンの取得

CATのAPIを使用するには、専用のトークンが必要です。以下の手順で取得してください。

  1. CATにログイン
  2. 画面右上のユーザーアイコンをクリック
  3. アカウント設定 を選択
  4. APIトークン タブを開く
  5. 新しいトークンを生成 ボタンをクリック
  6. 表示されたトークンをコピー(後で使うので保存しておく)

⚠️ 注意: 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で取得したprojectId
  • processes/8: Step 2で取得したprocessId
  • assigneeId=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に通知を送るには、専用のアプリを作成する必要があります。以下の手順で作成してください。

  1. Slack API管理画面にアクセス
    • https://api.slack.com/apps にアクセス
    • Slackアカウントでログイン
  2. 新しいアプリを作成
    • Create New App ボタンをクリック
    • From scratch を選択
  3. アプリ情報を入力
    • App Name: 任意の名前(例: CAT課題通知Bot)
    • Pick a workspace: 通知を送りたいワークスペースを選択
    • Create App ボタンをクリック

アプリが作成され、設定画面が表示されます。

3-2. Incoming Webhook有効化

作成したアプリにWebhook機能を追加します。以下の手順で設定してください。

  1. Incoming Webhooks機能を有効化
    • 左サイドバーの Incoming Webhooks をクリック
    • Activate Incoming Webhooks のトグルをONに切り替え
  2. Webhookを追加
    • 画面下部の Add New Webhook to Workspace ボタンをクリック
    • 通知先のチャンネルを選択(例: #general、#dev-notificationsなど)
    • 許可する ボタンをクリック
  3. 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. ワークフロー全体像

まず、今回作成するワークフローの全体像を把握しましょう。完成すると以下のようになります。

n8nワークフローイメージ画像

処理の流れは以下の通りです。

┌──────────────────┐
│ 手動実行トリガー │ ← 最初はテスト用に手動実行
└────────┬─────────┘
         ↓
┌──────────────────┐
│ CAT課題取得API   │ ← HTTP RequestノードでAPIを呼び出し
└────────┬─────────┘
         ↓
┌──────────────────┐
│ 課題データ整形   │ ← CodeノードでJSONを整形
└────────┬─────────┘
         ↓
┌──────────────────┐
│ 課題があるか判定 │ ← IFノードで条件分岐
└────┬────┴────┬───┘
     │ true    │ false
     ↓         ↓
┌─────────┐  (終了)
│Slack通知│
└─────────┘

各ノードの役割は以下の通りです。

  1. 手動実行トリガー: ワークフローの実行開始
  2. CAT課題取得API: HTTP RequestでCAT APIから課題データを取得
  3. 課題情報の抽出と整形: JavaScriptコードでデータを読みやすく変換
  4. 課題があるか判定: IFノードで課題の有無をチェック
  5. Slack通知送信: 課題があればSlackに詳細を送信

それでは、1つずつノードを作成していきましょう。

4-2. ノード1: Manual Trigger(手動実行トリガー)

最初のノードは、ワークフローを実行するトリガーです。まずはテスト用に手動実行できるようにします。

以下の手順でノードを追加してください。

  1. n8n画面中央の 「+」ボタン をクリック
  2. 検索ボックスに「Manual」と入力
  3. Manual Trigger を選択
  4. 設定はそのままでOK(デフォルトのまま)

このノードは、画面上の「Test workflow」ボタンをクリックしたときにワークフローを実行する役割を持ちます。開発・テスト段階で便利です(後で定期実行に変更します)。

4-3. ノード2: HTTP Request(CAT API呼び出し)

次に、CAT APIから課題データを取得するノードを作成します。

以下の手順でノードを追加してください。

  1. Manual Triggerノードの右側の 「+」ボタン をクリック
  2. 検索ボックスに「HTTP」と入力
  3. 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で取得したprojectId
  • processes/8: Step 2-2で取得したprocessId
  • assigneeId=25: Step 2-2で取得したuserId
  • YOUR_API_TOKEN: Step 2-1で取得したAPIトークン

設定が完了したら、動作を確認します。

画面上部の 「Test workflow」 ボタンをクリックします。

成功すると、ノードに緑のチェックマークが表示され、課題データが取得されます。データは画面右側のパネルで確認できます。

4-4. ノード3: Code(データ整形)

CAT APIから取得したデータは複雑な構造なので、Slackに送る前に読みやすく整形します。

以下の手順でノードを追加してください。

  1. HTTP Requestノードの右側の 「+」ボタン をクリック
  2. 検索ボックスに「Code」と入力
  3. 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, '更新時間') || ''
    }
  };
});

このコードは以下の処理を行います。

  1. データの取り出し: $input.all() でCAT APIのレスポンスを取得
  2. 空チェック: データがない場合は空配列を返す(後のIFノードで分岐)
  3. フィールド変換: CAT独自の形式から、シンプルなJSON形式に変換
  4. 各フィールドを整形: 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 完全に別のコンテナ(サイドカー)で実行 本番環境、高セキュリティが必要な場合

詳細: Task runners | n8n Docs

4-5. ノード4: IF(条件分岐)

課題が存在する場合のみSlackに通知するため、条件分岐を追加します。

以下の手順でノードを追加してください。

  1. Codeノードの右側の 「+」ボタン をクリック
  2. 検索ボックスに「IF」と入力
  3. 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に通知を送るノードを作成します。

以下の手順でノードを追加してください。

  1. IFノードの true(緑色) の出力から 「+」ボタン をクリック
  2. 検索ボックスに「HTTP」と入力
  3. 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

最後に、全体の動作を確認しましょう。

  1. 画面上部の 「Test workflow」 をクリック
  2. 全ノードが緑色のチェックマークになることを確認
  3. 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つのフィルタを追加しています。

  1. ステータスフィルタ: 「新規」「差し戻し」の課題のみ通知
  2. 時間フィルタ: 5分以内に更新された課題のみ通知

これにより、本当に通知すべき課題だけがSlackに送られるようになります。

フィルタ条件は自由に変更できます。例えば以下のようにカスタマイズ可能です。

// 10分以内に変更する場合
const tenMinutesAgo = new Date(Date.now() - 10 * 60 * 1000);

// 通知対象を増やす場合
const targetStatuses = ['新規', '差し戻し', '対応中'];

5-2. 定期実行(自動化)

手動実行から、5分ごとの自動実行に変更します。以下の手順でManual TriggerをSchedule Triggerに変更してください。

  1. Manual Triggerノードを削除
    • Manual Triggerノードをクリック
    • キーボードの Delete キーを押す
  2. Schedule Triggerを追加
    • 画面左上の 「+」ボタン をクリック
    • 検索ボックスに「Schedule」と入力
    • Schedule Trigger を選択
  3. Schedule Triggerの設定(Trigger Interval: Minutes、Minutes Between Triggers: 5)
  4. HTTP Requestノードと接続

    • Schedule Triggerノードの右端の点をドラッグ
    • HTTP Requestノードの左端の点に接続
  5. ワークフローをアクティブ化
    • 画面右上の トグルスイッチ を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で課題を更新する

フィルタ条件をテストする場合は、以下の手順を試してください。

  1. CATで課題を新規作成、または既存の課題を「新規」ステータスに変更
  2. n8nで 「Test workflow」 を実行
  3. 通知が届くことを確認

6-4. 定期実行が動かない

Schedule Triggerに変更したが自動実行されない場合、以下のポイントを確認してください。

  1. ワークフローがアクティブか: 画面右上のトグルスイッチが青色(ON)になっているか確認
  2. n8nコンテナが起動しているか: 以下のコマンドで確認します。

    docker ps | grep n8n
    

    コンテナが表示されない場合は、以下のコマンドで起動してください。

    docker compose up -d
    
  3. 実行履歴を確認: 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形式でエクスポートできます。

  1. n8nのワークフロー画面右上の 「︙」(メニュー) をクリック
  2. Download を選択
  3. workflows/cat-notification.json として保存

このJSONファイルはGitで管理できます。他のメンバーは、このファイルをn8nにインポートすることで同じワークフローを使用できます。

8. まとめ

お疲れ様でした!これで、CAT課題管理システムとSlackを連携した自動通知システムが完成しました。

実現できたこと

今回構築したシステムで実現できたことを振り返ります。

CAT APIとの連携

  • APIトークンを使った安全な認証
  • 段階的なID取得(サービス → プロジェクト → 課題)
  • 自分に割り当てられた課題だけを取得

Slackへの自動通知

  • Incoming Webhookを使った通知送信
  • 課題の詳細情報(ID、タイトル、ステータスなど)を整形して表示
  • リアルタイムでチャンネルに通知

条件に応じたフィルタリング

  • ステータスでフィルタ(新規、差し戻しのみ)
  • 時間でフィルタ(5分以内に更新されたもののみ)
  • 通知の過多を防ぐスマートな仕組み

定期実行による自動化

  • 5分ごとに自動チェック
  • 人手不要の完全自動化
  • n8nが起動している限り、常に監視

参考リンク

さらに学びたい方向けの参考情報です。

所要時間

実際の作業時間の目安です。

作業内容 所要時間
環境構築(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を試してみてください。

本記事が、皆さんの業務効率化の一助になれば幸いです。