This workflow corresponds to n8n.io template #12799 — we link there as the canonical source.
This workflow follows the Agent → Gmail recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "2f5PfEk4ZDZhmRBL",
"name": "Unstructured Documents to Structured SOP Converter",
"tags": [],
"nodes": [
{
"id": "856cff55-91ed-4d59-bcc4-7d7c45a9a421",
"name": "New or Updated Document Trigger",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
1184,
448
],
"parameters": {
"event": "fileUpdated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": ""
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "43d4df7f-232a-4329-a969-353f58ce976d",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
1408,
448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "qualityThreshold",
"type": "number",
"value": 0.8
},
{
"id": "id-2",
"name": "sopFolderId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Google Drive Folder ID for SOPs__>"
},
{
"id": "id-3",
"name": "sheetsDocumentId",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Google Sheets Document ID for logging__>"
},
{
"id": "id-4",
"name": "slackChannel",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Slack channel ID or name__>"
},
{
"id": "id-5",
"name": "stakeholderEmails",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Comma-separated email addresses__>"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "c6ad4faa-f339-47d6-883d-33222658b289",
"name": "Download Document from Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
1632,
448
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {
"binaryPropertyName": "data"
},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "f8a5bc31-37c9-45e8-b884-787cb5817186",
"name": "Extract Text from Document",
"type": "n8n-nodes-base.extractFromFile",
"position": [
1856,
448
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1.1
},
{
"id": "70bee6ec-81c1-450c-abd6-a275900fc3e0",
"name": "Normalize Content and Metadata",
"type": "n8n-nodes-base.set",
"position": [
2080,
448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "documentText",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "id-2",
"name": "documentName",
"type": "string",
"value": "={{ $('New or Updated Document Trigger').item.json.name }}"
},
{
"id": "id-3",
"name": "documentId",
"type": "string",
"value": "={{ $('New or Updated Document Trigger').item.json.id }}"
},
{
"id": "id-4",
"name": "processedDate",
"type": "string",
"value": "={{ $now.toISO() }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "d72842ef-e49b-45be-938c-d241c241f3d4",
"name": "Generate SOP Structure",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2304,
448
],
"parameters": {
"text": "={{ $json.documentText }}",
"options": {
"systemMessage": "You are an expert SOP (Standard Operating Procedure) generator.\n\nYour task is to analyze unstructured internal documents and convert them into well-structured SOPs.\n\nFor the provided document text, generate a structured SOP with the following components:\n1. Title: Clear, descriptive title for the SOP\n2. Purpose: Brief explanation of why this procedure exists\n3. Scope: Who this applies to and when it should be used\n4. Steps: Detailed step-by-step instructions (numbered list)\n5. Responsibilities: Who is responsible for each major step\n6. References: Any related documents or resources mentioned\n\nEnsure the output is clear, actionable, and follows standard SOP formatting conventions.\n\nReturn the structured SOP in the defined JSON format."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "bd44c251-3081-4def-87b7-c5277fcb63ca",
"name": "OpenAI Model for SOP Structure",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2312,
672
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "gpt-4o"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "e1c69524-fa02-45dd-8869-50b38eb87294",
"name": "SOP Structure Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2440,
672
],
"parameters": {
"jsonSchemaExample": "{\n\t\"title\": \"Standard Operating Procedure Title\",\n\t\"purpose\": \"Description of the purpose of this SOP\",\n\t\"scope\": \"Description of the scope and applicability\",\n\t\"steps\": [\"Step 1 description\", \"Step 2 description\", \"Step 3 description\"],\n\t\"responsibilities\": [\n\t\t{\n\t\t\t\"role\": \"Role name\",\n\t\t\t\"task\": \"Task description\"\n\t\t}\n\t],\n\t\"references\": [\"Reference 1\", \"Reference 2\"],\n\t\"confidence\": 0.95\n}"
},
"typeVersion": 1.3
},
{
"id": "ff8220ff-5b0b-4539-9a89-f15ee1241d19",
"name": "Refine for Clarity and Consistency",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2656,
448
],
"parameters": {
"text": "={{ JSON.stringify($json.output) }}",
"options": {
"systemMessage": "You are an SOP quality assurance specialist.\n\nYour task is to review and refine the generated SOP for clarity, consistency, and completeness.\n\nReview the provided SOP structure and:\n1. Improve clarity of language and instructions\n2. Ensure consistency in terminology and formatting\n3. Verify all steps are actionable and specific\n4. Check that responsibilities are clearly assigned\n5. Validate that the scope and purpose are well-defined\n6. Assess overall quality and assign a confidence score (0-1)\n\nReturn the refined SOP in the same JSON format with your improvements and confidence assessment."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "f042f9e4-371b-4f01-a9a8-4c8f227424cf",
"name": "OpenAI Model for Refinement",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2664,
672
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "gpt-4o"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "84939a4a-ddc2-4fa3-9996-2698d7132c9a",
"name": "Refined SOP Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
2792,
672
],
"parameters": {
"jsonSchemaExample": "{\n\t\"title\": \"Standard Operating Procedure Title\",\n\t\"purpose\": \"Description of the purpose of this SOP\",\n\t\"scope\": \"Description of the scope and applicability\",\n\t\"steps\": [\"Step 1 description\", \"Step 2 description\", \"Step 3 description\"],\n\t\"responsibilities\": [\n\t\t{\n\t\t\t\"role\": \"Role name\",\n\t\t\t\"task\": \"Task description\"\n\t\t}\n\t],\n\t\"references\": [\"Reference 1\", \"Reference 2\"],\n\t\"confidence\": 0.95\n}"
},
"typeVersion": 1.3
},
{
"id": "c92a7798-eec6-42ee-9bcd-d643b8fc1e73",
"name": "Check Quality Threshold",
"type": "n8n-nodes-base.if",
"position": [
3008,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": false,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.output.confidence }}",
"rightValue": "={{ $('Workflow Configuration').item.json.qualityThreshold }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "0321a38b-64b4-4ecf-af56-d1d2c0a5fd58",
"name": "Create SOP Document",
"type": "n8n-nodes-base.googleDocs",
"position": [
3232,
448
],
"parameters": {
"title": "=SOP: {{ $json.output.title }}",
"folderId": "={{ $('Workflow Configuration').item.json.sopFolderId }}"
},
"typeVersion": 2
},
{
"id": "fd21e889-81af-4ada-8f14-35dc33202987",
"name": "Log SOP Metadata",
"type": "n8n-nodes-base.googleSheets",
"position": [
3456,
448
],
"parameters": {
"columns": {
"value": {
"SOP Title": "={{ $json.output.title }}",
"Document ID": "={{ $json.documentId }}",
"Created Date": "={{ $json.processedDate }}",
"Google Doc Link": "={{ $('Create SOP Document').item.json.documentUrl }}",
"Confidence Score": "={{ $json.output.confidence }}",
"Original Document Name": "={{ $json.documentName }}"
},
"schema": [
{
"id": "Original Document Name",
"required": false,
"displayName": "Original Document Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "SOP Title",
"required": false,
"displayName": "SOP Title",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Confidence Score",
"required": false,
"displayName": "Confidence Score",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Created Date",
"required": false,
"displayName": "Created Date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Document ID",
"required": false,
"displayName": "Document ID",
"defaultMatch": true,
"canBeUsedToMatch": true
},
{
"id": "Google Doc Link",
"required": false,
"displayName": "Google Doc Link",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"Document ID"
]
},
"options": {},
"operation": "appendOrUpdate",
"sheetName": {
"__rl": true,
"mode": "name",
"value": "SOP Log"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').item.json.sheetsDocumentId }}"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "be0bc7ce-752d-4d69-91aa-8ae2b582a74e",
"name": "Notify Operations Team",
"type": "n8n-nodes-base.slack",
"position": [
3680,
448
],
"parameters": {
"text": "=\ud83c\udf89 New SOP Created!\n\nA new Standard Operating Procedure has been generated from an unstructured document.\n\n\ud83d\udcc4 *Title:* {{ $('Create SOP Document').item.json.title }}\n\ud83d\udcca *Confidence Score:* {{ $('Check Quality Threshold').item.json.confidenceScore }}%\n\ud83d\udd17 *Document Link:* {{ $('Create SOP Document').item.json.documentUrl }}\n\nThe SOP is now available for review and has been logged in the metadata tracker.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "id",
"value": "={{ $('Workflow Configuration').item.json.slackChannel }}"
},
"otherOptions": {}
},
"typeVersion": 2.4
},
{
"id": "c59f396d-214e-4a7a-9d6d-7c068bc85baf",
"name": "Email SOP to Stakeholders",
"type": "n8n-nodes-base.gmail",
"position": [
3904,
448
],
"parameters": {
"sendTo": "={{ $('Workflow Configuration').item.json.stakeholderEmails }}",
"message": "=<h2>New SOP Created</h2>\n<p>A new Standard Operating Procedure has been generated and is ready for review.</p>\n\n<h3>SOP Details:</h3>\n<ul>\n <li><strong>Title:</strong> {{ $json.output.title }}</li>\n <li><strong>Purpose:</strong> {{ $json.output.purpose }}</li>\n <li><strong>Scope:</strong> {{ $json.output.scope }}</li>\n <li><strong>Confidence Score:</strong> {{ $json.output.confidenceScore }}</li>\n</ul>\n\n<p><strong>Document Link:</strong> <a href=\"{{ $('Create SOP Document').item.json.documentUrl }}\">View SOP in Google Docs</a></p>\n\n<p>Please review the SOP and provide any feedback to the operations team.</p>\n\n<p>Best regards,<br>Automated SOP System</p>",
"options": {},
"subject": "=New SOP Created: {{ $json.output.title }}"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "102c806e-69ce-471b-9e91-da2159238c16",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1136,
272
],
"parameters": {
"color": 7,
"width": 656,
"height": 640,
"content": "## Trigger & Config"
},
"typeVersion": 1
},
{
"id": "87c63266-55cb-44f1-8182-eb0c75ed4a68",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1808,
272
],
"parameters": {
"color": 7,
"width": 416,
"height": 640,
"content": "## Text Data"
},
"typeVersion": 1
},
{
"id": "b20e2c6f-7f85-417c-aef0-5a896e8841ff",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2256,
272
],
"parameters": {
"color": 7,
"width": 656,
"height": 640,
"content": "## AI Logic"
},
"typeVersion": 1
},
{
"id": "d9d01c39-9e8e-4d79-887d-53d71c6c9937",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2928,
272
],
"parameters": {
"color": 7,
"width": 448,
"height": 640,
"content": "## SOP"
},
"typeVersion": 1
},
{
"id": "dcf6ee0a-6756-4173-ab0a-9efc14278cd4",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
3408,
272
],
"parameters": {
"color": 7,
"width": 672,
"height": 640,
"content": "## Log & Notify"
},
"typeVersion": 1
},
{
"id": "e31970ec-d802-4183-91a8-cda485a96628",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
336
],
"parameters": {
"width": 432,
"height": 512,
"content": "## Main\nThis workflow converts messy internal documents into clean, structured SOPs using AI.\n\nIt\u2019s designed for teams that have knowledge scattered across docs, notes, or processes, and need repeatable, standardized procedures without manual rewriting.\n\nBuilt by:\nHyrum Hurst \nAI Automation Engineer \u2014 QuarterSmart \nContact: hyrum@quartersmart.com\n\n## Setup\n1. Connect Google Drive and Docs\n2. Choose source folder for raw documents\n3. Configure AI tone and SOP format\n4. Set notification channels\n5. Review generated SOPs before rollout\n"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "d587b75f-6013-4f34-8a7c-6929ecf0af45",
"connections": {
"Log SOP Metadata": {
"main": [
[
{
"node": "Notify Operations Team",
"type": "main",
"index": 0
}
]
]
},
"Create SOP Document": {
"main": [
[
{
"node": "Log SOP Metadata",
"type": "main",
"index": 0
}
]
]
},
"Generate SOP Structure": {
"main": [
[
{
"node": "Refine for Clarity and Consistency",
"type": "main",
"index": 0
}
]
]
},
"Notify Operations Team": {
"main": [
[
{
"node": "Email SOP to Stakeholders",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Download Document from Drive",
"type": "main",
"index": 0
}
]
]
},
"Check Quality Threshold": {
"main": [
[
{
"node": "Create SOP Document",
"type": "main",
"index": 0
}
]
]
},
"Refined SOP Output Parser": {
"ai_outputParser": [
[
{
"node": "Refine for Clarity and Consistency",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Extract Text from Document": {
"main": [
[
{
"node": "Normalize Content and Metadata",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Model for Refinement": {
"ai_languageModel": [
[
{
"node": "Refine for Clarity and Consistency",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"SOP Structure Output Parser": {
"ai_outputParser": [
[
{
"node": "Generate SOP Structure",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Download Document from Drive": {
"main": [
[
{
"node": "Extract Text from Document",
"type": "main",
"index": 0
}
]
]
},
"Normalize Content and Metadata": {
"main": [
[
{
"node": "Generate SOP Structure",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Model for SOP Structure": {
"ai_languageModel": [
[
{
"node": "Generate SOP Structure",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"New or Updated Document Trigger": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Refine for Clarity and Consistency": {
"main": [
[
{
"node": "Check Quality Threshold",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleDriveOAuth2ApigoogleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically converts unstructured internal documentation into clear, actionable Standard Operating Procedures (SOPs).
Source: https://n8n.io/workflows/12799/ — 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.
Who is this for? Agencies, consultants, and service providers who conduct discovery calls and need to quickly turn conversations into professional proposals.
This comprehensive n8n workflow automates the entire Meta (Facebook/Instagram) advertising process, from asset analysis to ad creation. It combines AI-powered content analysis with automated ad deploy
Transcript Evalu8r V2 is a robust browser-based transcript analysis tool powered by Deepgram’s speech-to-text API and built into an n8n workflow template. This release introduces full in-browser audio
Transcript Evalu8r is an AI-powered transcript analysis workflow that automates the processing, visualization, and evaluation of transcribed conversations. This n8n workflow template is designed to he
Enterprise-grade resume screening automation built for production environments. This workflow combines intelligent AI analysis with comprehensive error handling to ensure reliable processing of candid