<h2 class="wp-block-heading">はじめに</h2>
<p class="wp-block-paragraph">今回は、Discord ボットから送信されたコマンドを n8n のワークフロー経由で Google スプレッドシートに書き出す「コマンド型自動記録システム」について解説します。すべてのコンポーネントは Docker Compose で一元管理されており、要約・サマライズには Ollama を活用しています。</p>
<h2 class="wp-block-heading">システム全体構成</h2>
<p class="wp-block-paragraph">まず全体の流れを把握しましょう。</p>
<pre class="wp-block-code"><code>sequenceDiagram
participant User as ユーザー
participant Bot as Discord Bot
participant n8n as n8n Workflow
participant Sheets as Google Sheets
User->>Bot: /diary or /task or /memo
Bot->>Bot: DISCORD_TOKEN 検証
Bot->>n8n: POST Webhook (JSON)
Note over n8n: body.type で分類<br/>diary/task/memo
alt type == diary
n8n->>Sheets: 「日記」シートに追加
else type == task
n8n->>Sheets: 「タスク」シートに追加
else type == memo
n8n->>Sheets: 「メモ」シートに追加
end</code></pre>
<h2 class="wp-block-heading">Discord ボットの実装</h2>
<p class="wp-block-paragraph">Discord 側は Node.js(<code>discord.js v14</code>)で構築したスラッシュコマンドボットです。</p>
<h3 class="wp-block-heading">Dockerfile</h3>
<p class="wp-block-paragraph">ベースイメージとして <code>node:22-alpine</code> を使用し、開発依存のみを省略して最小限にしています。</p>
<pre class="wp-block-code"><code>FROM node:22-alpine
WORKDIR /app
COPY package.json .
RUN npm install --omit=dev
COPY src/ ./src/
CMD ["node", "src/index.js"]</code></pre>
<h3 class="wp-block-heading">package.json</h3>
<p class="wp-block-paragraph"><code>type: module</code> を設定して ESM モジュールとして動作させています。外部依存は <code>discord.js ^14.16.3</code> のみです。</p>
<pre class="wp-block-code"><code>{
"name": "discord-bot",
"version": "1.0.0",
"type": "module",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js"
},
"dependencies": {
"discord.js": "^14.16.3"
}
}</code></pre>
<h3 class="wp-block-heading">コマンド処理ロジック(<code>src/index.js</code>)</h3>
<p class="wp-block-paragraph">ボットは起動時にグローバルスラッシュコマンド <code>diary</code>、<code>task</code>、<code>memo</code> を登録します。ユーザーがこれらのコマンドを実行すると、それぞれのタイプに合わせて n8n の Webhook に JSON で送信されます。環境変数でトークンとクライアントIDを読み込み検証し、Webhook URL は <code>.env</code> ファイルから供給されます。</p>
<pre class="wp-block-code"><code>flowchart LR
A[ボット起動] --> B[DISCORD_TOKEN 読み込み]
C[DISCORD_CLIENT_ID 読み込み]
D[N8N_WEBHOOK_URL 読み込み]
B --> E[グローバルコマンド登録<br/>/diary /task /memo]
F[ユーザーがスラッシュコマンドを実行] --> G[type 判定]
G --> H[JSON を n8n Webhook に POST]</code></pre>
<h2 class="wp-block-heading">n8n ワークフローの設計</h2>
<p class="wp-block-paragraph">n8n 側は「コマンド型自動記録システム」として、Discord Webhook からの入力を Google スプレッドシートに書き出す役割を担います。</p>
<h3 class="wp-block-heading">入力分類と出力先</h3>
<p class="wp-block-paragraph"><code>body.type</code> フィールドで 3 つのカテゴリに分岐し、それぞれ異なるシートの別タブに対応します。</p>
<p class="wp-block-paragraph">| <code>type</code> | シート名 | 説明 |<br>|——–|———-|——|<br>| diary | 日記 | 日々の記録 |<br>| task | タスク | 作業タスク |<br>| memo | メモ | 自由メモ |</p>
<h3 class="wp-block-heading">IF ノードによる分岐処理</h3>
<p class="wp-block-paragraph">ワークフローの中心には条件分岐(IF ノード)があり、入力された <code>type</code> に応じて 3 つのパイプラインを並行して管理しています。各パイプラインでは日時・投稿者・内容をマッピングし、対応するシートに追加する処理を一貫させています。</p>
<h2 class="wp-block-heading">Docker Compose 構成</h2>
<p class="wp-block-paragraph">すべてのサービスを Docker Compose で一元管理します。</p>
<h3 class="wp-block-heading">サービス連携とネットワーク</h3>
<p class="wp-block-paragraph">3 つのサービスが bridge ネットワーク <code>bot-network</code> を共有しています。Discord ボットは n8n の健康チェックが完了した後に起動される依存関係管理(depends_on)を採用しており、起動順序を保証しています。</p>
<pre class="wp-block-code"><code>flowchart TD
subgraph Docker["Docker Compose 構成"]
direction LR
env[".env ファイル<br/>環境変数供給"]
n8n["n8n サービス<br/>(公式イメージ)"]
bot["Discord Bot<br/>(node:22-alpine)"]
volume["永続化ボリューム<br/>(n8n 用命名ボリューム)"]
end
env --> n8n
n8n --> bot
n8n -.->|健康チェック完了後| bot
n8n ---|"bot-network"| bot</code></pre>
<h3 class="wp-block-heading">タイムゾーン設定</h3>
<p class="wp-block-paragraph">n8n サービスは <code>Asia/Tokyo</code> タイムゾーンで動作するように設定されています。</p>
<h2 class="wp-block-heading">環境変数構成(<code>.env.example</code>)</h2>
<pre class="wp-block-code"><code>DISCORD_TOKEN=your_discord_bot_token_here
DISCORD_CLIENT_ID=your_application_id_here
N8N_WEBHOOK_URL=http://n8n:5678/webhook/discord</code></pre>
<p class="wp-block-paragraph">これらの変数は <code>.env</code> ファイルからサービスに供給され、ボットと n8n が共通して参照します。</p>
<h2 class="wp-block-heading">まとめ</h2>
<p class="wp-block-paragraph">本システムでは、Discord ボットでスラッシュコマンドを受け付け → n8n ワークフローで <code>body.type</code> 別に分類 → Google スプレッドシートへ自動記録するパイプラインを構築しました。Ollama を活用した要約・サマライズ機能も Docker Compose の構成文書に組み込んでおり、全体の運用コストを抑えています。</p>
<pre class="wp-block-code"><code>flowchart LR
subgraph Step1["Step 1: Discord ボット"]
direction TB
A[ユーザーコマンド] --> B[type 判定<br/>diary/task/memo]
B --> C[n8n Webhook に JSON POST]
end
subgraph Step2["Step 2: n8n ワークフロー"]
direction TB
D[IF ノードで type 分岐] --> E{type == diary?}
E -->|はい| F1["「日記」シートに追加<br/>日時・投稿者・内容"]
E -->|いいえ| G{type == task?}
G -->|はい| F2["「タスク」シートに追加"]
G -->|いいえ| F3["「メモ」シートに追加"]
end
subgraph Step3["Step 3: Google Sheets 出力"]
direction TB
F1 --> H[自動記録完了]
F2 --> H
F3 --> H
end
Step1 --> Step2 --> Step3</code></pre>
はじめに
今回は、Discord ボットから送信されたコマンドを n8n のワークフロー経由で Google スプレッドシートに書き出す「コマンド型自動記録システム」について解説します。すべてのコンポーネントは Docker Compose で一元管理されており、要約・サマライズには Ollama を活用しています。
システム全体構成
まず全体の流れを把握しましょう。
sequenceDiagram
participant User as ユーザー
participant Bot as Discord Bot
participant n8n as n8n Workflow
participant Sheets as Google Sheets
User->>Bot: /diary or /task or /memo
Bot->>Bot: DISCORD_TOKEN 検証
Bot->>n8n: POST Webhook (JSON)
Note over n8n: body.type で分類<br/>diary/task/memo
alt type == diary
n8n->>Sheets: 「日記」シートに追加
else type == task
n8n->>Sheets: 「タスク」シートに追加
else type == memo
n8n->>Sheets: 「メモ」シートに追加
end
Discord ボットの実装
Discord 側は Node.js(discord.js v14)で構築したスラッシュコマンドボットです。
Dockerfile
ベースイメージとして node:22-alpine を使用し、開発依存のみを省略して最小限にしています。
FROM node:22-alpine
WORKDIR /app
COPY package.json .
RUN npm install --omit=dev
COPY src/ ./src/
CMD ["node", "src/index.js"]
package.json
type: module を設定して ESM モジュールとして動作させています。外部依存は discord.js ^14.16.3 のみです。
{
"name": "discord-bot",
"version": "1.0.0",
"type": "module",
"main": "src/index.js",
"scripts": {
"start": "node src/index.js"
},
"dependencies": {
"discord.js": "^14.16.3"
}
}
コマンド処理ロジック(src/index.js)
ボットは起動時にグローバルスラッシュコマンド diary、task、memo を登録します。ユーザーがこれらのコマンドを実行すると、それぞれのタイプに合わせて n8n の Webhook に JSON で送信されます。環境変数でトークンとクライアントIDを読み込み検証し、Webhook URL は .env ファイルから供給されます。
flowchart LR
A[ボット起動] --> B[DISCORD_TOKEN 読み込み]
C[DISCORD_CLIENT_ID 読み込み]
D[N8N_WEBHOOK_URL 読み込み]
B --> E[グローバルコマンド登録<br/>/diary /task /memo]
F[ユーザーがスラッシュコマンドを実行] --> G[type 判定]
G --> H[JSON を n8n Webhook に POST]
n8n ワークフローの設計
n8n 側は「コマンド型自動記録システム」として、Discord Webhook からの入力を Google スプレッドシートに書き出す役割を担います。
入力分類と出力先
body.type フィールドで 3 つのカテゴリに分岐し、それぞれ異なるシートの別タブに対応します。
| type | シート名 | 説明 |
|——–|———-|——|
| diary | 日記 | 日々の記録 |
| task | タスク | 作業タスク |
| memo | メモ | 自由メモ |
IF ノードによる分岐処理
ワークフローの中心には条件分岐(IF ノード)があり、入力された type に応じて 3 つのパイプラインを並行して管理しています。各パイプラインでは日時・投稿者・内容をマッピングし、対応するシートに追加する処理を一貫させています。
Docker Compose 構成
すべてのサービスを Docker Compose で一元管理します。
サービス連携とネットワーク
3 つのサービスが bridge ネットワーク bot-network を共有しています。Discord ボットは n8n の健康チェックが完了した後に起動される依存関係管理(depends_on)を採用しており、起動順序を保証しています。
flowchart TD
subgraph Docker["Docker Compose 構成"]
direction LR
env[".env ファイル<br/>環境変数供給"]
n8n["n8n サービス<br/>(公式イメージ)"]
bot["Discord Bot<br/>(node:22-alpine)"]
volume["永続化ボリューム<br/>(n8n 用命名ボリューム)"]
end
env --> n8n
n8n --> bot
n8n -.->|健康チェック完了後| bot
n8n ---|"bot-network"| bot
タイムゾーン設定
n8n サービスは Asia/Tokyo タイムゾーンで動作するように設定されています。
環境変数構成(.env.example)
DISCORD_TOKEN=your_discord_bot_token_here
DISCORD_CLIENT_ID=your_application_id_here
N8N_WEBHOOK_URL=http://n8n:5678/webhook/discord
これらの変数は .env ファイルからサービスに供給され、ボットと n8n が共通して参照します。
まとめ
本システムでは、Discord ボットでスラッシュコマンドを受け付け → n8n ワークフローで body.type 別に分類 → Google スプレッドシートへ自動記録するパイプラインを構築しました。Ollama を活用した要約・サマライズ機能も Docker Compose の構成文書に組み込んでおり、全体の運用コストを抑えています。
flowchart LR
subgraph Step1["Step 1: Discord ボット"]
direction TB
A[ユーザーコマンド] --> B[type 判定<br/>diary/task/memo]
B --> C[n8n Webhook に JSON POST]
end
subgraph Step2["Step 2: n8n ワークフロー"]
direction TB
D[IF ノードで type 分岐] --> E{type == diary?}
E -->|はい| F1["「日記」シートに追加<br/>日時・投稿者・内容"]
E -->|いいえ| G{type == task?}
G -->|はい| F2["「タスク」シートに追加"]
G -->|いいえ| F3["「メモ」シートに追加"]
end
subgraph Step3["Step 3: Google Sheets 出力"]
direction TB
F1 --> H[自動記録完了]
F2 --> H
F3 --> H
end
Step1 --> Step2 --> Step3
コメント