2026年4月10日
技術情報
CronとWebhookで構築する業務フロー自動化|設計指針と5つの実装パターン
業務フロー自動化はスケジュール起動(Cron)とイベント起動(Webhook)の使い分けに集約されます。本稿では両者の特性と実装上の要件を整理し、月次集計から問い合わせ即時対応まで、AI処理を含む現実的な5つの構成パターンを解説します。

概要
業務フロー自動化の核心は、突き詰めれば 「いつ動かすか」と「何をきっかけに動かすか」 の2点に集約されます。前者を担うのがスケジュール起動の Cron、後者を担うのがイベント起動の Webhook です。この2つを適切に使い分け、必要に応じて組み合わせるだけで、月次集計のようなバッチ処理から問い合わせへの即時対応まで、多くの業務フローを見通しよく設計できます。
本稿では、CronとWebhookそれぞれの特性と使い分け、実装上で外せない要件、そして両者を組み合わせた典型的な業務フローを5つのパターンとして整理します。DigitalBaseが社内AI基盤の構築で実際に採用している設計指針をもとに解説します。
CronとWebhookの違い
両者は「処理を起動する」という目的こそ同じですが、起動の契機も実装上の勘所も大きく異なります。まずは特性を整理します。
| 項目 | Cron | Webhook |
|---|---|---|
| 起動タイミング | 時刻ベース | イベントベース |
| 主な用途 | 定期処理、バッチ | リアルタイム反応 |
| 実装の難しさ | 容易(cron式の定義のみ) | やや複雑(HMAC署名・冪等性) |
| 処理が走るタイミング | 予測可能 | 予測不能(バースト注意) |
| 失敗時の扱い | 次回実行で復旧可能 | リトライ・再送の設計が必要 |
要点を一言で表すなら、「決まった時刻に必ず動く」のがCron、「外部から呼び出されたときだけ動く」のがWebhook です。この性質の違いが、後述する実装要件の差につながります。
Cron式の基本
Cronは5つのフィールドで起動タイミングを表現します。
* * * * * │ │ │ │ └─ 曜日 (0-6, 日曜=0) │ │ │ └─── 月 (1-12) │ │ └───── 日 (1-31) │ └─────── 時 (0-23) └───────── 分 (0-59)
業務でよく用いるパターンを以下に示します。
| 用途 | Cron式 |
|---|---|
| 平日朝9時 | 0 9 * * 1-5 |
| 毎月1日0時 | 0 0 1 * * |
| 15分おき | */15 * * * * |
| 営業時間内の毎時0分 | 0 9-18 * * 1-5 |
タイムゾーンは必ず明示します。サーバーのロケール設定に依存させず、スケジューラ側で Asia/Tokyo に固定するのが安全です。タイムゾーンの暗黙の差異は、後述するつまずきポイントの筆頭です。
Webhook受信側の必須要件
Webhookは外部から呼び出される性質上、Cronにはない実装要件を伴います。以下の3点は本番運用において必須と位置づけています。
1. HMAC署名検証
受信エンドポイントは外部に公開されるため、正当な送信元からのリクエストであることを署名で検証します。
import hmac import hashlib def verify_signature(payload: bytes, signature: str, secret: str) -> bool: expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature)
比較には必ず hmac.compare_digest を用い、タイミング攻撃を回避します。
2. 冪等性
同じイベントが2回届いても、副作用が1回で済むように設計します。多くの送信元はリトライを行うため、重複配信は例外ではなく前提です。送信元が付与する event_id をキーに処理済み判定を入れ、二重処理を防ぎます。
3. 即時応答 + 非同期処理
Webhookの送信元の多くは「数秒以内に200を返さないとリトライする」仕様です。受信時点では検証と受付のみを行い、重い処理は非同期に逃がします。
@app.post("/webhook/incoming") async def receive(event: dict, bg: BackgroundTasks): bg.add_task(process_async, event) return {"status": "accepted"} # すぐに応答を返す
この「即時応答・後続非同期」の構成が、リトライ嵐を防ぐうえで最も効果的です。
実装パターン1:月次経理データ集約(Cron主体)
シナリオ:全国8拠点の生産実績Excelを月初に自動集計し、ダッシュボードに反映します。
[ 毎月1日 7:00 (Cron) ] ↓ [ source_file: 各拠点のSharePoint上のExcelを取得 ] ↓ [ transform_llm: フォーマット差異をLLMで吸収 → 統一スキーマへ正規化 ] ↓ [ transform_aggregate: 拠点別・品目別に集計 ] ↓ [ load_sql: 集計テーブルにupsert ] ↓ [ action_webhook: ダッシュボードのキャッシュ無効化 ]
拠点ごとにExcelの様式が異なるケースは製造業の現場で頻出します。この様式差を機械的なパースで吸収しようとすると保守コストが膨らむため、LLMで統一スキーマへ正規化する工程を挟むのが現実的です。定刻に確実に動かす必要があるため、起動はCronが適しています。
実装パターン2:問い合わせ自動分類(Webhook主体)
シナリオ:メール受信を起点に、内容を即座に分類してSlackへ通知します。緊急案件であれば担当者を自動でアサインします。
[ メール受信 (IMAP IDLE → Webhook) ] ↓ [ HMAC検証 + 冪等性チェック ] ↓ [ transform_llm: 件名+本文を urgent/normal/low に分類し、要約を生成 ] ↓ [ flow_if: urgent ? true → action_slack(#urgent), action_webhook(チケット作成) false → action_slack(#inbox) ]
到着時刻が予測できない問い合わせ対応は、イベント起動のWebhookが本領を発揮する領域です。分類と要約をLLMに委ねることで、人手による一次仕分けの負荷を削減できます。
実装パターン3:在庫アラート(Cron + Webhook 連携)
シナリオ:5分おきに在庫を監視し、閾値を割り込んだらWebhookで複数システムへ通知します。
監視自体は定期処理のためCronで回し、閾値割れの検知時にのみWebhookで外部へ通知する構成です。ここでの要点は、同一商品について5分おきに通知が飛び続けるのを防ぐことです。最後の通知時刻を状態として保存し、一定時間内の重複通知を抑制します。状態を持たない監視は、現場で「通知疲れ」を招く典型的な失敗パターンです。
実装パターン4:承認フロー(Webhook + Cron督促)
シナリオ:申請受付 → 承認待ち → 期限超過なら督促 → 期限後はエスカレーション、という多段のフローを構成します。
申請の受付はWebhookで即座に処理しますが、「承認待ち」という状態は時間をまたいで永続化する必要があります。承認待ちの案件をDBに due_at(期限)付きで保持し、Cronで定期的に見回って期限超過を検知する構成が基本です。イベント起動と時刻起動を役割分担させることで、状態をまたぐ業務プロセスを無理なく表現できます。
実装パターン5:日次レポート + リアルタイム反応(ハイブリッド)
シナリオ:通常はCronで日次サマリを送り、重大インシデント発生時にはWebhookで即時通知します。
- 緊急は電話、通常はSlack、サマリはメール、と重要度に応じて通知経路を分ける
- 営業時間内外で通知方法を切り替える
平常運転とイレギュラー対応を同じ通知経路に押し込めると、重要な通知が埋もれます。CronとWebhookを併用しつつ、通知の段階設計を併せて行うことが、実運用での信頼性につながります。
つまずきやすいポイント
設計段階では見落とされがちな、運用で頻出する落とし穴を整理します。
Cron関連
- タイムゾーンずれ:サーバーがUTC、表示がJSTという不一致で、想定と異なる時刻に起動する
- ジョブ重複:前回の実行が長引いたとき、次回の起動と並走して同じデータを二重処理する
- 存在しない日付:
0 0 31 * *のような指定は、31日が存在しない月にスキップされる
Webhook関連
- リトライ嵐:受信側が重く200を返せず、送信元が再送を繰り返してさらに負荷が増す
- 署名漏れ:HMAC検証を入れないと、URLを知る第三者が任意にリクエストを送れてしまう
- 順序保証なし:多くのWebhookは配信順序を保証せず、後発のイベントが先に届くことがある
まとめ
業務フロー自動化の多くは、CronとWebhookの組み合わせで設計できます。本稿で示した設計指針は、次の3点に集約されます。
- 時刻起動はCron、イベント起動はWebhook:両者の役割を混在させない
- Webhookは即時200、処理は非同期:応答時間を最短に保ち、リトライ嵐を防ぐ
- 状態が必要ならDBに永続化:承認待ちや督促回数などの状態はDBに保持し、Cronで見回る
これらの原則を踏まえれば、シンプルな在庫アラートから多段の承認フロー、月次集計まで、複雑な業務プロセスも見通しよく構築できます。
