「問い合わせ受付」ワークフローで、問い合わせはスプレッドシート「問い合わせ一覧」に残り、#問い合わせ に届くようになりました。ここでは、平日の毎朝9時に「対応状況」が「未対応」の件数をSlackへ送るワークフローを作り、「数える」部分をサブワークフロー(別のワークフローから呼ばれる部品)に切り出します。読み終わると、決まった時刻に確実に動くワークフローと、使い回せる部品の作り方が手に入ります。前提は「n8nの使い方入門:最初のワークフローを作って動かす」の問い合わせ受付が動いていることです。版は2026年10月時点の安定版2.44.7で確かめています。
先に決めること
時刻の基準を日本時間に揃える
定期実行で一番多い失敗は時差です。Schedule Triggerはワークフローのタイムゾーンを使い、無ければn8n全体の設定を使います。セルフホストのn8nは何も設定しないとアメリカ東部時間(America/New_York)で動くので、「毎朝9時」が日本時間の22時(アメリカの冬時間に入ると23時)に届きます。
| 置き場所 | 設定するところ | 効く範囲 |
|---|---|---|
| セルフホストのn8n全体 | 環境変数 GENERIC_TIMEZONE=Asia/Tokyo(コンテナの時刻は TZ) | そのn8nの全ワークフロー |
| n8n Cloud全体 | 管理画面の「Instance settings」→「Runtime」の「Time zone」→「Save and restart」 | そのインスタンスの全ワークフロー |
| ワークフロー1本 | ワークフロー名の右の「…」→「Settings」→「Timezone」 | そのワークフローだけ。全体の設定より優先 |
n8n Cloudの初期値は登録時の地域で決まり、分からなければGMTです。セルフホストで GENERIC_TIMEZONE を task-runners 側にも渡す話は「n8nをセルフホストで導入する:Docker ComposeでVPSに立て、独自ドメインとHTTPSで使う」に書きました。
実際に運用していると、定期実行のワークフローには1本ずつ「Timezone」も Asia/Tokyo にしておくのが安全です。サーバーを移して GENERIC_TIMEZONE を書き忘れても、時刻がずれません。
どの日に動かすか
「毎朝」に土日を含めるのか、祝日はどうするのかを先に決めます。Schedule Triggerは曜日までは指定できますが、日本の祝日は知りません。祝日も止めるなら、応用の「祝日の一覧で止める」を足します。
部品の置き場所を揃える
サブワークフローは、既定では同じプロジェクト(Personalかチームのプロジェクト)のワークフローからしか呼べません。部品と呼ぶ側は同じプロジェクトに置きます。
作るものの一覧
最初は1本で作り、動いたら数える部分を2本目に切り出します。
| ワークフロー | ノード | 役割 |
|---|---|---|
| 毎朝の未対応件数 | Schedule Trigger | 平日9時に動き出す |
| 毎朝の未対応件数 | Execute Sub-workflow | 「問い合わせを数える」を呼び、件数と一覧を受け取る |
| 毎朝の未対応件数 | Slack | #問い合わせ に件数を送る |
| 問い合わせを数える | When Executed by Another Workflow | 呼ばれたら入力(状態・一覧の行数)を受け取る |
| 問い合わせを数える | Google Sheets | 「問い合わせ一覧」から指定の状態の行を読む |
| 問い合わせを数える | Code | 件数と、先頭数件の一覧にまとめて返す |
Schedule Triggerの「Trigger Interval」(動かす間隔の単位)は7種類あります。
| Trigger Interval | 決める項目 | 向く使い方 |
|---|---|---|
| Seconds | Seconds Between Triggers(1〜59) | ほぼ使わない |
| Minutes | Minutes Between Triggers(1〜59) | 新着の見回り(5分おきなど) |
| Hours | Hours Between Triggers、Trigger at Minute | 1時間おきの同期 |
| Days | Days Between Triggers、Trigger at Hour、Trigger at Minute | 土日も含めて毎日 |
| Weeks | Weeks Between Triggers、Trigger on Weekdays、Trigger at Hour、Trigger at Minute | 平日だけ、毎週月曜だけ |
| Months | Months Between Triggers、Trigger at Day of Month、Trigger at Hour、Trigger at Minute | 毎月1日の集計 |
| Custom (Cron) | Expression | 上で書けない組み合わせ |
n8n Cloudでは、Schedule Triggerで動いた回は1回ずつ実行回数に数え、サブワークフローの実行は数えません。数え方は「n8nの料金:Cloudとセルフホストの費用、商用利用の線引き」にあります。
手順
準備
「問い合わせ一覧」の対応状況には「未対応」「対応中」「完了」のどれかが入る前提です。表記がぶれると数え漏れるので、スプレッドシートの「データの入力規則」で3つから選ぶ形にします。
1本で作る: 平日9時に動かす
- 「Overview」で「Create workflow」を押し、名前を「毎朝の未対応件数」にする
- 「Add first step」を押し、「On a schedule」を選ぶ。これが Schedule Trigger
- 「Trigger Interval」を「Weeks」にする
- 「Weeks Between Triggers」は1のまま
- 「Trigger on Weekdays」で Monday・Tuesday・Wednesday・Thursday・Friday を選び、最初から入っている Sunday を外す
- 「Trigger at Hour」を「9am」、「Trigger at Minute」を0にする
- ノード名を「平日9時」に変える
Sunday を外し忘れると日曜にも通知が来ます。土日も含めて毎日なら「Days」で「Trigger at Hour」を「9am」にするだけです。

Cron式で書く場合
同じことはCron式でも書けます。「Trigger Interval」を「Custom (Cron)」にし、「Expression」に次を入れます。
0 9 * * 1-5
左から「分 時 日 月 曜日」で、「月曜〜金曜の9時0分」です。先頭に秒を足した6つの形(0 0 9 * * 1-5)も使えます。曜日は0が日曜です。
| やりたいこと | Expression |
|---|---|
| 平日の9時 | 0 9 * * 1-5 |
| 平日の9時と17時 | 0 9,17 * * 1-5 |
| 毎週月曜の8時30分 | 30 8 * * 1 |
| 毎月1日の9時 | 0 9 1 * * |
「第1月曜」のつもりの 0 9 1-7 * 1 は外れます。Cronは「日」と「曜日」を両方指定すると「どちらかに当てはまる日」に動くので、曜日に関係なく1日〜7日は毎日動き、そのあとも毎週月曜に動きます。2.44.7同梱のCronの部品でも、2026年11月は1日〜7日の毎日と9日(月曜)に動く予定でした。第何曜日は 0 9 1-7 * * にし、後ろで曜日を見て止めます。
Weeksで書けるならWeeksで書きます。画面で読めるからです。
動いた時刻と時差を確かめる
- 「平日9時」を開き、「Execute step」を押す
- OUTPUTに1件出たら、JSONの見え方に切り替える
Schedule Triggerはエディタで実行するとその場で1回動き、出力に Timezone が入ります。Asia/Tokyo (UTC+09:00) なら時差の心配はありません。America/New_York なら先に書いたタイムゾーンを直します。

秒はノードごとに決まった値が自動で入るので、9時0分37秒のように毎回同じ秒数だけ遅れて動きます。故障ではありません。
未対応の行を読む
- 「平日9時」の右の + から「Google Sheets」を選び、「Get row(s) in sheet」を選ぶ
- Credentialは問い合わせ受付で作ったものを選ぶ
- 「Document」と「Sheet」で「問い合わせ一覧」と「シート1」を選ぶ
- 「Filters」で「Column」を「対応状況」、「Value」を「未対応」にする
- 「Options」は空のままにする
- ノードの「Settings」タブで「Always Output Data」をオンにする
- ノード名を「未対応を読む」に変える
6番は0件の日のためです。条件に合う行が無いとGoogle Sheetsノードは何も出さず、後ろが動きません。オンにすると空の item が1件流れるので、次のCodeノードで取り除きます。
件数と一覧にまとめる
- 「未対応を読む」の右に「Code」ノードを足す
- 「Mode」は「Run Once for All Items」のまま、言語は「JavaScript」
- 下のコードを入れ、ノード名を「件数にまとめる」に変える
const rows = $input.all().filter(i => Object.keys(i.json).length > 0);
const lines = rows.slice(0, 5).map(i => `・${i.json['受付日時']} ${i.json['会社名']}(${i.json['種類']})`);
return [{ json: { 件数: rows.length, 一覧: lines.join('\n') } }];
空の item を除き、先頭5件を1行ずつの一覧にし、最後に1件の item にまとめています。だから次のSlackは1通だけ送ります。Codeノードの書き方は「n8nのCodeノード:JavaScriptとPythonで足りないところを書く」で詳しく扱っています。
Slackに送る
- 「件数にまとめる」の右に「Slack」を足し、「Send a message」を選ぶ
- 「Send Message To」は「Channel」、「Channel」は #問い合わせ
- 「Message Text」に下の本文を入れる
- 「Add option」から「Include Link to Workflow」を足してオフにする
おはようございます。未対応の問い合わせは {{ $json['件数'] }} 件です。
{{ $json['一覧'] }}
キーが日本語なので角かっこで書きます。0件の日も「0 件です」と届くようにしてあるのは、来なかった朝にn8nのどこかが止まっていると分かるからです。

試して公開する
- キャンバス下の「Execute workflow」を押し、#問い合わせ に件数が届くのを確かめる
- 右上の「Publish」を押す
- 翌営業日の9時過ぎに、キャンバス上部の「Executions」タブで実行が1件増えているのを確かめる
Schedule TriggerはPublishしないと動きません。エディタで届いたことに安心してPublishを忘れるのが典型です。時刻を変えたときも、Publishし直すまでは前の予定のままです。
サブワークフローに切り出す
「未対応を読む」「件数にまとめる」の2つは、夕方の通知や週報、AIエージェントの道具でも使う処理です。毎回コピーすると、列名を変えたときに全部直すことになるので、部品にします。
部品を作る
- 新しいワークフローを作り、名前を「問い合わせを数える」にする
- 「Add first step」で「When executed by another workflow」を選ぶ
- 「Input data mode」を「Define using fields below」にする
- 「Workflow Input Schema」で「Add field」を押し、「Name」に
status、「Type」に「String」を入れる - もう1つ足し、「Name」に
max_lines、「Type」に「Number」を入れる - 「毎朝の未対応件数」で「未対応を読む」と「件数にまとめる」を選んでコピーし、こちらに貼ってトリガーの後ろにつなぐ
- 「未対応を読む」の「Filters」の「Value」を
{{ $json.status }}に変え、ノード名を「状態で読む」にする - 「件数にまとめる」のコードを下のものに替える
- 右上の「Publish」を押す
const input = $('When Executed by Another Workflow').first().json;
const rows = $input.all().filter(i => Object.keys(i.json).length > 0);
const lines = rows.slice(0, input.max_lines || 5).map(i => `・${i.json['受付日時']} ${i.json['会社名']}(${i.json['種類']})`);
return [{ json: { 状態: input.status, 件数: rows.length, 一覧: lines.join('\n') } }];
1行目でトリガーが受け取った入力を取り出しています。直前のノードはGoogle Sheetsなので、$json ではトリガーの値に届きません。ノード名で指名する書き方は「n8nの式(Expression)とデータの扱い:$json・ノードの参照・日付・JSON」にあります。部品の最後のノードが出したもの、ここではCodeノードの1件が、呼んだ側に返ります。

入力の決め方を選ぶ
「Input data mode」は3つあります。
| Input data mode | 中身 | 向く場面 |
|---|---|---|
| Define using fields below | 名前と型(String・Number・Boolean・Array・Object・Allow Any Type)を1つずつ決める | 部品の大半 |
| Define using JSON example | 例のJSONを貼ると、そこから名前と型を読み取る | 入力が多い、入れ子のデータを受ける |
| Accept all data | 何でも受け取る。入力欄は出ない | itemをまるごと渡す。欠けた値は部品の中で扱う |
迷ったら「Define using fields below」にします。何を渡せばいいかが欄として出るので、半年後に別の人が使っても間違えません。運用しているn8nで「Accept all data」の部品を使っていたとき、呼ぶ側のノードを差し替えて項目名が変わり、部品が「0件」と返し続けたことがありました。エラーにならないので、気づくまで何日もかかりました。
呼ぶ側を作り替える
- 「毎朝の未対応件数」に戻り、「未対応を読む」と「件数にまとめる」を消す
- 「平日9時」の右の + から「Execute Sub-workflow」を選ぶ(ノードパネルで
subと打つと出る) - 「Source」は「Database」、「Workflow」は「From list」で「問い合わせを数える」を選ぶ
- 「Workflow Inputs」に
statusとmax_linesが並ぶので、statusに「未対応」、max_linesに5を入れる - 「Mode」は「Run once with all items」のまま
- 「Options」は足さない(完了を待つ設定のまま)
- ノード名を「未対応を数える」に変え、後ろにSlackをつなぎ直す
- 「Execute workflow」で試し、#問い合わせ に届いたらPublishする
部品が返す項目名を 件数 と 一覧 に揃えたので、Slackの本文は前のままで動きます。

部品の入力を変えたら、呼ぶ側のノードを開き、「Workflow Inputs」の右の「⋮」から「Refresh Input List」を押して入力欄を読み込み直します。型が合わずに止まるときは「Attempt To Convert Types」をオンにすると、文字の「5」を数の5に直して渡します。
「Mode」と「待つ・待たない」
| 設定 | 選べるもの | 動き | 使う場面 |
|---|---|---|---|
| Mode | Run once with all items(既定) | 届いたitemを全部まとめて、部品を1回だけ動かす | 件数の集計 |
| Mode | Run once for each item | itemの数だけ部品を1回ずつ動かす | 1件ずつ顧客管理に登録する |
| Wait For Sub-Workflow Completion | オン(既定) | 部品が終わるのを待ち、最後のノードの結果を受け取る | 結果を次で使うとき |
| Wait For Sub-Workflow Completion | オフ | 部品を走らせてすぐ次へ。受け取ったitemをそのまま流す | 結果が要らない処理 |
待つ設定なら、部品の失敗は呼んだ側の「未対応を数える」ノードの失敗として表に出ます。待たない設定だと呼んだ側は成功で終わるので、部品の「Settings」にも「Error Workflow」を指定します。エラー用ワークフローは「n8nを止めずに運用する:アップデート・バックアップ・エラー通知・脆弱性」で作ります。
2.0からは、部品の中で「Wait」ノード(承認や一定時間を待つノード)が待っても、呼んだ側は最後まで終わった結果を受け取ります。
誰から呼べるかを決める
部品のワークフロー名の右にある「…」→「Settings」の「This workflow can be called by」で、呼べる相手を絞れます。プロジェクトの共有が使えるプランで出る欄で、Community版の画面には出ません。
| 選択肢 | 意味 |
|---|---|
| No other workflows | どこからも呼べない |
| Workflows created by(Personalの持ち主の名前) / Only workflows in(チームのプロジェクト名) | 同じプロジェクトのワークフローだけ。既定 |
| Selected workflows | 「IDs of workflows that can call this one」に書いたIDのワークフローだけ |
| Any workflow | どのワークフローからでも呼べる |
プロジェクトをまたいで呼ぶなら「Selected workflows」にし、呼ぶ側のID(URLの /workflow/ の後ろの文字列)をカンマ区切りで書きます。「Any workflow」は誰のワークフローからでも部品が動かせるので使いません。
部品も公開する
部品は自分では動き出しませんが、公開が要ります。エディタで試すときは部品の下書きが、本番では部品の公開済みの版が動くからです。2.44.7の中身で確かめると、一度も公開していない部品は本番で Workflow is not active and cannot be executed. で止まります。
効いてくるのは逆の場面です。部品を直してエディタで試すと新しい動きになるのに、翌朝の本番は古いままです。部品を直したら部品をPublishし直します。呼ぶ側の公開し直しは要りません。
実行の記録をたどる
呼んだ側の実行で「未対応を数える」ノードを開くと、OUTPUTの「View sub-execution」から部品の実行へ、部品側の「View parent execution」から呼んだ側へ戻れます。部品が何を受け取り何を返したかはここで見ます。

選んだノードをそのまま部品にする
既存のワークフローの一部を部品にするなら「Convert to sub-workflow」が早いです。ノードを選び、キャンバスの何も無いところを右クリックして「Convert 2 nodes to sub-workflow」のような項目を選び、名前を入れて「Confirm」を押します。選んだノードが新しいワークフローに移り、元の場所には Execute Sub-workflow ノードが入ります。トリガーは選べず、範囲の入口と出口は1ノードずつで、Mergeが入口、Ifが出口になる選び方はできません。式で参照していた値は自動で部品の入力になり、型は「何でも受け取る」になるので、変換のあとでトリガーの型を決め直し、一度動かして中身を確かめます。
部品にするかどうかの判断
何でも部品にすると、追いかけるのが大変になります。本番で動かしてきた中では、次の線で分けるとうまく回ります。
| 部品にする | 部品にしない |
|---|---|
| 同じ並びのノードが3本目のワークフローに出てきた | 1本でしか使っていない(2本目までは様子を見る) |
| 列名など、変わったら全部直すことになるものを触る | 1〜2ノードで済む |
| 入力と出力をはっきり言える(状態を渡すと件数が返る) | 呼ぶ側ごとに少しずつ違う処理をさせたい |
| AIエージェントやMCPの道具としても使いたい | 前後のノードの値を細かく参照し合っている |
部品が部品を呼ぶのは2段までにしています。3段になると、失敗したときに実行の記録を3つたどることになり、朝の30分が消えます。名前は「問い合わせを数える」「顧客を探す」のように、何をするかが分かる動詞で付けます。
止まっていた間の回の扱い
2.44.7の既定では、止まっていた間に予定時刻が過ぎた回は捨てられ、次の予定から再開します。Schedule Triggerの「Settings」タブには「If Execution Is Missed」(取り逃した回をどうするか)と「Missed Execution Grace Period (Seconds)」(何秒の遅れまで取り逃しと見なさないか)が出ますが、これは「durable scheduler」(予定をデータベースに置く仕組み)で動かしているときだけ効きます。2.44.7では既定でオフで、環境変数 N8N_SCHEDULER_ENABLED=true でオンにします。2.45.0からは既定でオンです。
| If Execution Is Missed | 動き | 向くもの |
|---|---|---|
| Don’t Run Missed Executions(既定) | 取り逃した回は捨てて、次の予定から | 5分おきの見回り |
| Run the Most Recent Missed Execution | 取り逃した中で一番新しい1回だけ遅れて動かす | 毎朝の件数通知 |
| Run the Most Recent Missed Execution Per Rule | 上と同じことを、Trigger Rulesのルールごとに1回ずつ | 朝と夕方のように複数のルールを持つもの |
毎朝の件数通知は、消えるより遅れて届くほうがましなので「Run the Most Recent Missed Execution」にしています。取り逃した回を1回ずつ全部流す設定はありません。何が抜けたかの調べ方と外からの見張りは「n8nを止めずに運用する:アップデート・バックアップ・エラー通知・脆弱性」にまとめています。

応用
祝日の一覧で止める
- 「問い合わせ一覧」のファイルに「祝日」というシートを作り、A1に「日付」、その下に
2026-11-03の形で祝日と会社の休業日を入れる(表示形式は「書式なしテキスト」) - 「平日9時」の後ろにGoogle Sheetsの「Get row(s) in sheet」を足し、「祝日」シートを「日付」が
{{ $now.toFormat('yyyy-MM-dd') }}の条件で読む - そのノードの「Always Output Data」をオンにする
- 後ろに「If」ノードを足し、
{{ $json['日付'] }}が空のときだけ部品の呼び出しへ進める
祝日の一覧は年末に翌年分を足します。Ifノードの組み方は「n8nの分岐とループ:IF・Switch・Merge・Loop Over Items」で扱っています。
朝と夕方の2回送る
「平日9時」の「Add Rule」でルールを足し、同じWeeksで「Trigger at Hour」を「5pm」にすると、1つのノードで朝と夕方に動きます。夕方は「対応中」を数えるなら、Schedule Triggerを2つに分け、部品を違う status で呼びます。直すのは部品の1か所で済みます。
AIエージェントからも同じ部品を使う
「問い合わせを数える」は、AI Agentの道具「Call n8n Workflow Tool」からもそのまま呼べます。status をAIに決めさせれば「対応中は何件?」にも答えます。組み方は「n8nでAIエージェントを作る:ChatGPT・Claude・Geminiをつなぐ」と「n8nのMCP:ワークフローを外から呼び出す、外のMCPを使う」にあります。
できないことと、その代わり
| できないこと | 代わりの手 |
|---|---|
| 日本の祝日・会社の休業日を自動で避ける | 祝日の一覧をシートに持ち、Ifノードで止める |
| 「第1月曜」「月末の営業日」をCron式1本で書く | Cron式は広めに書き、後ろで日付と曜日を判定して止める |
| 止まっていた間の回を全部あとから流す | 最新の1回だけ自動で流し、残りは手で流す |
| 前の回が終わるまで次の回を待たせる | 間隔を処理時間より十分長くする。「Settings」の「Timeout Workflow」で長引いた回を打ち切る |
| テスト実行で部品の公開済みの版を動かす | 部品を公開してから本番の実行で確かめる |
| 別のn8nにあるワークフローを部品として呼ぶ | 相手側をWebhookで受け、HTTP Requestで呼ぶ(「n8nで外部サービスとつなぐ:Webhook・HTTP Request・API」) |
よく詰まるところ
| 症状 | 原因 | 直し方 |
|---|---|---|
| 時刻になっても動かない | ワークフローをPublishしていない | Publishする |
| 時刻や間隔を変えたのに前の予定のまま動く | 変更をPublishしていない。Cron式の中の変数は公開した時点の値で固まる | Publishし直す。変数を変えたときも公開し直す |
| 毎朝9時のはずが夜22時・23時に届く | タイムゾーンがAmerica/New_York | GENERIC_TIMEZONE(CloudはInstance settings)とワークフローの「Timezone」をAsia/Tokyoにする |
| 日曜にも通知が来る | Weeksの「Trigger on Weekdays」に最初から入っているSundayを外していない | Sundayを外してPublishし直す |
| 第1月曜だけのはずが毎日動く | Cronで日と曜日を両方指定すると「どちらか」で動く | 日だけで書き、曜日は後ろで判定する |
| 同じ通知が2通届く | 複製したワークフローも公開している、バックアップを戻した手元のn8nでも公開されたまま、前の回が終わる前に次の回が始まった | どのワークフロー・どのn8nから来たかを実行一覧で見て片方を止める。重なるなら間隔を延ばす |
| 0件の朝だけSlackが来ない | Google Sheetsが0件で何も出さず、後ろが止まった | 「Always Output Data」をオンにし、空のitemを除いて数える |
本番だけ Workflow is not active and cannot be executed. で止まる | 部品を一度も公開していない | 部品をPublishする |
| 部品を直したのに本番は古い動きのまま | 本番では部品の公開済みの版が動く | 部品をPublishし直す |
The sub-workflow (…) cannot be called by this workflow で止まる | 部品の「This workflow can be called by」で呼ぶ側が許されていない。別のプロジェクトから呼んでいる | 同じプロジェクトに移すか、「Selected workflows」に呼ぶ側のIDを書く |
| 部品の中で値が空のまま、結果が0件になる | 呼ぶ側で入力に値を入れていない(外した入力は null で届く) | 呼ぶ側の「Workflow Inputs」を全部埋める。必須の値は部品の中で空なら止める |
| 部品が失敗したのに誰も気づかない | 待たない設定で、部品にエラー用ワークフローを指定していない | 部品の「Settings」でも「Error Workflow」を指定する |
次にやること
通知が来なかった朝にすぐ気づけるよう、「n8nを止めずに運用する:アップデート・バックアップ・エラー通知・脆弱性」でエラー用ワークフローと外からの見張りを足します。部品の中の式や日付の扱いで迷ったら「n8nの式(Expression)とデータの扱い:$json・ノードの参照・日付・JSON」、祝日で止める条件や1件ずつの繰り返しを組むなら「n8nの分岐とループ:IF・Switch・Merge・Loop Over Items」を読みます。問い合わせ受付そのものの作り方に戻るなら「n8nの使い方入門:最初のワークフローを作って動かす」です。