mirror of
https://github.com/domfelipe/vibeflow-n8n.git
synced 2026-08-07 06:16:40 +00:00
Rebuild Vibeflow as an n8n safety gate
This commit is contained in:
parent
79fc67166a
commit
febec32131
101 changed files with 2405 additions and 3557 deletions
|
|
@ -1,10 +0,0 @@
|
|||
# Example Briefs
|
||||
|
||||
## Example 1
|
||||
Create an n8n workflow that receives leads from a webhook, scores them with AI, sends hot leads to Slack, and stores everything in HubSpot.
|
||||
|
||||
## Example 2
|
||||
Create a workflow that runs every weekday at 8 AM, pulls yesterday's orders from an API, summarizes key metrics, and posts the summary to Microsoft Teams.
|
||||
|
||||
## Example 3
|
||||
Create a workflow that watches Gmail for invoices, extracts key information with AI, stores structured records in Airtable, and alerts finance when the amount is above a threshold.
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# Example Final Report
|
||||
|
||||
## Summary
|
||||
A workflow named `Lead Intake and Triage` was created to receive incoming lead data, score urgency using AI, send high-priority leads to Slack, and store all leads in HubSpot.
|
||||
|
||||
## What was created
|
||||
- Webhook trigger for incoming lead payloads
|
||||
- Validation step for required lead fields
|
||||
- AI scoring and summarization step
|
||||
- Conditional branch for hot leads
|
||||
- Slack notification for hot leads
|
||||
- HubSpot create/update action
|
||||
- Generic failure notification path
|
||||
|
||||
## Assumptions used
|
||||
- Lead uniqueness is based on email
|
||||
- Slack notifications are required only for hot leads
|
||||
- Missing optional fields do not block processing
|
||||
|
||||
## Manual setup still required
|
||||
- Connect OpenAI credentials
|
||||
- Connect Slack credentials
|
||||
- Connect HubSpot credentials
|
||||
- Review final field mappings for HubSpot properties
|
||||
|
||||
## How to test
|
||||
1. Send a sample payload to the webhook
|
||||
2. Confirm the AI score is produced
|
||||
3. Verify hot leads appear in Slack
|
||||
4. Verify the record is stored in HubSpot
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
# Example Plans
|
||||
|
||||
## Example 1 Plan
|
||||
|
||||
- Workflow name: Lead Intake and Triage
|
||||
- Trigger: Webhook
|
||||
- Systems: Webhook, OpenAI, Slack, HubSpot
|
||||
- Steps:
|
||||
- Receive lead payload
|
||||
- Validate required fields
|
||||
- Score and summarize with AI
|
||||
- Branch on urgency
|
||||
- Notify Slack for hot leads
|
||||
- Upsert lead in HubSpot
|
||||
- Error handling:
|
||||
- Return validation error on missing fields
|
||||
- Send Slack alert on workflow failure
|
||||
|
||||
## Example 2 Plan
|
||||
|
||||
- Workflow name: Daily Orders Digest
|
||||
- Trigger: Schedule weekdays 08:00
|
||||
- Systems: HTTP API, Code/Transform, Microsoft Teams
|
||||
- Steps:
|
||||
- Run on schedule
|
||||
- Fetch yesterday's orders
|
||||
- Aggregate totals and deltas
|
||||
- Generate concise summary
|
||||
- Post digest to Teams
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
# Example Walkthroughs
|
||||
|
||||
## Walkthrough 1: Lead qualification
|
||||
|
||||
### User request
|
||||
Create an n8n workflow that receives a website lead, summarizes the lead using AI, classifies urgency, sends hot leads to Slack, and saves all leads in Airtable.
|
||||
|
||||
### Agent follow-up questions
|
||||
1. What triggers the workflow: webhook, form, or CRM event?
|
||||
2. How should a hot lead be defined?
|
||||
3. Should Airtable create new records only or update existing ones?
|
||||
4. Which Slack channel should receive hot leads?
|
||||
|
||||
### Normalized plan summary
|
||||
- trigger: webhook
|
||||
- systems: OpenAI, Slack, Airtable
|
||||
- duplicate strategy: upsert by email
|
||||
- alert rule: hot if urgency score >= 8
|
||||
- fallback: notify ops on failure
|
||||
|
||||
### Delivery excerpt
|
||||
Workflow created with webhook trigger, AI enrichment, urgency classification, hot lead branch, Slack notification, Airtable upsert path, and failure alert stub.
|
||||
|
||||
## Walkthrough 2: Weekly finance digest
|
||||
|
||||
### User request
|
||||
Every Monday morning, collect unpaid invoices from the ERP, summarize totals by customer, and send the finance team a Slack digest.
|
||||
|
||||
### Critical follow-ups
|
||||
1. What ERP or source system holds the invoice data?
|
||||
2. What timezone should Monday morning use?
|
||||
3. Should the digest include overdue aging buckets?
|
||||
4. Is Slack the only output?
|
||||
|
||||
### Plan summary
|
||||
- trigger: schedule weekly
|
||||
- output: internal Slack digest
|
||||
- data grouping: by customer and due bucket
|
||||
- caution: no customer-facing messages
|
||||
99
examples/safe-support-agent.workflow.json
Normal file
99
examples/safe-support-agent.workflow.json
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
"name": "Safe support agent",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "webhook",
|
||||
"name": "Authenticated Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"parameters": { "authentication": "headerAuth", "path": "support" },
|
||||
"credentials": { "httpHeaderAuth": { "id": "credential-reference", "name": "Webhook Header Auth" } }
|
||||
},
|
||||
{
|
||||
"id": "dedupe",
|
||||
"name": "Claim idempotency event",
|
||||
"type": "n8n-nodes-base.postgres",
|
||||
"onError": "continueErrorOutput",
|
||||
"parameters": {
|
||||
"operation": "executeQuery",
|
||||
"query": "INSERT INTO event_ledger (event_id) VALUES ($1) ON CONFLICT (event_id) DO NOTHING RETURNING event_id",
|
||||
"queryReplacement": "={{ $json.event_id }}"
|
||||
},
|
||||
"credentials": { "postgres": { "id": "credential-reference", "name": "Event Ledger" } }
|
||||
},
|
||||
{
|
||||
"id": "ledger-failure",
|
||||
"name": "Ledger failure stop",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"parameters": {}
|
||||
},
|
||||
{
|
||||
"id": "enabled",
|
||||
"name": "Agent enabled kill switch",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"parameters": { "conditions": { "boolean": [{ "value1": "={{ $json.agent_enabled }}", "value2": true }] } }
|
||||
},
|
||||
{
|
||||
"id": "agent",
|
||||
"name": "AI Agent",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"parameters": { "text": "={{ $json.body.message }}" }
|
||||
},
|
||||
{
|
||||
"id": "model",
|
||||
"name": "OpenAI Chat Model",
|
||||
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
|
||||
"parameters": { "modelName": "gpt-4.1-mini" },
|
||||
"credentials": { "openAiApi": { "id": "credential-reference", "name": "OpenAI" } }
|
||||
},
|
||||
{
|
||||
"id": "confidence",
|
||||
"name": "Confidence gate",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"parameters": { "conditions": { "number": [{ "value1": "={{ $json.confidence }}", "operation": "smaller", "value2": 0.7 }] } }
|
||||
},
|
||||
{
|
||||
"id": "handoff",
|
||||
"name": "Human handoff ticket",
|
||||
"type": "n8n-nodes-base.slack",
|
||||
"onError": "continueErrorOutput",
|
||||
"parameters": { "channel": "support", "text": "={{ $json.summary }}" }
|
||||
},
|
||||
{
|
||||
"id": "handoff-failure",
|
||||
"name": "Handoff failure stop",
|
||||
"type": "n8n-nodes-base.noOp",
|
||||
"parameters": {}
|
||||
},
|
||||
{
|
||||
"id": "response",
|
||||
"name": "Respond to Webhook",
|
||||
"type": "n8n-nodes-base.respondToWebhook",
|
||||
"parameters": { "respondWith": "json", "responseBody": "={{ $json }}" }
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Authenticated Webhook": { "main": [[{ "node": "Claim idempotency event", "type": "main", "index": 0 }]] },
|
||||
"Claim idempotency event": {
|
||||
"main": [
|
||||
[{ "node": "Agent enabled kill switch", "type": "main", "index": 0 }],
|
||||
[{ "node": "Ledger failure stop", "type": "main", "index": 0 }]
|
||||
]
|
||||
},
|
||||
"Agent enabled kill switch": { "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }], []] },
|
||||
"OpenAI Chat Model": { "ai_languageModel": [[{ "node": "AI Agent", "type": "ai_languageModel", "index": 0 }]] },
|
||||
"AI Agent": { "main": [[{ "node": "Confidence gate", "type": "main", "index": 0 }]] },
|
||||
"Confidence gate": {
|
||||
"main": [
|
||||
[{ "node": "Human handoff ticket", "type": "main", "index": 0 }],
|
||||
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
|
||||
]
|
||||
},
|
||||
"Human handoff ticket": {
|
||||
"main": [
|
||||
[],
|
||||
[{ "node": "Handoff failure stop", "type": "main", "index": 0 }]
|
||||
]
|
||||
}
|
||||
},
|
||||
"settings": { "executionTimeout": 120 }
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
{
|
||||
"plan_version": "0.3.0",
|
||||
"workflow_name": "Typeform Lead Triage",
|
||||
"objective": "Capture new Typeform submissions, summarize with AI, classify lead temperature, notify Slack for hot leads, and store all submissions in Airtable.",
|
||||
"trigger": {
|
||||
"type": "typeform_submission",
|
||||
"summary": "Runs whenever a new Typeform response is received.",
|
||||
"input_shape": "Form response payload with contact, answers, and metadata."
|
||||
},
|
||||
"systems": [
|
||||
"Typeform",
|
||||
"OpenAI",
|
||||
"Slack",
|
||||
"Airtable",
|
||||
"n8n"
|
||||
],
|
||||
"steps": [
|
||||
{
|
||||
"id": "step_1",
|
||||
"name": "Receive submission",
|
||||
"action": "Read the incoming Typeform payload."
|
||||
},
|
||||
{
|
||||
"id": "step_2",
|
||||
"name": "Summarize content",
|
||||
"action": "Generate a concise summary with AI.",
|
||||
"depends_on": [
|
||||
"step_1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step_3",
|
||||
"name": "Classify lead",
|
||||
"action": "Assign hot, warm, or cold label.",
|
||||
"depends_on": [
|
||||
"step_2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step_4",
|
||||
"name": "Branch urgent leads",
|
||||
"action": "If hot, send a Slack alert.",
|
||||
"depends_on": [
|
||||
"step_3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "step_5",
|
||||
"name": "Persist record",
|
||||
"action": "Write all leads to Airtable.",
|
||||
"depends_on": [
|
||||
"step_3"
|
||||
]
|
||||
}
|
||||
],
|
||||
"branching": [
|
||||
{
|
||||
"condition": "lead_temperature == 'hot'",
|
||||
"path": "notify_slack"
|
||||
},
|
||||
{
|
||||
"condition": "lead_temperature != 'hot'",
|
||||
"path": "skip_slack"
|
||||
}
|
||||
],
|
||||
"credentials": [
|
||||
{
|
||||
"system": "Typeform",
|
||||
"status": "required"
|
||||
},
|
||||
{
|
||||
"system": "OpenAI",
|
||||
"status": "required"
|
||||
},
|
||||
{
|
||||
"system": "Slack",
|
||||
"status": "required"
|
||||
},
|
||||
{
|
||||
"system": "Airtable",
|
||||
"status": "required"
|
||||
}
|
||||
],
|
||||
"assumptions": [
|
||||
"The Typeform payload includes enough text to summarize.",
|
||||
"Slack alerting is only required for hot leads.",
|
||||
"Airtable base and table are already chosen by the user."
|
||||
],
|
||||
"risks": [
|
||||
"Missing credentials block full end-to-end testing.",
|
||||
"Lead classification thresholds may need tuning after first runs."
|
||||
],
|
||||
"validation": {
|
||||
"checks": [
|
||||
"Confirm the Typeform trigger fires with a real payload.",
|
||||
"Confirm AI output contains both summary and label.",
|
||||
"Confirm Slack only receives hot leads.",
|
||||
"Confirm Airtable receives every submission."
|
||||
],
|
||||
"manual_steps": [
|
||||
"Connect credentials in n8n if placeholders were used.",
|
||||
"Review the prompt used for classification before production rollout."
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
{
|
||||
"name": "Vibeflow Demo - Support Escalation",
|
||||
"active": false,
|
||||
"meta": {
|
||||
"source": "vibeflow-n8n",
|
||||
"note": "Illustrative export skeleton for documentation and local experimentation."
|
||||
},
|
||||
"nodes": [
|
||||
{
|
||||
"id": "Webhook_1",
|
||||
"name": "Incoming Ticket",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"position": [260, 280],
|
||||
"parameters": {
|
||||
"path": "support-escalation-demo",
|
||||
"httpMethod": "POST"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "Set_1",
|
||||
"name": "Normalize Payload",
|
||||
"type": "n8n-nodes-base.set",
|
||||
"position": [520, 280],
|
||||
"parameters": {
|
||||
"keepOnlySet": false,
|
||||
"values": {
|
||||
"string": [
|
||||
{"name": "ticket_id", "value": "={{$json.id || ''}}"},
|
||||
{"name": "priority", "value": "={{$json.priority || 'normal'}}"},
|
||||
{"name": "summary", "value": "={{$json.summary || ''}}"}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "If_1",
|
||||
"name": "Urgent?",
|
||||
"type": "n8n-nodes-base.if",
|
||||
"position": [780, 280],
|
||||
"parameters": {
|
||||
"conditions": {
|
||||
"string": [
|
||||
{"value1": "={{$json.priority}}", "operation": "equal", "value2": "high"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Incoming Ticket": {
|
||||
"main": [[{"node": "Normalize Payload", "type": "main", "index": 0}]]
|
||||
},
|
||||
"Normalize Payload": {
|
||||
"main": [[{"node": "Urgent?", "type": "main", "index": 0}]]
|
||||
}
|
||||
}
|
||||
}
|
||||
43
examples/unsafe-support-agent.workflow.json
Normal file
43
examples/unsafe-support-agent.workflow.json
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "Unsafe support agent",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "webhook",
|
||||
"name": "Public Webhook",
|
||||
"type": "n8n-nodes-base.webhook",
|
||||
"parameters": { "path": "support" }
|
||||
},
|
||||
{
|
||||
"id": "agent",
|
||||
"name": "AI Agent",
|
||||
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||
"parameters": { "text": "Respond to the customer" }
|
||||
},
|
||||
{
|
||||
"id": "api",
|
||||
"name": "Send response",
|
||||
"type": "n8n-nodes-base.httpRequest",
|
||||
"retryOnFail": true,
|
||||
"maxTries": 10,
|
||||
"waitBetweenTries": 0,
|
||||
"parameters": {
|
||||
"url": "https://api.example.com/messages",
|
||||
"headerParameters": {
|
||||
"parameters": [{ "name": "Authorization", "value": "Bearer vf_fake_0123456789abcdef" }]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "shell",
|
||||
"name": "Run Shell",
|
||||
"type": "n8n-nodes-base.executeCommand",
|
||||
"parameters": { "command": "echo done" }
|
||||
}
|
||||
],
|
||||
"connections": {
|
||||
"Public Webhook": { "main": [[{ "node": "AI Agent", "type": "main", "index": 0 }]] },
|
||||
"AI Agent": { "main": [[{ "node": "Send response", "type": "main", "index": 0 }]] },
|
||||
"Send response": { "main": [[{ "node": "Run Shell", "type": "main", "index": 0 }]] }
|
||||
},
|
||||
"settings": {}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue