mcpField
N
n8n-workflow-automation

n8n-workflow-automation

github.com/datadrivenconstruction生産性377111 回インストール2 週間前に更新
リポジトリ

n8n-workflow-automation について

システム連携と定型処理の自動化に使う、建設業向けの n8n ワークフロー自動化スキルです。Revit から予算への連携、BIM 変更検出、数量抽出、プロジェクト報告の例を扱います。

主な機能

  1. 01n8n によるビジュアルワークフロー自動化
  2. 02Revit エクスポートから予算への連携
  3. 03BIM モデルの変更検出
  4. 04数量抽出とコスト照合
  5. 05定期的なプロジェクト報告ワークフロー

活用シーン

  1. 01Revit エクスポートを予算データに変換
  2. 02IFC モデルフォルダーの変更を検出
  3. 03日次プロジェクト状況報告を作成
  4. 04建築要素と単価を照合

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/datadrivenconstruction/ddc_skills_for_ai_agents_in_construction --skill n8n-workflow-automation

インストール後、Claude Code で/n8n-workflow-automationを入力して読み込まれたか確認します。

同梱ファイルclaw.jsoninstructions.md

詳細

建設向けn8nワークフロー自動化

概要

このスキルでは、n8nを使用して建設プロセスのビジュアルなワークフロー自動化を実現します。定型作業を自動化し、システムを連携させて、大規模なプログラミングを行わずに、プロジェクトから予算までのパイプラインを構築できます。

DDCの方法論から着想 — BIMモデルとコスト見積もりをつなぐ処理を自動化します。

「『プロジェクトから見積もりまで』のプロセスを自動化することで、予算作成にかかる時間を数週間から数時間に短縮できます。」 — DDC LinkedInの投稿

クイックスタート

n8nのインストール
# Using Docker (recommended)
docker run -it --rm \
  --name n8n \
  -p 5678:5678 \
  -v ~/.n8n:/home/node/.n8n \
  n8nio/n8n

# Using npm
npm install n8n -g
n8n start

# Access at: http://localhost:5678

建設ワークフローの例

1. Revitから予算までのパイプライン
{
  "name": "Revit to Budget Automation",
  "nodes": [
    {
      "name": "Watch Revit Export Folder",
      "type": "n8n-nodes-base.localFileTrigger",
      "parameters": {
        "path": "/data/revit_exports",
        "events": ["add"],
        "fileExtension": ".xlsx"
      }
    },
    {
      "name": "Read Excel Data",
      "type": "n8n-nodes-base.readWriteFile",
      "parameters": {
        "operation": "read",
        "filePath": "={{ $json.fileName }}"
      }
    },
    {
      "name": "Parse BIM Elements",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "language": "python",
        "code": "import pandas as pd\nimport json\n\ndf = pd.read_excel(items[0].binary.data)\n\nelements = df.to_dict('records')\n\nreturn [{'json': {'elements': elements, 'count': len(elements)}}]"
      }
    },
    {
      "name": "Match to Unit Prices",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "http://api.construction-prices.com/match",
        "method": "POST",
        "body": "={{ JSON.stringify($json.elements) }}"
      }
    },
    {
      "name": "Calculate Costs",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "language": "javascript",
        "code": "const elements = items[0].json.elements;\n\nlet totalCost = 0;\nconst costBreakdown = [];\n\nfor (const elem of elements) {\n  const cost = elem.quantity * elem.unit_price;\n  totalCost += cost;\n  costBreakdown.push({\n    category: elem.category,\n    quantity: elem.quantity,\n    unit_price: elem.unit_price,\n    total: cost\n  });\n}\n\nreturn [{\n  json: {\n    total_cost: totalCost,\n    breakdown: costBreakdown\n  }\n}];"
      }
    },
    {
      "name": "Generate Report",
      "type": "n8n-nodes-base.spreadsheetFile",
      "parameters": {
        "operation": "create",
        "fileName": "cost_estimate_{{ $now.format('yyyy-MM-dd') }}.xlsx"
      }
    },
    {
      "name": "Send Email Notification",
      "type": "n8n-nodes-base.emailSend",
      "parameters": {
        "to": "[email protected]",
        "subject": "New Cost Estimate Generated",
        "text": "Total estimate: ${{ $json.total_cost }}"
      }
    }
  ]
}
2. 日次プロジェクトレポートの自動化
{
  "name": "Daily Project Report",
  "nodes": [
    {
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.cron",
      "parameters": {
        "cronExpression": "0 6 * * 1-5"
      }
    },
    {
      "name": "Fetch Project Data",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "{{ $env.PROJECT_API }}/status",
        "method": "GET"
      }
    },
    {
      "name": "Fetch Weather Data",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "https://api.openweathermap.org/data/2.5/weather",
        "qs": {
          "q": "{{ $json.project_location }}",
          "appid": "{{ $env.WEATHER_API_KEY }}"
        }
      }
    },
    {
      "name": "Generate Report",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "language": "javascript",
        "code": "const project = items[0].json;\nconst weather = items[1].json;\n\nconst report = {\n  date: new Date().toISOString().split('T')[0],\n  project_name: project.name,\n  progress: project.progress_pct,\n  weather: {\n    condition: weather.weather[0].main,\n    temp: Math.round(weather.main.temp - 273.15)\n  },\n  tasks_today: project.scheduled_tasks,\n  blockers: project.blockers || []\n};\n\nreturn [{ json: report }];"
      }
    },
    {
      "name": "Post to Slack",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#project-updates",
        "text": "📊 Daily Report - {{ $json.project_name }}\n\nProgress: {{ $json.progress }}%\n🌡️ Weather: {{ $json.weather.condition }} ({{ $json.weather.temp }}°C)\n\nToday's Tasks:\n{{ $json.tasks_today.join('\\n') }}"
      }
    }
  ]
}
3. BIMモデルの変更検出
{
  "name": "BIM Change Detection",
  "nodes": [
    {
      "name": "Watch IFC Folder",
      "type": "n8n-nodes-base.localFileTrigger",
      "parameters": {
        "path": "/models",
        "events": ["change"],
        "fileExtension": ".ifc"
      }
    },
    {
      "name": "Extract Model Data",
      "type": "n8n-nodes-base.executeCommand",
      "parameters": {
        "command": "python /scripts/extract_ifc.py {{ $json.fileName }}"
      }
    },
    {
      "name": "Compare with Previous",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "language": "python",
        "code": "import json\n\ncurrent = json.loads(items[0].json.output)\nprevious = load_previous_version()\n\nchanges = {\n  'added': [],\n  'modified': [],\n  'deleted': []\n}\n\n# Compare logic\nfor elem in current:\n  if elem['id'] not in previous:\n    changes['added'].append(elem)\n  elif elem != previous[elem['id']]:\n    changes['modified'].append(elem)\n\nfor elem_id in previous:\n  if elem_id not in [e['id'] for e in current]:\n    changes['deleted'].append(previous[elem_id])\n\nreturn [{'json': changes}]"
      }
    },
    {
      "name": "Update Database",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO model_changes (timestamp, changes) VALUES (NOW(), '{{ JSON.stringify($json) }}')"
      }
    },
    {
      "name": "Notify Team",
      "type": "n8n-nodes-base.microsoftTeams",
      "parameters": {
        "message": "🔔 Model Updated\n\n+{{ $json.added.length }} elements added\n📝 {{ $json.modified.length }} elements modified\n-{{ $json.deleted.length }} elements deleted"
      }
    }
  ]
}

よくあるワークフローパターン

データ抽出パターン
// n8n Code Node - Extract BIM Quantities
const xlsx = require('xlsx');

// Read uploaded file
const workbook = xlsx.read(items[0].binary.data, { type: 'buffer' });
const sheetName = workbook.SheetNames[0];
const data = xlsx.utils.sheet_to_json(workbook.Sheets[sheetName]);

// Process BIM elements
const quantities = {};
for (const row of data) {
  const category = row['Category'] || 'Unknown';
  const volume = parseFloat(row['Volume']) || 0;

  if (!quantities[category]) {
    quantities[category] = { count: 0, volume: 0 };
  }
  quantities[category].count++;
  quantities[category].volume += volume;
}

return [{ json: { quantities, total_elements: data.length } }];
コスト照合パターン
// n8n Code Node - Match elements to unit prices
const elements = items[0].json.elements;
const priceDatabase = $env.PRICE_DATABASE;

const matched = [];

for (const elem of elements) {
  // Fuzzy match description to price items
  const match = await $http.post(`${priceDatabase}/search`, {
    query: elem.description,
    category: elem.category
  });

  matched.push({
    ...elem,
    matched_item: match.data.best_match,
    unit_price: match.data.unit_price,
    confidence: match.data.confidence
  });
}

return [{ json: { matched_elements: matched } }];
レポート生成パターン
// n8n Code Node - Generate PDF Report
const PDFDocument = require('pdfkit');

const doc = new PDFDocument();
const buffers = [];

doc.on('data', buffers.push.bind(buffers));

// Header
doc.fontSize(20).text('Cost Estimate Report', { align: 'center' });
doc.moveDown();

// Project Info
doc.fontSize(12).text(`Project: ${items[0].json.project_name}`);
doc.text(`Date: ${new Date().toLocaleDateString()}`);
doc.moveDown();

// Cost Summary
doc.fontSize(14).text('Cost Summary', { underline: true });
for (const [category, cost] of Object.entries(items[0].json.costs)) {
  doc.fontSize(10).text(`${category}: $${cost.toLocaleString()}`);
}

doc.end();

return new Promise(resolve => {
  doc.on('end', () => {
    resolve([{
      json: { success: true },
      binary: {
        data: Buffer.concat(buffers).toString('base64'),
        fileName: 'cost_report.pdf',
        mimeType: 'application/pdf'
      }
    }]);
  });
});

統合ノード

建設向けの便利なn8nノード
Data Sources:
  - Google Sheets: Project tracking, cost databases
  - Airtable: Element databases, issue tracking
  - PostgreSQL: BIM databases, project data
  - HTTP Request: API integrations

File Processing:
  - Read/Write File: Excel, CSV, JSON
  - Execute Command: Python scripts, CLI tools
  - Code: Custom processing logic

Communication:
  - Slack: Team notifications
  - Microsoft Teams: Project updates
  - Email: Reports, alerts
  - Telegram: Mobile notifications

Cloud Storage:
  - AWS S3: Model storage
  - Google Drive: Document sharing
  - Dropbox: File sync

ワークフローテンプレート

テンプレート:QTOからExcelへ
{
  "workflow": "QTO Extraction",
  "trigger": "Manual/Webhook",
  "steps": [
    "Receive IFC file",
    "Extract quantities (Python/IfcOpenShell)",
    "Group by category",
    "Add unit prices",
    "Calculate totals",
    "Generate Excel report",
    "Upload to cloud storage",
    "Send notification"
  ]
}
テンプレート:日次ステータスの収集
{
  "workflow": "Daily Status",
  "trigger": "Cron (6:00 AM)",
  "steps": [
    "Fetch project status from API",
    "Get weather forecast",
    "Check scheduled tasks",
    "Compile daily report",
    "Post to Slack/Teams",
    "Email to stakeholders"
  ]
}

ベストプラクティス

1. **Error Handling**
   - Always add error branches
   - Log failures to database
   - Send alerts on critical failures

2. **Data Validation**
   - Validate input data format
   - Check for required fields
   - Handle missing values gracefully

3. **Performance**
   - Use batch processing for large datasets
   - Implement pagination for API calls
   - Cache frequently used data

4. **Security**
   - Store credentials in environment variables
   - Use encryption for sensitive data
   - Implement access controls

クイックリファレンス

ワークフローの種類トリガーよく使われるノード
ファイル処理ファイルトリガーCode、HTTP、Spreadsheet
定期レポートCronHTTP、Code、Email
データ同期WebhookDatabase、API、Code
通知各種Slack、Teams、Email

リソース

次のステップ

  • コードベースのデータパイプラインについては、etl-pipelineを参照してください
  • AIを活用した自動化については、llm-data-automationを参照してください
  • インテリジェントなドキュメント検索については、vector-searchを参照してください

コメント