OSSワークフロー自動化比較:n8n vs Temporal vs Prefect でZapierを脱却する
オープンソースラボ編集部 ・ 2026年6月13日
OSSワークフロー自動化比較:n8n vs Temporal vs Prefect でZapierを脱却する
Zapier(月$19.99〜)・Make(旧Integromat、月$9〜)・Tray.io(月$695〜)に対して、n8n(ノーコード×コード混在の自動化)・Temporal(コード定義の信頼性の高いワークフロー)・Prefect(Pythonデータパイプライン)はワークフロー自動化をセルフホストできます。
OSSワークフロー自動化を選ぶ理由
- コスト: Zapier Business(月$49)→ n8nセルフホストで0円(タスク数無制限)
- コード統合: n8nはGUIにJavaScriptノードを混在させて高度なロジックを実装
- 信頼性: Temporalはワークフローの状態を永続化し、障害後に自動再開
- データパイプライン: PrefectはPythonで書けるため機械学習・データ処理に最適
主要ツールの概要
n8n
2019年公開、TypeScript/Vue製のOSSです。GitHubスター51k+。400+のインテグレーション(Slack・Gmail・Notion・Salesforce・Shopify等)とノードベースUIで、コードを書かずにワークフローを組み立てられます。JavaScriptノードとPythonノードで複雑なロジックも追加できます。
# docker-compose.yml - n8n セルフホスト(本番構成)
version: '3.8'
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
N8N_HOST: n8n.yourcompany.com
N8N_PORT: "5678"
N8N_PROTOCOL: https
N8N_BASIC_AUTH_ACTIVE: "true"
N8N_BASIC_AUTH_USER: admin
N8N_BASIC_AUTH_PASSWORD: ${N8N_PASSWORD}
# データベース(PostgreSQL推奨・本番用)
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${DB_PASSWORD}
# タイムゾーン
GENERIC_TIMEZONE: Asia/Tokyo
# Webhook URL(外部サービスからの着信)
WEBHOOK_URL: https://n8n.yourcompany.com/
# 暗号化(認証情報の暗号化キー)
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
# メール設定
N8N_EMAIL_MODE: smtp
N8N_SMTP_HOST: smtp.sendgrid.net
N8N_SMTP_PORT: "587"
N8N_SMTP_USER: apikey
N8N_SMTP_PASS: ${SENDGRID_KEY}
N8N_SMTP_SENDER: n8n@yourcompany.com
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: n8n
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
n8n_data:
postgres_data:
// n8n ワークフロー例1: GitHub PRを自動でSlackに通知
// (n8n UIでノードをつなぐ操作をJSONで表現)
// ノード構成: GitHub Webhook → Code → Slack
// Codeノード(JavaScript): PRのレビュー担当者を自動アサイン
const pr = $input.first().json;
// ファイル変更からチームを判定
const changedFiles = pr.pull_request.changed_files_count;
const labels = pr.pull_request.labels?.map(l => l.name) || [];
let reviewer = 'frontend-team';
if (labels.includes('backend') || changedFiles > 20) {
reviewer = 'senior-dev-team';
}
return [{
json: {
pr_title: pr.pull_request.title,
pr_url: pr.pull_request.html_url,
author: pr.pull_request.user.login,
reviewer,
slack_channel: `#pr-review-${reviewer}`,
message: `🔔 新しいPRがレビュー待ちです
*${pr.pull_request.title}*
作成者: ${pr.pull_request.user.login}
変更ファイル: ${changedFiles}件
${pr.pull_request.html_url}`,
}
}];
# n8n REST APIでワークフローをプログラムから管理
import requests
import os
N8N_URL = 'https://n8n.yourcompany.com'
N8N_API_KEY = os.environ['N8N_API_KEY']
headers = {
'X-N8N-API-KEY': N8N_API_KEY,
'Content-Type': 'application/json',
}
# ワークフロー一覧を取得
def list_workflows():
resp = requests.get(f'{N8N_URL}/api/v1/workflows', headers=headers)
resp.raise_for_status()
return resp.json()['data']
# ワークフローを有効化/無効化
def toggle_workflow(workflow_id: str, active: bool):
resp = requests.patch(
f'{N8N_URL}/api/v1/workflows/{workflow_id}',
headers=headers,
json={'active': active},
)
resp.raise_for_status()
return resp.json()
# ワークフローを手動トリガー(Webhookノード経由)
def trigger_workflow(webhook_path: str, payload: dict):
resp = requests.post(
f'{N8N_URL}/webhook/{webhook_path}',
json=payload,
)
resp.raise_for_status()
return resp.json()
# 使用例: 毎朝のデータ同期ワークフローをトリガー
result = trigger_workflow(
webhook_path='daily-sync',
payload={
'date': '2026-06-14',
'source': 'automated-script',
'sync_type': 'full',
}
)
print(f'ワークフロートリガー完了: {result}')
Temporal
2019年公開、Go製のOSSです(Uberの社内ツールをOSS化)。GitHubスター13k+。長時間実行・障害耐性の高いワークフローをコード(Python・TypeScript・Go・Java)で定義します。注文処理・決済フロー・メール送信シーケンスなど「途中で失敗しても再開できる」ことが重要なビジネスプロセスに向いています。
# Temporal Python SDK でワークフローを定義
# pip install temporalio
from temporalio import activity, workflow
from temporalio.client import Client
from temporalio.worker import Worker
from datetime import timedelta
# アクティビティ(個々の処理ステップ)
@activity.defn
async def charge_credit_card(amount: float, card_token: str) -> str:
'''クレジットカード決済(失敗時は自動リトライ)'''
# 実際の決済APIを呼び出す
import httpx
resp = await httpx.AsyncClient().post(
'https://api.stripe.com/v1/charges',
data={'amount': int(amount * 100), 'currency': 'jpy', 'source': card_token},
auth=('sk_live_xxxx', ''),
)
if resp.status_code != 200:
raise Exception(f'決済失敗: {resp.text}')
return resp.json()['id']
@activity.defn
async def send_confirmation_email(email: str, order_id: str) -> None:
'''注文確認メール送信'''
import httpx
await httpx.AsyncClient().post(
'https://api.sendgrid.com/v3/mail/send',
headers={'Authorization': 'Bearer SG_xxxx'},
json={
'to': [{'email': email}],
'from': {'email': 'orders@yourcompany.com'},
'subject': f'ご注文確認 #{order_id}',
'content': [{'type': 'text/plain', 'value': f'ご注文 #{order_id} を承りました。'}],
},
)
@activity.defn
async def update_inventory(product_id: str, quantity: int) -> None:
'''在庫を減らす'''
import asyncpg
conn = await asyncpg.connect('postgresql://...')
await conn.execute(
'UPDATE products SET stock = stock - $1 WHERE id = $2',
quantity, product_id
)
# ワークフロー(アクティビティを順番に実行)
@workflow.defn
class OrderWorkflow:
@workflow.run
async def run(self, order: dict) -> str:
# 決済(失敗時は3回リトライ、最大60秒待機)
charge_id = await workflow.execute_activity(
charge_credit_card,
args=[order['amount'], order['card_token']],
start_to_close_timeout=timedelta(seconds=60),
retry_policy=RetryPolicy(maximum_attempts=3),
)
# 在庫更新と確認メールを並列実行
await asyncio.gather(
workflow.execute_activity(
update_inventory,
args=[order['product_id'], order['quantity']],
start_to_close_timeout=timedelta(seconds=30),
),
workflow.execute_activity(
send_confirmation_email,
args=[order['email'], order['order_id']],
start_to_close_timeout=timedelta(seconds=30),
),
)
return charge_id
機能比較表
| 比較項目 | n8n | Temporal | Prefect |
|---|---|---|---|
| ノーコードUI | ✅ | ❌ | ❌ |
| 障害時自動再開 | △ | ✅ | ✅ |
| 長時間ワークフロー | △ | ✅(日〜月単位) | ✅ |
| データパイプライン | △ | △ | ✅ |
| 400+インテグレーション | ✅ | ❌ | △ |
| GitHub Stars | 51k+ | 13k+ | 17k+ |
ワークフロー自動化はLow-Codeカテゴリ/categories/low-codeのNocoDB・Budibaseと連携してフォーム送信→データ保存→通知の全自動フローを構築します。DevOpsカテゴリ/categories/devopsのGitLab CI・GitHub Actionsと組み合わせてデプロイ後のスモークテスト・Slack通知・チケット更新を連動させる統合も一般的です。
FAQ
Q. ZapierからN8Nへの移行で注意することは?
A. 主な注意点: ①Zapierの「Zap」は1:1でN8Nのワークフローに変換できますが、一部のトリガー/アクションはN8Nに対応するノードがない場合があります(その場合はHTTPリクエストノードで直接API呼び出し)②Zapierの「Filters」はN8NのIF/Switchノード、「Formatter」はCodeノード(JavaScript)で代替③Webhookトリガー: ZapierのWebhookトリガーURLをN8Nに切り替えるだけ(URL形式が異なる)。移行ステップ: ①N8Nで並行して同じワークフローを構築②テスト用のWebhookで動作確認③外部サービスのWebhook URLをN8Nに切り替えて本番移行④Zapierを無効化。
Q. N8Nのコード(JavaScriptノード)とZapierのFormatterの違いは?
A. N8Nのコードノードは任意のJavaScript(またはPython)を書ける完全なプログラミング環境です。できること: 正規表現処理・配列操作・外部APIの呼び出し(httpリクエスト)・複数アイテムの変換・条件分岐ロジック。Zapierのは定型の変換(大文字変換・日付フォーマット等)のみ。実例: Zapierでは「メールの件名から注文番号を抽出する」のにFormatterでは対応できずZapier Code(有料)が必要でした。N8Nのコードノードではconst match = $json.subject.match(/ORDER-(\d+)/); return [{json: {order_id: match?.[1]}}]と書くだけで無料で対応できます。
Q. Temporalはどんなユースケースに最適ですか?
A. Temporalが最も価値を発揮するのは「失敗したら途中から再開したい長時間のビジネスプロセス」です。具体例: ①ECサイトの注文フロー(決済→在庫確認→配送指示→メール→3日後にレビュー依頼)が途中で失敗しても続きから再開②ユーザーオンボーディング(アカウント作成→メール確認→7日間のウェルカムシーケンス→未ログインなら14日後にリマインダー)③バッチデータ処理(100万件のCSVを1000件ずつ処理→途中でクラッシュしても処理済みの分はスキップして再開)。逆に向かないケース: 単純なWebhook→通知のような短時間1ステップのフローはn8nが圧倒的に簡単です。
Q. PrefectとApache Airflowの違いは何ですか?
A. どちらもPythonデータパイプライン向けですが: Apache Airflow: DAG(有向非巡回グラフ)をPythonファイルで定義し、ScheduledJobsとして管理。歴史が長くエコシステムが豊富。設定が複雑でローカルでのテストが難しい。Prefect: 普通のPython関数に@flow・@taskデコレータを付けるだけでワークフロー化。ローカルでpython my_flow.pyで実行できてテストが簡単。動的なワークフロー(実行時にタスク数が変わる)に対応。PrefectはAirflowからの移行が容易で、既存のPythonコードへの追加が最小限です。Airflowの方がKubernetes上での大規模スケーリングが成熟しています。
まとめ
| ユースケース | 推奨ツール |
|---|---|
| Zapier代替・GUIノーコード | n8n |
| 障害耐性・長時間ビジネスプロセス | Temporal |
| Pythonデータパイプライン・ML | Prefect |