2025.05.19

DifyのワークフローをNode Cronで定期実行

Shuji
- Dify
- AI
- Remix
はじめに
Difyは現状ノーコードだけではワークフローのスケジュール実行がないようで、
公式のスケジュール機能の導入法があるものの、やや複雑に感じ、よりシンプルにできないかと思い、node.jsからタスクスケジューラをローカル環境で実行してみました。
本記事の対象としましては、すでにDifyでワークフローを組んでいるがスケジュール実行する方法を検討している方向けです。
Node Cronの導入
node-cron
モジュールは、node.js 用の純粋な JavaScript で書かれたタスクスケジューラです。
このモジュールを使うことで、簡単にnode.js 内で crontab の構文を使ってタスクをスケジュールすることができます。
またnode.js実行環境であれば他でも良いのですが、本記事ではRemixでサーバーアクションを実行しています。
npm i node-cron
インストール後、以下のコードで 30分ごとに処理を実行するジョブを定義しました。
import * as cron from 'node-cron';
let job: cron.ScheduledTask;
export function startCronJob() {
try {
// 30分毎に実行するcron job
job = cron.schedule('*/30 * * * *', () => {
try {
console.log(`[${new Date().toISOString()}] Cron job executed: 30 minute interval`);
} catch (error) {
console.error('Error in cron job execution:', error);
}
}, {
timezone: "Asia/Tokyo"
});
console.log('Cron job started successfully');
} catch (error) {
console.error('Error starting cron job:', error);
}
}
export function stopCronJob() {
try {
if (job) {
job.stop();
console.log('Cron job stopped successfully');
}
} catch (error) {
console.error('Error stopping cron job:', error);
}
}
Cron構文
node-cron
の構文は6フィールド構文(秒付き)をサポートしています。
# ┌────────────── 秒 (0 - 59) (オプショナル)
# │ ┌──────────── 分 (0 - 59)
# │ │ ┌────────── 時 (0 - 23)
# │ │ │ ┌──────── 日 (1 - 31)
# │ │ │ │ ┌────── 月 (1 - 12)
# │ │ │ │ │ ┌──── 曜日 (0 - 7)(日曜 = 0 または 7)
# │ │ │ │ │ │
# * * * * * *
例えば次のような指定ができます。
*/30 * * * *
→ 30分毎に実行(00分, 30分)0 9 * * *
→ 毎日朝9時に実行0 0 12 * * 1
→ 毎日朝9時に実行以下で、サーバー起動時にcron jobを開始すると、ジョブが定期実行されるのが確認できるかと思います。
import { startCronJob } from './utils/cron.server';
startCronJob();
Dify側の設定
今回は、定期実行を主としているので、ワークフローはコード実行するだけの単純な内容にしています。

認証情報の取得
workflow idとAPIキーを取得し、node.jsアプリの方にセットします。workflow idは公開URLではなく、ワークフローアプリのhttps://cloud.dify.ai/app/{workflow_id}/workflow
となるURLから確認できます。
APIキーはバックエンドサービスAPIから作成して取得します。

APIキーを発行後にはワークフローアプリを再度公開しておきます。
ワークフローを実行する処理
DifyのAPIエンドポイントに対して、ワークフローのIDと必要なパラメータを渡してPOSTリクエストを送り、ワークフローを実行します。
const workflowId = "xxx";
if (!workflowId) {
throw new Error('DIFY_WORKFLOW_ID is not set');
}
const response = await fetch(`https://api.dify.ai/v1/workflows/run`, {
method: 'POST',
headers: {
'Authorization': `Bearer app-xxx`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
workflow_id: workflowId,
inputs: {},
response_mode: "blocking",
user: "abc-123"
})
});
if (!response.ok) {
const errorText = await response.text();
console.error(`Dify API request failed: ${response.status} - ${errorText}`);
throw new Error(`Dify API request failed: ${response.statusText}`);
}
const result = await response.json();
console.log('Workflow execution result:', result);
- エンドポイント:
https://api.dify.ai/v1/workflows/run
- Authorizationヘッダ: Difyで発行されたAPIキー(
app-xxx
)を使い、Bearer認証。 - Content-Type: JSON。
- body(リクエストボディ)には以下を含む:
workflow_id
: 実行するワークフローIDinputs
: ワークフローに渡す入力パラメータ(今回は空)response_mode
:"blocking"
(完了まで待機する同期実行)user
: ユーザーID(トラッキング用識別子)
成功すると以下のようなレスポンスボディが返ってきます。
[0] Workflow execution result: {
[0] task_id: 'xxx',
[0] workflow_run_id: 'xxx',
[0] data: {
[0] id: 'xxx',
[0] workflow_id: 'xxx',
[0] status: 'succeeded',
[0] outputs: null,
[0] error: null,
[0] elapsed_time: 0.1323442067950964,
[0] total_tokens: 0,
[0] total_steps: 3,
[0] created_at: 1747629120,
[0] finished_at: 1747629120
[0] }
[0] }
Dify側のログでも成功したことを確認できました。

最後に
今回はDifyのワークフローをnode.jsで定期実行することに焦点を当てて説明しました。Difyはノーコードだけでも様々なタスクを自動化できますが、外部のアプリケーションと連携することでより可能性が広がると感じています!
これからも実際の業務を想定したパターンを試してみたいと思いますので、もし感じたことがありましたらメッセージいただけますと幸いです!
Other Articles
FastAPI × React LeafletでGoogle Earth Engineの衛星データを扱う
Google Earth Engine で衛生データを表示する
Difyの外部ナレッジAPIでNotion APIのデータを取得
Dify × NotionでAIチャットボットを構築する
Gatsby × Tailwindcss × ダークモードでSEO対策
[Gatsby.js] gatsby-plugin-canonical-urlsでcanonicalタグを生成する
[Gatsby.js] gatsby-plugin-robots-txtでrobot.txtを生成する
[Gatsby.js] gatsby-plugin-sitemapでサイトマップを生成する
Difyのワークフローでスクレイピングしたデータを外部アプリへPOST
Difyの外部ナレッジAPIでRAGを拡張する
DifyとRemixの連携によるチャットボット構築
Remix × Vitest で Login API をテストする
GatsbyでGifを動作させる(TypeScript)
RemixでStripeを使った決済機能の導入