The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Weekly Support Triage Review with Apify",
"nodes": [
{
"parameters": {},
"id": "manual-trigger",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [
260,
220
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"weeksInterval": 1
}
]
}
},
"id": "weekly-schedule",
"name": "Weekly Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
260,
420
]
},
{
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "tickets",
"name": "tickets",
"type": "array",
"value": [
{
"id": "T-1001",
"customerName": "Jordan Lee",
"subject": "Charged twice and still cannot access my account",
"message": "I was charged twice yesterday and the login link still says my account is disabled. This is blocking my team. Please fix this today or refund us.",
"channel": "email",
"customerTier": "business"
},
{
"id": "T-1002",
"customerName": "Mina",
"subject": "How do I export invoices?",
"message": "Where can I download all invoices for last quarter? I need them for accounting.",
"channel": "chat",
"customerTier": "starter"
}
]
},
{
"id": "default-language",
"name": "defaultLanguage",
"type": "string",
"value": "English"
},
{
"id": "brand-voice",
"name": "brandVoice",
"type": "string",
"value": "calm, concise, and helpful"
},
{
"id": "business-context",
"name": "businessContext",
"type": "string",
"value": "SaaS support team handling billing, account access, onboarding, bugs, cancellations, and feature questions."
},
{
"id": "reply-signature",
"name": "replySignature",
"type": "string",
"value": "Support Team"
},
{
"id": "include-reply-draft",
"name": "includeReplyDraft",
"type": "boolean",
"value": true
},
{
"id": "include-faq-candidates",
"name": "includeFaqCandidates",
"type": "boolean",
"value": true
}
]
}
},
"id": "support-input",
"name": "Support Tickets Input",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
540,
320
],
"notesInFlow": true,
"notes": "Replace the sample tickets with records from Gmail, Zendesk, Help Scout, Intercom, a form, or a spreadsheet. Keep only the fields your team is comfortable sending to Apify."
},
{
"parameters": {
"method": "POST",
"url": "={{'https://api.apify.com/v2/acts/jumpy_invoice~support-triage-intelligence/run-sync-get-dataset-items?token=' + $env.APIFY_TOKEN}}",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{JSON.stringify($json)}}",
"options": {
"timeout": 120000
}
},
"id": "run-apify-actor",
"name": "Run Support Triage Actor",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
820,
320
],
"notesInFlow": true,
"notes": "Calls the published Apify actor using APIFY_TOKEN from the n8n environment. The actor returns priority, category, sentiment, escalation guidance, draft replies, and FAQ candidates."
},
{
"parameters": {
"jsCode": "const analyses = Array.isArray($json) ? $json : [$json];\nconst tickets = analyses.filter(Boolean);\nconst totalTickets = tickets.length;\nconst urgentTickets = tickets.filter((ticket) => ticket.priority === 'urgent' || ticket.escalationRequired);\nconst negativeTickets = tickets.filter((ticket) => ticket.sentiment === 'negative');\nconst categories = tickets.reduce((counts, ticket) => {\n const category = ticket.category || 'uncategorized';\n counts[category] = (counts[category] || 0) + 1;\n return counts;\n}, {});\nconst escalationQueue = urgentTickets.map((ticket) => ({\n id: ticket.id,\n customerName: ticket.customerName,\n subject: ticket.subject,\n priority: ticket.priority,\n priorityScore: ticket.priorityScore,\n category: ticket.category,\n reason: ticket.escalationReason,\n nextActions: ticket.nextActions || []\n}));\nconst replyReviewQueue = tickets.filter((ticket) => ticket.replyDraft).map((ticket) => ({\n id: ticket.id,\n subject: ticket.subject,\n priority: ticket.priority,\n category: ticket.category,\n draftSubject: ticket.replyDraft.subject,\n draftBody: ticket.replyDraft.body\n}));\nconst faqCandidates = tickets.filter((ticket) => ticket.faqCandidate).map((ticket) => ({\n id: ticket.id,\n question: ticket.faqCandidate.question,\n answerOutline: ticket.faqCandidate.answerOutline,\n reuseScore: ticket.faqCandidate.reuseScore\n}));\nconst topNextActions = tickets.flatMap((ticket) => ticket.nextActions || []).slice(0, 12);\nreturn [{ json: { totalTickets, urgentCount: urgentTickets.length, negativeCount: negativeTickets.length, categories, escalationQueue, replyReviewQueue, faqCandidates, topNextActions, tickets } }];"
},
"id": "prepare-review",
"name": "Prepare Human Review Queue",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1100,
320
],
"notesInFlow": true,
"notes": "Builds escalationQueue, replyReviewQueue, faqCandidates, and topNextActions. This keeps the workflow human-in-the-loop instead of auto-sending replies."
},
{
"parameters": {
"mode": "manual",
"duplicateItem": false,
"assignments": {
"assignments": [
{
"id": "report-title",
"name": "reportTitle",
"type": "string",
"value": "={{'Weekly Support Triage Review - ' + $json.urgentCount + ' urgent of ' + $json.totalTickets + ' tickets'}}"
},
{
"id": "report-summary",
"name": "reportSummary",
"type": "string",
"value": "={{'Analyzed ' + $json.totalTickets + ' tickets. Urgent/escalation: ' + $json.urgentCount + '. Negative sentiment: ' + $json.negativeCount + '. Top category: ' + Object.entries($json.categories).sort((a,b)=>b[1]-a[1])[0]?.[0]}}"
},
{
"id": "escalation-queue",
"name": "escalationQueue",
"type": "array",
"value": "={{$json.escalationQueue}}"
},
{
"id": "reply-review-queue",
"name": "replyReviewQueue",
"type": "array",
"value": "={{$json.replyReviewQueue}}"
},
{
"id": "faq-candidates",
"name": "faqCandidates",
"type": "array",
"value": "={{$json.faqCandidates}}"
},
{
"id": "top-next-actions",
"name": "topNextActions",
"type": "array",
"value": "={{$json.topNextActions}}"
}
]
}
},
"id": "final-review-report",
"name": "Final Human Review Report",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1380,
320
],
"notesInFlow": true,
"notes": "Final report object ready to route to Slack, email, ClickUp, Notion, Airtable, Google Sheets, or a support lead."
},
{
"parameters": {
"content": "## Weekly Support Triage Review\n\nUse this workflow to turn messy support tickets into a human review queue. It sends ticket records to the Apify Support Triage Intelligence actor, then produces escalation items, reply drafts for approval, FAQ candidates, and next actions.",
"height": 220,
"width": 420
},
"id": "note-overview",
"name": "Overview Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
500,
40
]
},
{
"parameters": {
"content": "## Setup\n\n1. Set `APIFY_TOKEN` in your n8n environment.\n2. Edit **Support Tickets Input** with your ticket records, brand voice, business context, and reply signature.\n3. Run manually once before activating the weekly schedule.",
"height": 220,
"width": 420
},
"id": "note-setup",
"name": "Setup Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
780,
560
]
},
{
"parameters": {
"content": "## Human review required\n\nThis template does not send customer replies automatically. Review draft replies before sending, especially for billing, refund, legal, security, angry-language, or account-access tickets.",
"height": 200,
"width": 420
},
"id": "note-human-review",
"name": "Human Review Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1070,
40
]
},
{
"parameters": {
"content": "## Output routing\n\nThe final node returns a compact report object. Connect it to Slack, email, ClickUp, Notion, Airtable, Google Sheets, or a support lead dashboard after you verify the sample output.",
"height": 200,
"width": 420
},
"id": "note-output-routing",
"name": "Output Routing Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1360,
560
]
}
],
"connections": {
"Manual Trigger": {
"main": [
[
{
"node": "Support Tickets Input",
"type": "main",
"index": 0
}
]
]
},
"Weekly Schedule": {
"main": [
[
{
"node": "Support Tickets Input",
"type": "main",
"index": 0
}
]
]
},
"Support Tickets Input": {
"main": [
[
{
"node": "Run Support Triage Actor",
"type": "main",
"index": 0
}
]
]
},
"Run Support Triage Actor": {
"main": [
[
{
"node": "Prepare Human Review Queue",
"type": "main",
"index": 0
}
]
]
},
"Prepare Human Review Queue": {
"main": [
[
{
"node": "Final Human Review Report",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"tags": [
{
"name": "Support"
},
{
"name": "Apify"
},
{
"name": "Human Review"
}
]
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Weekly Support Triage Review with Apify. Uses httpRequest. Event-driven trigger; 10 nodes.
Source: https://github.com/xiaopeng215-sys/geo-visibility-audit-mcp/blob/main/workflows/support-triage-weekly-review.n8n.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow uses the Zyte API to automatically detect and extract structured data from E-commerce sites, Articles, Job Boards, and Search Engine Results (SERP) - no custom CSS selectors required.
Automate LinkedIn lead generation by scraping comments from targeted posts and enriching profiles with detailed data
This workflow contains community nodes that are only compatible with the self-hosted version of n8n.
This workflow runs a spider job in the background via Scrapyd, using a YAML config that defines selectors and parsing rules. When triggered, it schedules the spider with parameters (query, project ID,
This n8n workflow collects leads from Google Maps, scrapes their websites via direct HTTP requests, and extracts valid email addresses — all while mimicking real user behavior to improve scraping reli