diff --git a/A Very Simple _Human in the Loop_ Email Response System Using AI and IMAP.txt b/A Very Simple _Human in the Loop_ Email Response System Using AI and IMAP.txt new file mode 100644 index 0000000..8a1a23e --- /dev/null +++ b/A Very Simple _Human in the Loop_ Email Response System Using AI and IMAP.txt @@ -0,0 +1,436 @@ +{ +"id": "Nvn78tMRNnKji7Fg", +"meta": { +"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462", +"templateCredsSetupCompleted": true +}, +"name": "Very simple Human in the loop system email with AI e IMAP", +"tags": [], +"nodes": [ +{ +"id": "271bb16f-9b62-41d9-ab76-114cd7ba915a", +"name": "Email Trigger (IMAP)", +"type": "n8n-nodes-base.emailReadImap", +"position": [ +-1300, +1340 +], +"parameters": { +"options": {} +}, +"credentials": { +"imap": { +"id": "k31W9oGddl9pMDy4", +"name": "IMAP info@n3witalia.com" +} +}, +"typeVersion": 2 +}, +{ +"id": "42d150d8-d574-49f9-9c0e-71a2cdea3b79", +"name": "Markdown", +"type": "n8n-nodes-base.markdown", +"position": [ +-1040, +1340 +], +"parameters": { +"html": "={{ $json.textHtml }}", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "e9498a60-0078-4581-b269-7ff552f4047a", +"name": "Send Email", +"type": "n8n-nodes-base.emailSend", +"position": [ +920, +1320 +], +"webhookId": "a79ae1b4-648c-4cb4-b6cd-04ea3c1d9314", +"parameters": { +"html": "={{ $('Set Email text').item.json.email }}", +"options": {}, +"subject": "=Re: {{ $('Email Trigger (IMAP)').item.json.subject }}", +"toEmail": "={{ $('Email Trigger (IMAP)').item.json.from }}", +"fromEmail": "={{ $('Email Trigger (IMAP)').item.json.to }}" +}, +"credentials": { +"smtp": { +"id": "hRjP3XbDiIQqvi7x", +"name": "SMTP info@n3witalia.com" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "ab9f6ac3-2095-44df-aeba-2eab96ecf425", +"name": "Email Summarization Chain", +"type": "@n8n/n8n-nodes-langchain.chainSummarization", +"position": [ +-780, +1340 +], +"parameters": { +"options": { +"binaryDataKey": "={{ $json.data }}", +"summarizationMethodAndPrompts": { +"values": { +"prompt": "=Write a concise summary of the following in max 100 words:\n\n\"{{ $json.data }}\"\n\nDo not enter the total number of words used.", +"combineMapPrompt": "=Write a concise summary of the following in max 100 words:\n\n\"{{ $json.data }}\"\n\nDo not enter the total number of words used." +} +} +}, +"operationMode": "nodeInputBinary" +}, +"typeVersion": 2 +}, +{ +"id": "86b7c3d0-e1f2-4e2f-b293-8042700d6816", +"name": "Write email", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +-340, +1340 +], +"parameters": { +"text": "=Write the text to reply to the following email:\n\n{{ $json.response.text }}", +"options": { +"systemMessage": "You are an expert at answering emails. You need to answer them professionally based on the information you have. This is a business email. Be concise and never exceed 100 words. Only the body of the email, not create the subject" +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.7 +}, +{ +"id": "5d5a397f-f9c3-4691-afd0-9a6102679eac", +"name": "OpenAI", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-400, +1560 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini", +"cachedResultName": "gpt-4o-mini" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "5b36a295-fda6-4174-9078-0a8ec57620d2", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-800, +1260 +], +"parameters": { +"width": 320, +"height": 240, +"content": "Chain that summarizes the received email" +}, +"typeVersion": 1 +}, +{ +"id": "7110fe1f-0099-49aa-9095-96e733aa468f", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-360, +1260 +], +"parameters": { +"width": 340, +"height": 240, +"content": "Agent that retrieves business information from a vector database and processes the response" +}, +"typeVersion": 1 +}, +{ +"id": "e2bdbd64-3c37-4867-ae2c-0f6937d82b81", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1100, +1260 +], +"parameters": { +"height": 240, +"content": "Convert email to Markdown format for better understanding of LLM models" +}, +"typeVersion": 1 +}, +{ +"id": "8ae5d216-5897-4c33-800a-27ff939b174a", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +620, +1300 +], +"parameters": { +"height": 180, +"content": "If the feedback is OK send email" +}, +"typeVersion": 1 +}, +{ +"id": "4cfce63c-5931-45c5-99ca-eb85dca962b5", +"name": "Approve Email", +"type": "n8n-nodes-base.emailSend", +"position": [ +380, +1340 +], +"webhookId": "4f9f06e7-9b2b-4896-9b51-245972341d12", +"parameters": { +"message": "=

MESSAGE

\n{{ $('Email Trigger (IMAP)').item.json.textHtml }}\n\n

AI RESPONSE

\n{{ $json.email }}", +"options": {}, +"subject": "=[Approval Required] {{ $('Email Trigger (IMAP)').item.json.subject }}", +"toEmail": "info@n3witalia.com", +"fromEmail": "info@n3witalia.com", +"operation": "sendAndWait" +}, +"credentials": { +"smtp": { +"id": "hRjP3XbDiIQqvi7x", +"name": "SMTP info@n3witalia.com" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "d6c8acd2-ebc1-4aaa-bfcc-cdb18fcc8715", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-820, +1560 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "deepseek-chat", +"cachedResultName": "deepseek-chat" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "97Cz4cqyiy1RdcQL", +"name": "DeepSeek" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "33bbedeb-129a-4e99-ab5a-9e0ec4456156", +"name": "Set Email text", +"type": "n8n-nodes-base.set", +"position": [ +100, +1340 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "35d7c303-42f4-4dd1-b41e-6eb087c23c3d", +"name": "email", +"type": "string", +"value": "={{ $json.output }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "2293e0e6-4f2a-4622-a610-64b65f34e1e5", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +320, +1300 +], +"parameters": { +"height": 180, +"content": "Human in the loop" +}, +"typeVersion": 1 +}, +{ +"id": "510196ec-adaf-4e6c-aac0-8ca8b754438a", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1100, +940 +], +"parameters": { +"color": 3, +"width": 540, +"height": 260, +"content": "# How it works\nThis workflow automates the handling of incoming emails, summarizes their content, generates appropriate responses and validate it through send IMAP email with \"Human in the loop\" system. \n\nYou can quickly integrate Gmail and Outlook via the appropriate nodes" +}, +"typeVersion": 1 +}, +{ +"id": "c4c9157d-4d05-47a1-a5eb-63865e838d39", +"name": "Approved?", +"type": "n8n-nodes-base.if", +"position": [ +680, +1340 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "62e26bc5-1732-4699-a602-99490c7406fd", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.data.approved }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "47e79286-00f4-48e8-a0d1-e0f56d9ba0d5", +"connections": { +"OpenAI": { +"ai_languageModel": [ +[ +{ +"node": "Write email", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Markdown": { +"main": [ +[ +{ +"node": "Email Summarization Chain", +"type": "main", +"index": 0 +} +] +] +}, +"Approved?": { +"main": [ +[ +{ +"node": "Send Email", +"type": "main", +"index": 0 +} +], +[] +] +}, +"Write email": { +"main": [ +[ +{ +"node": "Set Email text", +"type": "main", +"index": 0 +} +] +] +}, +"Approve Email": { +"main": [ +[ +{ +"node": "Approved?", +"type": "main", +"index": 0 +} +] +] +}, +"Set Email text": { +"main": [ +[ +{ +"node": "Approve Email", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Email Summarization Chain", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Email Trigger (IMAP)": { +"main": [ +[ +{ +"node": "Markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Email Summarization Chain": { +"main": [ +[ +{ +"node": "Write email", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Auto-Tag Blog Posts in WordPress with AI.txt b/Auto-Tag Blog Posts in WordPress with AI.txt new file mode 100644 index 0000000..59cd713 --- /dev/null +++ b/Auto-Tag Blog Posts in WordPress with AI.txt @@ -0,0 +1,913 @@ +{ +"id": "siXUnQhJpCJ9rHzu", +"meta": { +"instanceId": "a9f3b18652ddc96459b459de4fa8fa33252fb820a9e5a1593074f3580352864a", +"templateCredsSetupCompleted": true +}, +"name": "Auto-Tag Blog Posts in WordPress with AI", +"tags": [ +{ +"id": "ijuVOmJpw5mCrzQX", +"name": "marketing", +"createdAt": "2025-01-28T16:42:03.029Z", +"updatedAt": "2025-01-28T16:42:03.029Z" +} +], +"nodes": [ +{ +"id": "0561d80b-f360-4a8e-930d-49b778833991", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +3260, +480 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "yWpagxp5s8o3dlBp", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "d71aec64-299c-4258-8eb4-95821d15b758", +"name": "Auto-fixing Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing", +"position": [ +3460, +540 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "1468a001-ca7b-4726-ae31-02b28d78b07e", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +3360, +680 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "yWpagxp5s8o3dlBp", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "bb4221ad-94d7-4543-850f-87b83735d2a6", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +3560, +760 +], +"parameters": { +"jsonSchemaExample": "{\n\t\"tags\": [\"Germany\", \"Technology\", \"Workflow Automation\"]\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "2380c4ea-d804-45b2-8341-417afa2ae21f", +"name": "RSS Feed Trigger", +"type": "n8n-nodes-base.rssFeedReadTrigger", +"position": [ +3140, +320 +], +"parameters": { +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "782e9c61-7d51-499b-89b2-888415c5116e", +"name": "Return article details", +"type": "n8n-nodes-base.set", +"position": [ +4140, +320 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "ebe28fc7-f166-4428-b3f3-b319f2d080df", +"name": "tag_ids", +"type": "array", +"value": "={{ $json.tag_ids }}" +}, +{ +"id": "bc296683-2a93-42b4-a9a7-90a2bc22f37b", +"name": "title", +"type": "string", +"value": "={{ $('MOCK article').item.json.title }}" +}, +{ +"id": "32dc0950-3708-447e-a3b6-a5c5ae9bdcd0", +"name": "content", +"type": "string", +"value": "={{ $('MOCK article').item.json.content }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "6b5ce61f-8351-40ab-9e63-51c3e85ce53d", +"name": "Split Out", +"type": "n8n-nodes-base.splitOut", +"position": [ +2200, +840 +], +"parameters": { +"options": { +"destinationFieldName": "missing_tag" +}, +"fieldToSplitOut": "missing_tags" +}, +"typeVersion": 1 +}, +{ +"id": "2338e3e8-cba4-48c8-8c1a-50019af70932", +"name": "Loop over articles", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +1980, +320 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "39b89004-6032-4d22-8bcc-3dfd1d793ed0", +"name": "SET initial record", +"type": "n8n-nodes-base.set", +"position": [ +2200, +440 +], +"parameters": { +"options": {}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "ec0b93cb-de9d-41be-9d4b-6846d3ee14a2", +"name": "GET WP tags", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2440, +440 +], +"parameters": { +"url": "https://www.example.com/wp-json/wp/v2/tags", +"options": {}, +"authentication": "predefinedCredentialType", +"nodeCredentialType": "wordpressApi" +}, +"credentials": { +"wordpressApi": { +"id": "XXXXXXX", +"name": "Example" +} +}, +"executeOnce": true, +"typeVersion": 4.2, +"alwaysOutputData": true +}, +{ +"id": "cbabadef-9f5f-4402-8bd7-255f5c237ff9", +"name": "POST WP tags", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2420, +840 +], +"parameters": { +"url": "https://www.example.com/wp-json/wp/v2/tags", +"method": "POST", +"options": {}, +"sendQuery": true, +"authentication": "predefinedCredentialType", +"queryParameters": { +"parameters": [ +{ +"name": "slug", +"value": "={{ $json.missing_tag }}" +}, +{ +"name": "name", +"value": "={{ $json.missing_tag.replaceAll(\"-\",\" \").toTitleCase() }}" +} +] +}, +"nodeCredentialType": "wordpressApi" +}, +"credentials": { +"wordpressApi": { +"id": "XXXXXXX", +"name": "Example" +} +}, +"executeOnce": false, +"typeVersion": 4.2 +}, +{ +"id": "6bf40d39-4b42-413f-9502-3ca494f75bcb", +"name": "GET updated WP tags", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2700, +840 +], +"parameters": { +"url": "https://www.example.com/wp-json/wp/v2/tags", +"options": {}, +"authentication": "predefinedCredentialType", +"nodeCredentialType": "wordpressApi" +}, +"credentials": { +"wordpressApi": { +"id": "XXXXXXX", +"name": "Example" +} +}, +"executeOnce": true, +"typeVersion": 4.2 +}, +{ +"id": "aea9a631-0cd8-4ed8-9fb1-981b8e11f3dd", +"name": "Keep matches", +"type": "n8n-nodes-base.filter", +"position": [ +2200, +1040 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "8ec4fdfc-73f3-4d7b-96e4-f42a18252599", +"operator": { +"type": "array", +"operation": "contains", +"rightType": "any" +}, +"leftValue": "={{ $('SET initial record').first().json.tags.map(item => item.toLowerCase().replaceAll(\" \",\"-\")) }}", +"rightValue": "={{ $json.slug }}" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "6d71d7a5-495d-4809-b66f-9f1cba0d11c6", +"name": "Combine tag_ids", +"type": "n8n-nodes-base.aggregate", +"position": [ +2420, +1040 +], +"parameters": { +"options": {}, +"fieldsToAggregate": { +"fieldToAggregate": [ +{ +"renameField": true, +"outputFieldName": "tag_ids", +"fieldToAggregate": "id" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "dc3cac68-dee8-4821-963b-b0594d1a7e0e", +"name": "Combine slugs", +"type": "n8n-nodes-base.aggregate", +"position": [ +2700, +440 +], +"parameters": { +"options": {}, +"fieldsToAggregate": { +"fieldToAggregate": [ +{ +"renameField": true, +"outputFieldName": "tags", +"fieldToAggregate": "slug" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "8e0f668c-e3ac-4d70-9ffb-5515e6221c62", +"name": "If", +"type": "n8n-nodes-base.if", +"position": [ +2440, +640 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "8d77d072-cb47-4fbb-831a-0e6f3ecefc71", +"operator": { +"type": "array", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $json.missing_tags }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "7988188d-07e6-4a36-94f2-e21d7677802e", +"name": "MOCK article", +"type": "n8n-nodes-base.set", +"position": [ +3740, +320 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "4a69cf1b-341a-40bc-a36a-b76c05bdd819", +"name": "title", +"type": "string", +"value": "={{ $('RSS Feed Trigger').item.json.title }}" +}, +{ +"id": "63097eb0-6165-4365-a5b5-e9f3de65d715", +"name": "content", +"type": "string", +"value": "={{ $('RSS Feed Trigger').item.json.content }}" +}, +{ +"id": "ae4859ec-ad14-403e-b5b6-53703fefe3f3", +"name": "categories", +"type": "array", +"value": "={{ $('RSS Feed Trigger').item.json.categories }}" +}, +{ +"id": "3f94d5ac-5196-4ad0-acea-79c07b0ee2c6", +"name": "tags", +"type": "array", +"value": "={{ $json.output.tags }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "4578cb14-dc86-4bc4-8d59-f0c088574164", +"name": "Return missing tags", +"type": "n8n-nodes-base.code", +"position": [ +2200, +640 +], +"parameters": { +"jsCode": "const new_ary = $('SET initial record').first().json.tags.map(x => x.toLowerCase().replaceAll(\" \",\"-\")).filter(x => !$input.first().json.tags.includes(x))\n\nreturn {\"missing_tags\": new_ary};" +}, +"typeVersion": 2 +}, +{ +"id": "91c8dde5-58ce-4bf6-ac3c-0062cbf0046e", +"name": "Wordpress", +"type": "n8n-nodes-base.wordpress", +"position": [ +4360, +320 +], +"parameters": { +"title": "=Demo tagging post: {{ $json.title }}", +"additionalFields": { +"tags": "={{ $json.tag_ids }}", +"content": "=This is a post to demo automatic tagging a WordPress postvia n8n. The following content could be rewritten in full or part with commentary using AI.\n\n{{ $json.content }}" +} +}, +"credentials": { +"wordpressApi": { +"id": "XXXXXXX", +"name": "Example" +} +}, +"typeVersion": 1 +}, +{ +"id": "8257534e-f433-4225-a795-230fd367cc01", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3000, +200 +], +"parameters": { +"color": 7, +"width": 1673.0029952487134, +"height": 1061.6563737812796, +"content": "## Demo Usage in Another Workflow (Tagging an article discovered with an RSS feed)" +}, +"typeVersion": 1 +}, +{ +"id": "b14e6fda-c569-4ada-90d9-77b61049c531", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1680, +198.96245932022566 +], +"parameters": { +"color": 7, +"width": 1243.102096674096, +"height": 1077.24135750937, +"content": "## Auto-Tag Posts in WordPress\n\nThis workflow allows you to hand off the responsibility of tagging content for WordPress to an AI Agent in n8n with no data entry required." +}, +"typeVersion": 1 +}, +{ +"id": "21420d0f-a5c9-4eac-b6d9-06d3a6de5fb9", +"name": "Demo Usage in Another Workflow", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +1780, +320 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "7571b196-3827-478f-b032-84d99adf4aa8", +"name": "Auto-Tag Posts in WordPress", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +3940, +320 +], +"parameters": { +"mode": "each", +"options": {}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "siXUnQhJpCJ9rHzu" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "e5b63f63-09a6-452d-9d26-8501fc49d7fe", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2640, +140 +], +"parameters": { +"color": 5, +"width": 256.62869115182394, +"height": 146.4958582739091, +"content": "## Copy this workflow\n\nYou can use it inline by removing the Called by Another Workflow trigger, or as-is as a subworkflow" +}, +"typeVersion": 1 +}, +{ +"id": "2ea9fbdd-b492-4030-b640-227a163d70ef", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3040, +980 +], +"parameters": { +"width": 409.8780943583022, +"height": 248.2919292392927, +"content": "Handing off tagging and categorization fully to AI lets you **put your WordPress account on autopilot** without a human-in-the-loop.\n\nIn this example the application is use-case agnostic, but with this workflow you can:\n1. Use AI to rewrite content with original thoughts and tags\n2. Ensure healthy information architecture on your site\n3. Quickly generate multivariate tag and category combinations for optimal SEO" +}, +"typeVersion": 1 +}, +{ +"id": "57cfa462-fc71-4173-b7c9-8253c4e240d1", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3900, +500 +], +"parameters": { +"color": 3, +"width": 369.61896876326364, +"height": 103.91486928512641, +"content": "### To ensure data can be passed to subsequent nodes, make sure to select \"Run Once for Each Item\" if executing a subworkflow" +}, +"typeVersion": 1 +}, +{ +"id": "7f1dfade-07be-49b7-b5ee-99b58f1e6cc7", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2640, +660 +], +"parameters": { +"color": 6, +"width": 211.8330719827787, +"content": "## What's this? \nIf there are missing tags we create them in WP, otherwise we keep get them all from WP and keep the relevant ones." +}, +"typeVersion": 1 +}, +{ +"id": "61711c71-3e45-4b06-80a8-b651177b585d", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1960, +540 +], +"parameters": { +"color": 3, +"width": 174.33565557367925, +"height": 251.80401948434695, +"content": "## What's this? \nOne of the few potential failure points in this workflow, when checking for missing tags it's important that both the generated tags and the existing tags are in the same case (snake, dash, title)." +}, +"typeVersion": 1 +}, +{ +"id": "31db85c9-e4c2-4409-9d92-7eb005223de0", +"name": "Generate tags for article", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +3360, +320 +], +"parameters": { +"text": "=Please provide 3-5 suitable tags for the following article:\n\n{{ $json.content }}\n\nTag Formatting Rules:\n1. Tags should be in title case", +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.4 +}, +{ +"id": "7d6eac92-6f6f-44a4-8dce-0830440a9dff", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1600, +1040 +], +"parameters": { +"width": 285.2555025627061, +"content": "## ! A note about cases !\nIf you want your tags to follow a different case than I am using (dash case for slug, title case for name), then you will need to update a few nodes in this workflow." +}, +"typeVersion": 1 +}, +{ +"id": "133be2f7-071b-4651-b3b5-8052a64b7f49", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2600, +1200 +], +"parameters": { +"color": 5, +"width": 296.01271681531176, +"content": "## Ready for a challenge?\n\nMake this subworkflow executable for both categories and tags, accounting for different API calls to different endpoints." +}, +"typeVersion": 1 +}, +{ +"id": "7807e967-ac3d-4a4d-bd9d-f123d57e1676", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4400, +1155.7364351382535 +], +"parameters": { +"color": 4, +"width": 244.3952545193282, +"height": 87.34661077350344, +"content": "## About the maker\n**[Find Ludwig Gerdes on LinkedIn](https://www.linkedin.com/in/ludwiggerdes)**" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": { +"Generate tags for article": [ +{ +"json": { +"output": { +"tags": [ +"Team Achievements", +"Global Community", +"Product Growth", +"2024 Highlights", +"Reflecting on Progress" +] +} +} +} +] +}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "3acdf19c-288e-4a3b-87ae-5adbf44285fe", +"connections": { +"If": { +"main": [ +[ +{ +"node": "GET updated WP tags", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Split Out", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out": { +"main": [ +[ +{ +"node": "POST WP tags", +"type": "main", +"index": 0 +} +] +] +}, +"GET WP tags": { +"main": [ +[ +{ +"node": "Combine slugs", +"type": "main", +"index": 0 +} +] +] +}, +"Keep matches": { +"main": [ +[ +{ +"node": "Combine tag_ids", +"type": "main", +"index": 0 +} +] +] +}, +"MOCK article": { +"main": [ +[ +{ +"node": "Auto-Tag Posts in WordPress", +"type": "main", +"index": 0 +} +] +] +}, +"POST WP tags": { +"main": [ +[ +{ +"node": "GET updated WP tags", +"type": "main", +"index": 0 +} +] +] +}, +"Combine slugs": { +"main": [ +[ +{ +"node": "Return missing tags", +"type": "main", +"index": 0 +} +] +] +}, +"Combine tag_ids": { +"main": [ +[ +{ +"node": "Loop over articles", +"type": "main", +"index": 0 +} +] +] +}, +"RSS Feed Trigger": { +"main": [ +[ +{ +"node": "Generate tags for article", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Generate tags for article", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Loop over articles": { +"main": [ +[], +[ +{ +"node": "SET initial record", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"SET initial record": { +"main": [ +[ +{ +"node": "GET WP tags", +"type": "main", +"index": 0 +} +] +] +}, +"GET updated WP tags": { +"main": [ +[ +{ +"node": "Keep matches", +"type": "main", +"index": 0 +} +] +] +}, +"Return missing tags": { +"main": [ +[ +{ +"node": "If", +"type": "main", +"index": 0 +} +] +] +}, +"Return article details": { +"main": [ +[ +{ +"node": "Wordpress", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Auto-fixing Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Generate tags for article", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Generate tags for article": { +"main": [ +[ +{ +"node": "MOCK article", +"type": "main", +"index": 0 +} +] +] +}, +"Auto-Tag Posts in WordPress": { +"main": [ +[ +{ +"node": "Return article details", +"type": "main", +"index": 0 +} +] +] +}, +"Demo Usage in Another Workflow": { +"main": [ +[ +{ +"node": "Loop over articles", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Auto-label incoming Gmail messages with AI nodes.txt b/Auto-label incoming Gmail messages with AI nodes.txt new file mode 100644 index 0000000..badbfe4 --- /dev/null +++ b/Auto-label incoming Gmail messages with AI nodes.txt @@ -0,0 +1,475 @@ +{ +"nodes": [ +{ +"id": "8141ffad-df2a-403b-a869-799c036f9733", +"name": "Gmail trigger", +"type": "n8n-nodes-base.gmailTrigger", +"position": [ +-600, +580 +], +"parameters": { +"simple": false, +"filters": {}, +"options": {}, +"pollTimes": { +"item": [ +{ +"mode": "everyMinute" +} +] +} +}, +"credentials": { +"gmailOAuth2": { +"id": "uBcIMfsTtKjexw7I", +"name": "Gmail (workfloowstutorial@gmail.com)" +} +}, +"typeVersion": 1 +}, +{ +"id": "6d9aa398-e2de-4fd0-b939-2a12d0c9fe14", +"name": "Get message content", +"type": "n8n-nodes-base.gmail", +"position": [ +-340, +580 +], +"parameters": { +"simple": false, +"options": {}, +"messageId": "={{ $json.id }}", +"operation": "get" +}, +"credentials": { +"gmailOAuth2": { +"id": "uBcIMfsTtKjexw7I", +"name": "Gmail (workfloowstutorial@gmail.com)" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "cd86bc09-8c7f-4c85-9cb3-6dbd42420672", +"name": "Set label values", +"type": "n8n-nodes-base.set", +"position": [ +300, +580 +], +"parameters": { +"fields": { +"values": [ +{ +"name": "labels", +"type": "arrayValue", +"arrayValue": "={{ $json.labels }}" +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "329435a6-51d1-416e-9aa9-5fe9a8dce74f", +"name": "Get all labels", +"type": "n8n-nodes-base.gmail", +"position": [ +580, +460 +], +"parameters": { +"resource": "label", +"returnAll": true +}, +"credentials": { +"gmailOAuth2": { +"id": "uBcIMfsTtKjexw7I", +"name": "Gmail (workfloowstutorial@gmail.com)" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "7ae2dd15-472d-4a4b-b036-f80ebd7e3c28", +"name": "Split out assigned labels", +"type": "n8n-nodes-base.splitOut", +"position": [ +580, +700 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "labels" +}, +"typeVersion": 1 +}, +{ +"id": "744c7afa-75b1-4b3b-8ccb-e2106c01f387", +"name": "Merge corresponding labels", +"type": "n8n-nodes-base.merge", +"position": [ +860, +580 +], +"parameters": { +"mode": "combine", +"options": {}, +"mergeByFields": { +"values": [ +{ +"field1": "name", +"field2": "labels" +} +] +}, +"outputDataFrom": "input1" +}, +"typeVersion": 2.1 +}, +{ +"id": "e47424dc-f43e-41a9-b1e5-ab3e08cbf395", +"name": "Aggregate label IDs", +"type": "n8n-nodes-base.aggregate", +"position": [ +1120, +580 +], +"parameters": { +"options": {}, +"fieldsToAggregate": { +"fieldToAggregate": [ +{ +"renameField": true, +"outputFieldName": "label_ids", +"fieldToAggregate": "id" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "22ba8297-8efc-463e-8ae0-385fd94a205f", +"name": "Add labels to message", +"type": "n8n-nodes-base.gmail", +"position": [ +1340, +580 +], +"parameters": { +"labelIds": "={{ $json.label_ids }}", +"messageId": "={{ $('Gmail trigger').item.json[\"id\"] }}", +"operation": "addLabels" +}, +"credentials": { +"gmailOAuth2": { +"id": "uBcIMfsTtKjexw7I", +"name": "Gmail (workfloowstutorial@gmail.com)" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "7ebb1aad-00ad-43fa-9e07-e5f324864a74", +"name": "Assign labels for message", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +-80, +580 +], +"parameters": { +"prompt": "={{ $json.text }}", +"messages": { +"messageValues": [ +{ +"message": "Your task is to categorize the message according to the following labels.\n\nPartnership - email about sponsored content, cooperation etc.\nInquiry - email about products, services.\nNotification - email that doesn't require response. \n\nOne email can have more than one label. Return only label names in JSON format, nothing else. Do not make things up. " +} +] +} +}, +"typeVersion": 1.3 +}, +{ +"id": "2f82db6a-422c-4697-a629-cc782d88209d", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1100, +400 +], +"parameters": { +"color": 4, +"width": 420.4803040774015, +"height": 240.57943708322733, +"content": "## Add AI labels to Gmail messages\nWith this workflow you can automatically set labels for your Gmail message according to its content. \n\nIn this workflow available are 3 labels: \"Partnership\", \"Inquiry\" and \"Notification\". Feel free to adjust labels according to your needs. \n\n**Please remember to set label names both in your Gmail account and workflow.**" +}, +"typeVersion": 1 +}, +{ +"id": "4a10fb2b-aebb-4735-bbdb-7f07f1136d95", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1100, +660 +], +"parameters": { +"width": 421.0932411886662, +"height": 257.42916378714597, +"content": "## ⚠️ Note\n\n1. Complete video guide for this workflow is available [on my YouTube](https://youtu.be/a8Dhj3Zh9vQ). \n2. Remember to add your credentials and configure nodes (covered in the video guide).\n3. If you like this workflow, please subscribe to [my YouTube channel](https://www.youtube.com/@workfloows) and/or [my newsletter](https://workfloows.com/).\n\n**Thank you for your support!**" +}, +"typeVersion": 1 +}, +{ +"id": "76e62351-d502-4377-9df2-fe92df00fe03", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-660, +400 +], +"parameters": { +"width": 238.4602598584674, +"height": 348.5873725349161, +"content": "### Gmail Trigger\nReceive data from Gmail about new incoming message. \n\n⚠️ Set polling interval according to your needs." +}, +"typeVersion": 1 +}, +{ +"id": "c10702db-211f-4638-bcf0-fbbe18251cb7", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +60, +780 +], +"parameters": { +"width": 241.53974014153226, +"height": 319.3323098457962, +"content": "###\n\n\n\n\n\n\n\n\n\n\n### JSON schema\nEdit JSON schema and label names according to your needs.\n\n⚠️ **Label names in system prompt and JSON schema should be the same.**" +}, +"typeVersion": 1 +}, +{ +"id": "cb6e3573-3d4d-4313-a97e-86a017438399", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +800, +420 +], +"parameters": { +"width": 226.14233872620645, +"height": 347.0476323933831, +"content": "### Merge labels\nCombine labels retrieved from Gmail account and assigned by AI together." +}, +"typeVersion": 1 +}, +{ +"id": "8cfb4341-98e6-4944-b26c-15e39184f468", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1060, +420 +], +"parameters": { +"width": 452.48413953150185, +"height": 347.0476323933831, +"content": "### Aggregarte labels and add to message\nCreate array of label IDs and add to the desired email message in Gmail." +}, +"typeVersion": 1 +}, +{ +"id": "bb9766e8-0b72-47f8-9a8e-0b291609e814", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-400, +400 +], +"parameters": { +"width": 238.4602598584674, +"height": 348.5873725349161, +"content": "### Get message content\nBased on Gmail message ID retrieve body content of the email and pass it to AI chain." +}, +"typeVersion": 1 +}, +{ +"id": "48630cbd-8336-4577-928e-37341f09ef9b", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-140, +400 +], +"parameters": { +"width": 378.57661273793565, +"height": 348.5873725349161, +"content": "### Assign labels\nLet the AI decide which labels suit the best content of the message.\n\n⚠️ **Remember to edit system prompt** - modify label names and instructions according to your needs." +}, +"typeVersion": 1 +}, +{ +"id": "60a9d75e-1564-4b1d-b3f2-acc2e3bf2411", +"name": "JSON Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +140, +800 +], +"parameters": { +"jsonSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"labels\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\"Inquiry\", \"Partnership\", \"Notification\"]\n }\n }\n },\n \"required\": [\"labels\"]\n}\n" +}, +"typeVersion": 1 +}, +{ +"id": "2bdf3fed-8a7f-411a-bad4-266bfea5cede", +"name": "OpenAI Chat", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +-120, +800 +], +"parameters": { +"model": "gpt-4-turbo-preview", +"options": { +"temperature": 0, +"responseFormat": "json_object" +} +}, +"credentials": { +"openAiApi": { +"id": "jazew1WAaSRrjcHp", +"name": "OpenAI (workfloows@gmail.com)" +} +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"connections": { +"JSON Parser": { +"ai_outputParser": [ +[ +{ +"node": "Assign labels for message", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"OpenAI Chat": { +"ai_languageModel": [ +[ +{ +"node": "Assign labels for message", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Gmail trigger": { +"main": [ +[ +{ +"node": "Get message content", +"type": "main", +"index": 0 +} +] +] +}, +"Get all labels": { +"main": [ +[ +{ +"node": "Merge corresponding labels", +"type": "main", +"index": 0 +} +] +] +}, +"Set label values": { +"main": [ +[ +{ +"node": "Get all labels", +"type": "main", +"index": 0 +}, +{ +"node": "Split out assigned labels", +"type": "main", +"index": 0 +} +] +] +}, +"Aggregate label IDs": { +"main": [ +[ +{ +"node": "Add labels to message", +"type": "main", +"index": 0 +} +] +] +}, +"Get message content": { +"main": [ +[ +{ +"node": "Assign labels for message", +"type": "main", +"index": 0 +} +] +] +}, +"Assign labels for message": { +"main": [ +[ +{ +"node": "Set label values", +"type": "main", +"index": 0 +} +] +] +}, +"Split out assigned labels": { +"main": [ +[ +{ +"node": "Merge corresponding labels", +"type": "main", +"index": 1 +} +] +] +}, +"Merge corresponding labels": { +"main": [ +[ +{ +"node": "Aggregate label IDs", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Blog Creation in Brand Voice with AI.txt b/Automate Blog Creation in Brand Voice with AI.txt new file mode 100644 index 0000000..1109cc8 --- /dev/null +++ b/Automate Blog Creation in Brand Voice with AI.txt @@ -0,0 +1,691 @@ +{ +"nodes": [ +{ +"id": "d3159589-dbb7-4cca-91f5-09e8b2e4cba8", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +240, +500 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "b4b42b3f-ef30-4fc8-829d-59f8974c4168", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2180, +700 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "032c3012-ed8d-44eb-94f0-35790f4b616f", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2980, +460 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "bf922785-7e8f-4f93-bfff-813c16d93278", +"name": "OpenAI Chat Model2", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2020, +520 +], +"parameters": { +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "d8d4b26f-270f-4b39-a4cd-a6e4361da591", +"name": "Extract Voice Characteristics", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +2160, +540 +], +"parameters": { +"text": "=### Analyse the given content\n\n{{ $json.data.map(item => item.replace(/\\n/g, '')).join('\\n---\\n') }}", +"options": { +"systemPromptTemplate": "You help identify and define a company or individual's \"brand voice\". Using the given content belonging to the company or individual, extract all voice characteristics from it along with description and examples demonstrating it." +}, +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"array\",\n \"items\": {\n \"type\": \"object\",\n \t\"properties\": {\n \"characteristic\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" },\n \"examples\": { \"type\": \"array\", \"items\": { \"type\": \"string\" } }\n }\n\t}\n}" +}, +"typeVersion": 1 +}, +{ +"id": "8cca272c-b912-40f1-ba08-aa7c5ff7599c", +"name": "Get Blog", +"type": "n8n-nodes-base.httpRequest", +"position": [ +480, +500 +], +"parameters": { +"url": "https://blog.n8n.io", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "aa1e2a02-2e2b-4e8d-aef8-f5f7a54d9562", +"name": "Get Article", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1120, +500 +], +"parameters": { +"url": "=https://blog.n8n.io{{ $json.article }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "78ae3dfc-5afd-452f-a2b6-bdb9dbd728bd", +"name": "Extract Article URLs", +"type": "n8n-nodes-base.html", +"position": [ +640, +500 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"extractionValues": { +"values": [ +{ +"key": "article", +"attribute": "href", +"cssSelector": ".item.post a.global-link", +"returnArray": true, +"returnValue": "attribute" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "3b2b6fea-ed2f-43ba-b6d1-e0666b88c65b", +"name": "Split Out URLs", +"type": "n8n-nodes-base.splitOut", +"position": [ +800, +500 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "article" +}, +"typeVersion": 1 +}, +{ +"id": "68bb20b1-2177-4c0f-9ada-d1de69bdc2a0", +"name": "Latest Articles", +"type": "n8n-nodes-base.limit", +"position": [ +960, +500 +], +"parameters": { +"maxItems": 5 +}, +"typeVersion": 1 +}, +{ +"id": "f20d7393-24c9-4a51-872e-0dce391f661c", +"name": "Extract Article Content", +"type": "n8n-nodes-base.html", +"position": [ +1280, +500 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"extractionValues": { +"values": [ +{ +"key": "data", +"cssSelector": ".post-section", +"returnValue": "html" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "299a04be-fe9b-47d9-b2c6-e2e4628f77e0", +"name": "Combine Articles", +"type": "n8n-nodes-base.aggregate", +"position": [ +1780, +540 +], +"parameters": { +"options": { +"mergeLists": true +}, +"fieldsToAggregate": { +"fieldToAggregate": [ +{ +"fieldToAggregate": "data" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "8480ece7-0dc1-4682-ba9e-ded2c138d8b8", +"name": "Article Style & Brand Voice", +"type": "n8n-nodes-base.merge", +"position": [ +2560, +320 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "024efee2-5a2f-455c-a150-4b9bdce650b2", +"name": "Save as Draft", +"type": "n8n-nodes-base.wordpress", +"position": [ +3460, +320 +], +"parameters": { +"title": "={{ $json.output.title }}", +"additionalFields": { +"slug": "={{ $json.output.title.toSnakeCase() }}", +"format": "standard", +"status": "draft", +"content": "={{ $json.output.body }}" +} +}, +"credentials": { +"wordpressApi": { +"id": "YMW8mGrekjfxKJUe", +"name": "Wordpress account" +} +}, +"typeVersion": 1 +}, +{ +"id": "71f4ab1e-ef61-48f3-92e8-70691f7d0750", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +480, +180 +], +"parameters": { +"color": 7, +"width": 606, +"height": 264, +"content": "## 1. Import Existing Content\n[Read more about the HTML node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.html/)\n\nFirst, we'll need to gather existing content for the brand voice we want to replicate. This content can be blogs, social media posts or internal documents - the idea is to use this content to \"train\" our AI to produce content from the provided examples. One call out is that the quality and consistency of the content is important to get the desired results.\n\nIn this demonstration, we'll grab the latest blog posts off a corporate blog to use as an example. Since, the blog articles are likely consistent because of the source and narrower focus of the medium, it'll serve well to showcase this workflow." +}, +"typeVersion": 1 +}, +{ +"id": "3d3a55a5-4b4a-4ea2-a39c-82b366fb81e6", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1440, +240 +], +"parameters": { +"color": 7, +"width": 434, +"height": 230, +"content": "## 2. Convert HTML to Markdown\n[Learn more about the Markdown node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.markdown)\n\nMarkdown is a great way to optimise the article data we're sending to the LLM because it reduces the amount of tokens required but keeps all relevant writing structure information.\n\nAlso useful to get Markdown output as a response because typically it's the format authors will write in." +}, +"typeVersion": 1 +}, +{ +"id": "08c0b683-ec06-47ce-871c-66265195ca29", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1980, +80 +], +"parameters": { +"color": 7, +"width": 446, +"height": 233, +"content": "## 3. Using AI to Analyse Article Structure and Writing Styles\n[Read more about the Basic LLM Chain node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nOur approach is to first perform a high-level analysis of all available articles in order to replicate their content layout and writing styles. This will act as a guideline to help the AI to structure our future articles." +}, +"typeVersion": 1 +}, +{ +"id": "515fe69f-061e-4dfc-94ed-4cf2fbe10b7b", +"name": "Capture Existing Article Structure", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +2020, +380 +], +"parameters": { +"text": "={{ $json.data.join('\\n---\\n') }}", +"messages": { +"messageValues": [ +{ +"message": "=Given the following one or more articles (which are separated by ---), describe how best one could replicate the common structure, layout, language and writing styles of all as aggregate." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.4 +}, +{ +"id": "ba4e68fb-eccc-4efa-84be-c42a695dccdb", +"name": "Markdown", +"type": "n8n-nodes-base.markdown", +"position": [ +1600, +540 +], +"parameters": { +"html": "={{ $json.data }}", +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "d459ff5b-0375-4458-a49f-59700bb57e12", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2340, +740 +], +"parameters": { +"color": 7, +"width": 446, +"height": 253, +"content": "## 4. Using AI to Extract Voice Characteristics and Traits\n[Read more about the Information Extractor node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor/)\n\nSecond, we'll use AI to analysis the brand voice characteristics of the previous articles. This picks out the tone, style and choice of language used and identifies them into categories. These categories will be used as guidelines for the AI to keep the future article consistent in tone and voice. " +}, +"typeVersion": 1 +}, +{ +"id": "71fe32a9-1b8a-446c-a4ff-fb98c6a68e1b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2720, +0 +], +"parameters": { +"color": 7, +"width": 626, +"height": 633, +"content": "## 5. Automate On-Brand Articles Using AI\n[Read more about the Information Extractor node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor)\n\nFinally with this approach, we can feed both content and voice guidelines into our final LLM - our content generation agent - to produce any number of on-brand articles, social media posts etc.\n\nWhen it comes to assessing the output, note the AI does a pretty good job at simulating format and reusing common phrases and wording for the target article. However, this could become repetitive very quickly! Whilst AI can help speed up the process, a human touch may still be required to add a some variety." +}, +"typeVersion": 1 +}, +{ +"id": "4e6fbe4e-869e-4bef-99ba-7b18740caecf", +"name": "Content Generation Agent", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +3000, +320 +], +"parameters": { +"text": "={{ $json.instruction }}", +"options": { +"systemPromptTemplate": "=You are a blog content writer who writes using the following article guidelines. Write a content piece as requested by the user. Output the body as Markdown. Do not include the date of the article because the publishing date is not determined yet.\n\n## Brand Article Style\n{{ $('Article Style & Brand Voice').item.json.text }}\n\n##n Brand Voice Characteristics\n\nHere are the brand voice characteristic and examples you must adopt in your piece. Pick only the characteristic which make sense for the user's request. Try to keep it as similar as possible but don't copy word for word.\n\n|characteristic|description|examples|\n|-|-|-|\n{{\n$('Article Style & Brand Voice').item.json.output.map(item => (\n`|${item.characteristic}|${item.description}|${item.examples.map(ex => `\"${ex}\"`).join(', ')}|`\n)).join('\\n')\n}}" +}, +"attributes": { +"attributes": [ +{ +"name": "title", +"required": true, +"description": "title of article" +}, +{ +"name": "summary", +"required": true, +"description": "summary of article" +}, +{ +"name": "body", +"required": true, +"description": "body of article" +}, +{ +"name": "characteristics", +"required": true, +"description": "comma delimited string of characteristics chosen" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "022de44c-c06c-41ac-bd50-38173dae9b37", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3460, +480 +], +"parameters": { +"color": 7, +"width": 406, +"height": 173, +"content": "## 6. Save Draft to Wordpress\n[Learn more about the Wordpress node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.wordpress/)\n\nTo close out the template, we'll simple save our generated article as a draft which could allow human team members to review and validate the article before publishing." +}, +"typeVersion": 1 +}, +{ +"id": "fe54c40e-6ddd-45d6-a938-f467e4af3f57", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2900, +660 +], +"parameters": { +"color": 5, +"width": 440, +"height": 120, +"content": "### Q. Do I need to analyse Brand Voice for every article?\nA. No! I would recommend storing the results of the AI's analysis and re-use for a list of planned articles rather than generate anew every time." +}, +"typeVersion": 1 +}, +{ +"id": "1832131e-21e8-44fc-9370-907f7b5a6eda", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1000, +680 +], +"parameters": { +"color": 5, +"width": 380, +"height": 120, +"content": "### Q. Can I use other media than blog articles?\nA. Yes! This approach can use other source materials such as PDFs, as long as they can be produces in a text format to give to the LLM." +}, +"typeVersion": 1 +}, +{ +"id": "8e8706a3-122d-436b-9206-de7a6b2f3c39", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-220, +-120 +], +"parameters": { +"width": 400, +"height": 800, +"content": "## Try It Out!\n### This n8n template demonstrates how to use AI to generate new on-brand written content by analysing previously published content.\n\nWith such an approach, it's possible to generate a steady stream of blog article drafts quickly with high consistency with your brand and existing content.\n\n### How it works\n* In this demonstration, the n8n.io blog is used as the source of existing published content and 5 of the latest articles are imported via the HTTP node.\n* The HTML node is extract the article bodies which are then converted to markdown for our LLMs.\n* We use LLM nodes to (1) understand the article structure and writing style and (2) identify the brand voice characteristics used in the posts.\n* These are then used as guidelines in our final LLM node when generating new articles.\n* Finally, a draft is saved to Wordpress for human editors to review or use as starting point for their own articles.\n\n### How to use\n* Update Step 1 to fetch data from your desired blog or change to fetch existing content in a different way.\n* Update Step 5 to provide your new article instruction. For optimal output, theme topics relevant to your brand.\n\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!" +}, +"typeVersion": 1 +}, +{ +"id": "1510782d-0f88-40ca-99a8-44f984022c8e", +"name": "New Article Instruction", +"type": "n8n-nodes-base.set", +"position": [ +2820, +320 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "2c7e2a28-30f9-4533-a394-a5e967ebf4ec", +"name": "instruction", +"type": "string", +"value": "=Write a comprehensive guide on using AI for document classification and document extraction. Explain the benefits of using vision models over traditional OCR. Close out with a recommendation of using n8n as the preferred way to get started with this AI use-case." +} +] +} +}, +"typeVersion": 3.4 +} +], +"pinData": {}, +"connections": { +"Get Blog": { +"main": [ +[ +{ +"node": "Extract Article URLs", +"type": "main", +"index": 0 +} +] +] +}, +"Markdown": { +"main": [ +[ +{ +"node": "Combine Articles", +"type": "main", +"index": 0 +} +] +] +}, +"Get Article": { +"main": [ +[ +{ +"node": "Extract Article Content", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out URLs": { +"main": [ +[ +{ +"node": "Latest Articles", +"type": "main", +"index": 0 +} +] +] +}, +"Latest Articles": { +"main": [ +[ +{ +"node": "Get Article", +"type": "main", +"index": 0 +} +] +] +}, +"Combine Articles": { +"main": [ +[ +{ +"node": "Capture Existing Article Structure", +"type": "main", +"index": 0 +}, +{ +"node": "Extract Voice Characteristics", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Extract Voice Characteristics", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Content Generation Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model2": { +"ai_languageModel": [ +[ +{ +"node": "Capture Existing Article Structure", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Extract Article URLs": { +"main": [ +[ +{ +"node": "Split Out URLs", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Article Content": { +"main": [ +[ +{ +"node": "Markdown", +"type": "main", +"index": 0 +} +] +] +}, +"New Article Instruction": { +"main": [ +[ +{ +"node": "Content Generation Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Content Generation Agent": { +"main": [ +[ +{ +"node": "Save as Draft", +"type": "main", +"index": 0 +} +] +] +}, +"Article Style & Brand Voice": { +"main": [ +[ +{ +"node": "New Article Instruction", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Voice Characteristics": { +"main": [ +[ +{ +"node": "Article Style & Brand Voice", +"type": "main", +"index": 1 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get Blog", +"type": "main", +"index": 0 +} +] +] +}, +"Capture Existing Article Structure": { +"main": [ +[ +{ +"node": "Article Style & Brand Voice", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Competitor Research with Exa.ai, Notion and AI Agents.txt b/Automate Competitor Research with Exa.ai, Notion and AI Agents.txt new file mode 100644 index 0000000..80cee52 --- /dev/null +++ b/Automate Competitor Research with Exa.ai, Notion and AI Agents.txt @@ -0,0 +1,1359 @@ +{ +"meta": { +"instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" +}, +"nodes": [ +{ +"id": "d26b0190-c683-45fc-ac5b-0654af78f080", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-1000, +-620 +], +"parameters": { +"width": 377.7154173079816, +"height": 511.2813260861502, +"content": "## Try It Out!\n\n### This workflow builds a competitor research agent using Exa.ai as a starting point. The HTTP Request tool is used to demonstrate how you can build powerful agents with minimal effort.\n\n* Using Exa's findSimilar search, we ask it to look for similar companies ie. competitors, to our source company.\n* This list of competitors is sent to 3 agents to scour the internet to find company overview, product offering and customer reviews.\n* A report is then compiled from the output of all 3 agents into a notion table.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!" +}, +"typeVersion": 1 +}, +{ +"id": "747d2f04-1e9c-45bb-b2ad-68da81524f4f", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-520, +-420 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "5cb5f5a1-bc2d-4557-aff4-1993d8dcb99b", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1020, +20 +], +"parameters": { +"model": "gpt-4o-mini", +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "eafe20ab-0385-42e6-abbf-e15126bbb6fa", +"name": "Search Crunchbase", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1320, +20 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"fields": "markdown", +"method": "POST", +"sendBody": true, +"dataField": "data", +"authentication": "genericCredentialType", +"parametersBody": { +"values": [ +{ +"name": "url" +}, +{ +"name": "pageOptions", +"value": "={{ {\n onlyMainContent: true,\n replaceAllPathsWithAbsolutePaths: true,\n removeTags: 'img,svg,video,audio'\n} }}", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"genericAuthType": "httpHeaderAuth", +"toolDescription": "Call this tool to read the contents of a crunchbase profile.", +"optimizeResponse": true +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 1 +}, +{ +"id": "71729e21-a820-41a3-9cde-a52a63d1366d", +"name": "Search WellFound", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1180, +180 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"fields": "markdown", +"method": "POST", +"sendBody": true, +"dataField": "data", +"authentication": "genericCredentialType", +"parametersBody": { +"values": [ +{ +"name": "url" +}, +{ +"name": "pageOptions", +"value": "={{ {\n onlyMainContent: true,\n replaceAllPathsWithAbsolutePaths: true,\n removeTags: 'img,svg,video,audio'\n} }}", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"genericAuthType": "httpHeaderAuth", +"toolDescription": "Call this tool to read the contents of a wellfound profile.", +"optimizeResponse": true +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 1 +}, +{ +"id": "ad5be9e0-14dc-40b2-b080-b079fb4c1d4b", +"name": "Search LinkedIn", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1320, +180 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"fields": "markdown", +"method": "POST", +"sendBody": true, +"dataField": "data", +"authentication": "genericCredentialType", +"parametersBody": { +"values": [ +{ +"name": "url" +}, +{ +"name": "pageOptions", +"value": "={{ {\n onlyMainContent: true,\n replaceAllPathsWithAbsolutePaths: true,\n removeTags: 'img,svg,video,audio'\n} }}", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"genericAuthType": "httpHeaderAuth", +"toolDescription": "Call this tool to read the contents of a linkedin company profile. You must pass in the the linkedin.com url.", +"optimizeResponse": true +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 1 +}, +{ +"id": "405fa211-436d-4601-bc3e-ad6e6d99886d", +"name": "Structured Output Parser1", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1600, +20 +], +"parameters": { +"jsonSchemaExample": "{\n \"company_name\": \"\",\n \"company_website\": \"\",\n \"year_founded\": \"\",\n \"founders\": [{ \"name\": \"\", \"linkedIn\": \"\" }],\n \"ceo\": [{ \"name\": \"\", \"linkedIn\": \"\", \"twitter\": \"\" }],\n \"key_people\": [{ \"name\": \"\", \"role\": \"\", \"linkedIn\": \"\", \"twitter\": \"\" }],\n \"employees\": [{ \"name\": \"\", \"role\": \"\", \"linkedIn\": \"\", \"twitter\": \"\" }],\n \"open_jobs\": [{ \"role\": \"\", \"description\": \"\", \"published\": \"\" }],\n \"offices\": [{ \"address\": \"\", \"city\": \"\" }],\n \"money_raised\": \"\",\n \"funding_status\": \"\",\n \"investors\": [{ \"name\": \"\", \"description\": \"\", \"linkedIn\": \"\" }],\n \"customers\": [{ \"name\": \"\", \"url\": \"\" }],\n \"yoy_customer_growth\": \"\",\n \"annual_revenue\": \"\",\n \"yoy_revenue_growth\": \"\",\n \"latest_articles\": [{ \"title\": \"\", \"snippet\": \"\", \"url\": \"\", \"published_date\": \"\" }]\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "e4955f40-6e8c-42d9-bb1e-d134485717f2", +"name": "Webscraper Tool1", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1460, +180 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"fields": "markdown", +"method": "POST", +"sendBody": true, +"dataField": "data", +"authentication": "genericCredentialType", +"parametersBody": { +"values": [ +{ +"name": "url" +}, +{ +"name": "pageOptions", +"value": "={{ {\n onlyMainContent: true,\n replaceAllPathsWithAbsolutePaths: true,\n removeTags: 'img,svg,video,audio'\n} }}", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"genericAuthType": "httpHeaderAuth", +"toolDescription": "Call this tool to fetch any additional webpage and its contents which may be helpful in gathering information for the data points.", +"optimizeResponse": true +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 1 +}, +{ +"id": "4ddf8829-e11d-4002-ad96-1b3fcddebef7", +"name": "Remove Duplicates", +"type": "n8n-nodes-base.removeDuplicates", +"position": [ +320, +-380 +], +"parameters": { +"compare": "selectedFields", +"options": {}, +"fieldsToCompare": "url" +}, +"typeVersion": 1.1 +}, +{ +"id": "06d7e6fb-9fe8-4c31-9042-fa375b63dd63", +"name": "Extract Domain", +"type": "n8n-nodes-base.set", +"position": [ +140, +-240 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "d82bab07-3434-4db3-ba89-d722279e3c40", +"name": "title", +"type": "string", +"value": "={{ $json.title }}" +}, +{ +"id": "8a774c1d-c4b1-427a-aa4d-cda0071656ce", +"name": "url", +"type": "string", +"value": "=https://{{ $json.url.extractDomain() }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "991fbb7f-9ba5-4672-8573-6a28e77ed5fc", +"name": "Results to List", +"type": "n8n-nodes-base.splitOut", +"position": [ +140, +-380 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "results" +}, +"typeVersion": 1 +}, +{ +"id": "f09112bc-65b5-4b6d-b568-eef95d064d45", +"name": "Check Company Profiles Exist", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1180, +20 +], +"parameters": { +"url": "https://serpapi.com/search", +"fields": "position,title,link,snippet,source", +"dataField": "organic_results", +"sendQuery": true, +"authentication": "predefinedCredentialType", +"fieldsToInclude": "selected", +"parametersQuery": { +"values": [ +{ +"name": "q" +} +] +}, +"toolDescription": "Call this tool to check if a company profile exists in either crunchbase, wellfound or linkedin.\n* To check if a company has a crunchbase profile, use the query \"site: https://crunchbase.com/organizations (company)\"\n* To check if a company has a wellfound profile, use the query \"site: https://wellfound.com/company (company)\"\n* To check if a company has a linked company profile, use the query \"site: https://linkedin.com/company (company)\"", +"optimizeResponse": true, +"nodeCredentialType": "serpApi" +}, +"credentials": { +"serpApi": { +"id": "aJCKjxx6U3K7ydDe", +"name": "SerpAPI account" +} +}, +"typeVersion": 1 +}, +{ +"id": "5ac6eb04-7c94-443f-bdd3-52e5fc1f72ff", +"name": "Webscraper Tool", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +2180, +-40 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"fields": "markdown", +"method": "POST", +"sendBody": true, +"dataField": "data", +"authentication": "genericCredentialType", +"parametersBody": { +"values": [ +{ +"name": "url" +}, +{ +"name": "pageOptions", +"value": "={{ {\n onlyMainContent: true,\n replaceAllPathsWithAbsolutePaths: true,\n removeTags: 'img,svg,video,audio'\n} }}", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"genericAuthType": "httpHeaderAuth", +"toolDescription": "Call this tool to fetch webpage contents. Pass in the url to fetch.", +"optimizeResponse": true +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 1 +}, +{ +"id": "082b8e76-30b8-48f2-a581-a04a6f05c20d", +"name": "Search Company Website", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +2040, +-40 +], +"parameters": { +"url": "https://serpapi.com/search", +"fields": "position,title,link,snippet,source", +"dataField": "organic_results", +"sendQuery": true, +"authentication": "predefinedCredentialType", +"fieldsToInclude": "selected", +"parametersQuery": { +"values": [ +{ +"name": "q" +} +] +}, +"toolDescription": "Call this tool to query the company's profile website.\nExamples could include \"(company) pricing\", \"(company) plans\", \"(company) features\" etc", +"optimizeResponse": true, +"nodeCredentialType": "serpApi" +}, +"credentials": { +"serpApi": { +"id": "aJCKjxx6U3K7ydDe", +"name": "SerpAPI account" +} +}, +"typeVersion": 1 +}, +{ +"id": "ca3140c5-b4ff-41d5-b0a1-b2595e1fc789", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +2320, +-40 +], +"parameters": { +"jsonSchemaExample": "{\n \"features\": [{ \"name\": \"\", \"description\": \"\" }],\n \"pricing_plans\": [{ \"name\": \"\", \"description\": \"\", \"tier\": \"\", \"price\": \"\", \"monthly_or_annually\": \"\" }],\n \"factors_that_impact_price\": [{ \"factor\": \"\", \"description\": \"\" }],\n \"discounts_promotions\": [{ \"offer\": \"\", \"start\": \"\", \"end\": \"\", \"description\": \"\" }],\n \"custom_plans\": { \"is_available\": false, \"applicable_for\": \"\", \"price\": \"\", \"duration\": \"\", \"description\": \"\" },\n \"free_trial\": { \"is_available\": false, \"applicable_for\": \"\", \"price\": \"\", \"duration\": \"\", \"description\": \"\" },\n \"freemium_version\": { \"is_available\": false, \"applicable_for\": \"\", \"price\": \"\", \"duration\": \"\", \"description\": \"\" },\n \"complementary_tools\": [{ \"name\": \"\", \"description\": \"\", \"price\": \"\" }],\n \"techonology used\": [{ \"name\": \"\", \"description\": \"\", \"purpose\": \"\" }]\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "3c5493eb-6ca9-4909-997d-ddf3f3c88e2d", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1900, +-40 +], +"parameters": { +"model": "gpt-4o-mini", +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "299920bb-194b-4a95-8822-c0f6d559dd15", +"name": "Search Product Review Sites", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +2757, +20 +], +"parameters": { +"url": "https://serpapi.com/search", +"fields": "position,title,link,snippet,source", +"dataField": "organic_results", +"sendQuery": true, +"authentication": "predefinedCredentialType", +"fieldsToInclude": "selected", +"parametersQuery": { +"values": [ +{ +"name": "q", +"value": "{company_or_product} reviews (site:trustpilot.com OR site:producthunt.com)", +"valueProvider": "fieldValue" +}, +{ +"name": "num", +"value": "3", +"valueProvider": "fieldValue" +} +] +}, +"toolDescription": "Call this tool to search for customer reviews for the desired company or their product/service.", +"optimizeResponse": true, +"nodeCredentialType": "serpApi", +"placeholderDefinitions": { +"values": [ +{ +"name": "company_or_product", +"description": "the name of the company or their product to search for reviews for" +} +] +} +}, +"credentials": { +"serpApi": { +"id": "aJCKjxx6U3K7ydDe", +"name": "SerpAPI account" +} +}, +"typeVersion": 1 +}, +{ +"id": "216bc875-365c-4536-b3b4-90de29265cb5", +"name": "Webscraper Tool2", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +2897, +20 +], +"parameters": { +"url": "https://api.firecrawl.dev/v0/scrape", +"fields": "markdown", +"method": "POST", +"sendBody": true, +"dataField": "data", +"authentication": "genericCredentialType", +"parametersBody": { +"values": [ +{ +"name": "url", +"value": "{url_or_link}", +"valueProvider": "fieldValue" +}, +{ +"name": "pageOptions", +"value": "={{ {\n onlyMainContent: true,\n replaceAllPathsWithAbsolutePaths: true,\n removeTags: 'img,svg,video,audio'\n} }}", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"genericAuthType": "httpHeaderAuth", +"toolDescription": "Call this tool to fetch webpage contents. Pass in the url to fetch.", +"optimizeResponse": true, +"placeholderDefinitions": { +"values": [ +{ +"name": "url_or_link", +"description": "the url or lik to the review site webpage." +} +] +} +}, +"credentials": { +"httpHeaderAuth": { +"id": "OUOnyTkL9vHZNorB", +"name": "Firecrawl API" +} +}, +"typeVersion": 1 +}, +{ +"id": "c13f23fd-77b9-4f4c-bdc6-50120ed84cbd", +"name": "Structured Output Parser2", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +3037, +20 +], +"parameters": { +"jsonSchemaExample": "{\n \"number_of_reviews\": 0,\n \"positive_mentions_%\": \"\",\n \"negative_mentions_%\": \"\",\n \"top_pros\": [\"\"],\n \"top_cons\": [\"\"],\n \"top_countries\": [\"\"],\n \"top_social_media_platforms\": [\"\"]\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "784202a0-4022-4941-8fcc-f1c05c9820a6", +"name": "OpenAI Chat Model2", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2617, +20 +], +"parameters": { +"model": "gpt-4o", +"options": { +"temperature": 0 +} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "fbc2e1c1-7851-4fbb-b46c-9fa35eacd810", +"name": "Insert Into Notion", +"type": "n8n-nodes-base.notion", +"position": [ +3520, +-240 +], +"parameters": { +"title": "={{ $json.output.company_name }}", +"blockUi": { +"blockValues": [ +{ +"type": "heading_1", +"textContent": "={{ $json.output.company_name }}" +}, +{ +"textContent": "=Report generated on {{ $now.format('dd MMM yyyy') }}" +}, +{ +"type": "heading_2", +"textContent": "Company Overview" +}, +{ +"textContent": "=Offices:\n{{ $json.output.offices.map(item => `${item.address}, ${item.city}`).join('\\n') }}\n\nYear Founded:\n{{ $json.output.year_founded }}\n\nFounders:\n{{ $json.output.founders.map(item => `${item.name} (${item.linkedIn})`).join('\\n') }}\n\nCEO:\n{{ $json.output.ceo.map(item => `${item.name} (${item.linkedIn})`).join('\\n') }}\n\nEmployees:\n{{ $json.output.employees.map(item => `${item.name} - ${item.role}, (${item.linkedIn})`).join('\\n') }}\n\nOpen Roles:\n{{ $json.output.open_jobs.map(item => `${item.role} (${item.published}), ${item.description}`).join('\\n') }}" +}, +{ +"type": "heading_2", +"textContent": "Company Funding" +}, +{ +"textContent": "=Money Raised:\n{{ $json.output.money_raised || 'unknown' }}\n\nFunding Status:\n{{ $json.output.funding_status }}\n\nYoY Customer Growth:\n{{ $json.output.yoy_customer_growth || 'unknown' }}\n\nAnnual Revenue:\n{{ $json.output.annual_revenue || 'unknown' }}\n\nYoY Revenue Growth:\n{{ $json.output.yoy_revenue_growth || 'unknown' }}\n\nInvestors:\n{{ $json.output.investors.map(item => `${item.name}, ${item.description} (${item.linkedIn})`).join('\\n') }}\n\nCustomers:\n{{ $json.output.customers.map(item => `${item.name} (${item.url})`).join('\\n') }}" +}, +{ +"type": "heading_2", +"textContent": "Company News" +}, +{ +"textContent": "={{ $json.output.latest_articles.length ? $json.output.latest_articles.map(item =>\n`**${item.title}**\n${item.url}\n${item.published_date} | ${item.snippet}\n`).join('\\n') : 'None Found' }}" +}, +{ +"type": "heading_2", +"textContent": "Product Offering" +}, +{ +"textContent": "=Features:\n{{ $json.output.features.map(item => `${item.name} - ${item.description.split('.')[0]}.`).join('\\n') }}\n" +}, +{ +"textContent": "=Pricing Plans:\n{{ $json.output.pricing_plans.map(item =>\n`${item.name} - ${item.price} (${item.tier})\n* ${item.description}`\n).join('\\n\\n') }}\n\nFactors that Impact Price:\n{{ $json.output.factors_that_impact_price.map(item => `${item.factor} - ${item.description}`).join('\\n') }}\n\nCurrent Discounts and/or Promotions:\n{{ $json.output.discounts_promotions.length ? $json.output.discounts_promotions.map(item =>\n `${item.offer} (${item.start} - ${item.end})\n* ${item.description}`\n).join('\\n\\n') : '* None Found' }}\n\nCustom Plans:\n{{ $json.output.custom_plans.is_available ? (\n `${$json.output.custom_plans.applicable_for} - ${$json.output.custom_plans.price}\n* ${$json.output.custom_plans.description}`\n) : 'Not applicable' }}\n\nFree Trials:\n{{ $json.output.free_trial.is_available ? (\n `${$json.output.free_trial.applicable_for} - ${$json.output.free_trial.price}\n* ${$json.output.free_trial.description}`\n) : 'Not applicable' }}\n\nFreemium Version:\n{{ $json.output.freemium_version.is_available ? (\n `${$json.output.freemium_version.applicable_for} - ${$json.output.freemium_version.price}\n* ${$json.output.freemium_version.description}`\n) : 'Not applicable' }}\n\nComplimentary Tools:\n{{ $json.output.complementary_tools.map(item =>\n `${item.name} - ${item.price}\n* ${item.description}`\n).join('\\n\\n') }}" +}, +{ +"type": "heading_2", +"textContent": "=Product Reviews" +}, +{ +"textContent": "=Number of Reviews: {{ $json.output.number_of_reviews }}\nPositive Mentions (%): {{ $json.output['positive_mentions_%'] }} \nNegative Mentions (%): {{ $json.output['negative_mentions_%'] }} \n\nTop Pros:\n{{ $json.output.top_pros.length ? $json.output.top_pros.map(item => `* ${item}`).join('\\n'): '* None Found' }}\n\nTop Cons:\n{{ $json.output.top_cons.length ? $json.output.top_cons.map(item => `* ${item}`).join('\\n') : '* None Found' }} \n\nTop Countries:\n{{ $json.output.top_countries.length ? $json.output.top_countries.map(item => `* ${item}`).join('\\n') : '* None Found' }}\n\nTop Social Media Platforms:\n{{ $json.output.top_social_media_platforms.length ? $json.output.top_social_media_platforms.map(item => `* ${item}`).join('\\n') : '* None Found' }}" +} +] +}, +"options": {}, +"resource": "databasePage", +"databaseId": { +"__rl": true, +"mode": "list", +"value": "2d1c3c72-6e8e-42f3-aece-c6338fd24333", +"cachedResultUrl": "https://www.notion.so/2d1c3c726e8e42f3aecec6338fd24333", +"cachedResultName": "n8n Competitor Analysis" +}, +"propertiesUi": { +"propertyValues": [ +{ +"key": "Founded|rich_text", +"textContent": "={{ $json.output.year_founded }}" +}, +{ +"key": "Funding Status|rich_text", +"textContent": "={{ $json.output.funding_status }}" +}, +{ +"key": "Money Raised|rich_text", +"textContent": "={{ $json.output.money_raised || ''}}" +}, +{ +"key": "Positive Reviews (%)|rich_text", +"textContent": "={{ $json.output['positive_mentions_%'] }}%" +}, +{ +"key": "Pros|rich_text", +"textContent": "={{ $json.output.top_pros.join(', ') }}" +}, +{ +"key": "Cons|rich_text", +"textContent": "={{ $json.output.top_cons.join(', ') }}" +} +] +} +}, +"credentials": { +"notionApi": { +"id": "iHBHe7ypzz4mZExM", +"name": "Notion account" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "ec6b578d-4808-4613-881b-67dbcf30f641", +"name": "Limit", +"type": "n8n-nodes-base.limit", +"position": [ +320, +-240 +], +"parameters": { +"maxItems": 10 +}, +"typeVersion": 1 +}, +{ +"id": "2f25cf2e-86c6-4d23-a1ae-cc35134f0d8a", +"name": "Loop Over Items", +"type": "n8n-nodes-base.splitInBatches", +"position": [ +680, +-280 +], +"parameters": { +"options": {} +}, +"typeVersion": 3 +}, +{ +"id": "360000e3-bc07-4be9-91cf-169b85ed7ad5", +"name": "Competitor Search via Exa.ai", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-80, +-420 +], +"parameters": { +"url": "https://api.exa.ai/findSimilar", +"method": "POST", +"options": {}, +"sendBody": true, +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "url", +"value": "={{ $json.company_url }}" +}, +{ +"name": "type", +"value": "neural" +}, +{ +"name": "useAutoprompt", +"value": "true" +}, +{ +"name": "contents", +"value": "={{ { \"text\": false } }}" +}, +{ +"name": "excludeDomains", +"value": "={{ [$json.company_url, \"github.com\", \"linkedIn.com\"] }}" +} +] +}, +"genericAuthType": "httpHeaderAuth" +}, +"credentials": { +"httpHeaderAuth": { +"id": "BWhPl6CgBKn3UJca", +"name": "Exa.ai" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "dae53670-bafb-4dff-95e7-cc94adf5f344", +"name": "Get Company News", +"type": "@n8n/n8n-nodes-langchain.toolHttpRequest", +"position": [ +1460, +20 +], +"parameters": { +"url": "https://serpapi.com/search", +"fields": "position,title,link,snippet,source", +"sendBody": true, +"dataField": "organic_results", +"authentication": "predefinedCredentialType", +"parametersBody": { +"values": [ +{ +"name": "q" +}, +{ +"name": "engine", +"value": "google_news", +"valueProvider": "fieldValue" +} +] +}, +"fieldsToInclude": "selected", +"toolDescription": "Call this tool to search for the latest news articles of a company.", +"optimizeResponse": true, +"nodeCredentialType": "serpApi" +}, +"credentials": { +"serpApi": { +"id": "aJCKjxx6U3K7ydDe", +"name": "SerpAPI account" +}, +"httpHeaderAuth": { +"id": "BWhPl6CgBKn3UJca", +"name": "Exa.ai" +} +}, +"typeVersion": 1 +}, +{ +"id": "84809359-06c8-41d9-8269-571cac716d17", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-589.9031441651332, +-613.6533489294407 +], +"parameters": { +"color": 7, +"width": 1128.870960716006, +"height": 582.8537144476434, +"content": "## Step 1. Get Competitors\n[Read more about using the HTTP Request node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest)\n\nExa.ai is a relatively new AI search engine startup with a specialised API for finding similar companies.\nThis is perfect for marketing research as we can easily find competitors to compare against." +}, +"typeVersion": 1 +}, +{ +"id": "d43e8b2a-53dd-41db-aacd-f3fdd29d8fe9", +"name": "Set Source Company", +"type": "n8n-nodes-base.set", +"position": [ +-300, +-420 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3910089f-065d-4f05-a3b7-a5b848b91eb9", +"name": "company_url", +"type": "string", +"value": "https://notion.so" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "1c28b108-dc18-4304-aed9-275e719c4edd", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-340, +-440 +], +"parameters": { +"width": 181.85939799093455, +"height": 308.12010511833364, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### 🚨Required!\nRemember to set your company here." +}, +"typeVersion": 1 +}, +{ +"id": "5cb54393-795b-4738-aac2-cc9395456420", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +560, +-525.6986144265638 +], +"parameters": { +"color": 7, +"width": 332.87733508600377, +"height": 492.4668447935363, +"content": "## Step 2. Feed into Agent Pipeline\n[Learn more about loops](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches)\n\nA loop is used to ensure competitors are processed one at a time. This is ideal when we don't want errors to fail the entire pipeline." +}, +"typeVersion": 1 +}, +{ +"id": "4cdddfd1-8631-4d88-a65d-10a53daeaf78", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1800, +-420 +], +"parameters": { +"color": 7, +"width": 687.9856526661888, +"height": 600.1548730999224, +"content": "## Step 4. Research Competitor Product Offering\n[Learn more about using AI Agents](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n\nThis agent uses SERPAPI to discover the competitor's product pages. Once found, it will use the webscraping tool to fetch the page's contents to extract the necessary data points." +}, +"typeVersion": 1 +}, +{ +"id": "3a374ce6-0ae0-4f8e-ad6a-35ab2c8da211", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +920, +-400 +], +"parameters": { +"color": 7, +"width": 849.3810544357925, +"height": 775.191233831828, +"content": "## Step 3. Discover Competitor Company and Funding Overview\n[Learn more about using AI Agents](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n\nThis agent searches crunchbase.com, wellfound.com and linkedin.com for the competitor's company details, people data, funding activity and latest news." +}, +"typeVersion": 1 +}, +{ +"id": "fa580430-d6c6-4d41-b0f9-c86ad89dc6ab", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2520, +-400 +], +"parameters": { +"color": 7, +"width": 683.8444841203574, +"height": 633.9023021841829, +"content": "## Step 5. Capture Competitor Product Reviews\n[Learn more about using AI Agents](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent)\n\nThis agent uses SERPAPI to discover product reviews for the competitor's product or service and then summarises the pros and cons." +}, +"typeVersion": 1 +}, +{ +"id": "b050b11f-9b4f-4ed1-94b9-3ec69a1ceba7", +"name": "Collect Results", +"type": "n8n-nodes-base.set", +"position": [ +3340, +-240 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3c58a9dd-28c5-4758-a362-d5b29f6a8204", +"name": "output", +"type": "object", +"value": "={{\n {\n ...$('Company Overview Agent').item.json.output,\n ...$('Company Product Offering Agent').item.json.output,\n ...$('Company Product Reviews Agent').item.json.output,\n }\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "1fc6468e-8a89-4a37-a8d6-1fe94c274b3a", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3220, +-481.22655186925294 +], +"parameters": { +"color": 7, +"width": 529.1065295866968, +"height": 572.5257167828777, +"content": "## Step 6. Collect Results and Send to Notion\n[Read more about using Notion](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.notion)\n\nFinally, once the agent's have completed their tasks successfully, we compiled a competitor report and insert it as a new row in our Notion table.\nYou can check out a copy of this table here: https://jimleuk.notion.site/2d1c3c726e8e42f3aecec6338fd24333?v=de020fa196f34cdeb676daaeae44e110&pvs=4" +}, +"typeVersion": 1 +}, +{ +"id": "863c40c7-e56d-464f-8105-0cb151654715", +"name": "2sec", +"type": "n8n-nodes-base.wait", +"position": [ +3680, +280 +], +"webhookId": "94b5b09f-0599-4585-b83b-f669726bc2ef", +"parameters": { +"amount": 2 +}, +"typeVersion": 1.1 +}, +{ +"id": "c1a4b720-f56b-4c3a-aeca-a89f473132f4", +"name": "Company Overview Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1020, +-200 +], +"parameters": { +"text": "={{ $('Loop Over Items').item.json.url }}", +"options": { +"systemMessage": "Your role is a company researcher agent. Your goal is to research and discover the following information about a company:\n* Year founded\n* Founder(s)\n* CEO\n* Key people\n* Employees\n* Open jobs\n* Offices\n* Money raised\n* Funding status\n* Investors\n* Customers\n* YoY customer growth\n* Annual revenue\n* YoY revenue growth\n* Latest articles\n\n## Steps\n1. check if the company's crunchbase profile exists and if it does read the profile page to gather the required information. If you are able to satisfies all data points from the profile, then do not return your response.\n2. repeat step 1 for wellfound if there are missing data points on the crunchbase profile.\n3. repeat step 1 for linkedin if there are missing data points on the wellfound profile.\n4. If there are still missing datapoints after checking cruchbase, wellfound and linkedin then just give up and return your response.\n\nIf a data point is not found after completing all the above steps, do not use null values in your final response. Use either an empty array, object or string depending on the required schema for the data point.\nDo not retry any link that returns a 400,401,403 or 500 error code." +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.6 +}, +{ +"id": "1070c7f0-544a-478b-bd97-df8f2c0d79fa", +"name": "Company Product Offering Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +1900, +-240 +], +"parameters": { +"text": "={{ $('Loop Over Items').item.json.url }}", +"options": { +"systemMessage": "Your role is company product/service researcher. Your goal is to search and collect the following information:\n* features sets\n* number of pricing plans\n* Factors that impact price\n* Lowest-tier, Mid-tier and Highest-tier price\n* Custom plans if available\n* Discounts & promotions offered currently\n* whether a Free trial is offered\n* description of freemium version if available\n* Complementary tools offered\n* technology used\n\n# steps\n1. Search for the relevant webpage on the company's website. This search should return a url address.\n2. Use this url address with the webscraper tool to fetch the contents of the webpage.\n3. Use the contents of th webpage to populate the data points.\n\nIf a data point is not found after completing all the above steps, do not use null values in your final response. Use either an empty array, object or string depending on the required schema for the data point.\nDo not retry any link that returns a 400,401,403 or 500 error code." +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.6 +}, +{ +"id": "5dec7033-5057-483f-930d-e950b6eabe05", +"name": "Company Product Reviews Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +2617, +-200 +], +"parameters": { +"text": "={{ $('Loop Over Items').item.json.url }}", +"options": { +"systemMessage": "Your role is customer reviews agent. Your goal is to gather and collect online customer reviews for a company or their product or service.\n* number of reviews\n* Positive mentions, %\n* Negative mentions, %\n* Top pros\n* Top cons\n* Top countries\n* Top social media platforms\n\n## steps\n1. search for review sites that may have reviews for the company or product in question. retrieve the links or urls of the serch results where the reviews are found.\n2. Identify relevant items in the search result and and extract the urls from the search results.\n2. using the extracted urls from the search results, fetch the webpage of the review sites containing reviews for the company or product.\n3. extract the reviews from the fetched review sites to populate the required data points.\n\nIf a data point is not found after completing all the above steps, do not use null values in your final response. Use either an empty array, object or string depending on the required schema for the data point.\nDo not retry any link that returns a 400,401,403 or 500 error code." +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.6 +}, +{ +"id": "787bb405-1744-43b7-8c47-1a2c23331e05", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3480, +-260 +], +"parameters": { +"width": 181.85939799093455, +"height": 308.12010511833364, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n### 🚨Required!\nRemember to set your Notion Database here." +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"2sec": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Limit": { +"main": [ +[ +{ +"node": "Loop Over Items", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Domain": { +"main": [ +[ +{ +"node": "Remove Duplicates", +"type": "main", +"index": 0 +} +] +] +}, +"Collect Results": { +"main": [ +[ +{ +"node": "Insert Into Notion", +"type": "main", +"index": 0 +} +] +] +}, +"Loop Over Items": { +"main": [ +null, +[ +{ +"node": "Company Overview Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Results to List": { +"main": [ +[ +{ +"node": "Extract Domain", +"type": "main", +"index": 0 +} +] +] +}, +"Search LinkedIn": { +"ai_tool": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Webscraper Tool": { +"ai_tool": [ +[ +{ +"node": "Company Product Offering Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Company News": { +"ai_tool": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Search WellFound": { +"ai_tool": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Webscraper Tool1": { +"ai_tool": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Webscraper Tool2": { +"ai_tool": [ +[ +{ +"node": "Company Product Reviews Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Company Product Offering Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Remove Duplicates": { +"main": [ +[ +{ +"node": "Limit", +"type": "main", +"index": 0 +} +] +] +}, +"Search Crunchbase": { +"ai_tool": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Insert Into Notion": { +"main": [ +[ +{ +"node": "2sec", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model2": { +"ai_languageModel": [ +[ +{ +"node": "Company Product Reviews Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Set Source Company": { +"main": [ +[ +{ +"node": "Competitor Search via Exa.ai", +"type": "main", +"index": 0 +} +] +] +}, +"Company Overview Agent": { +"main": [ +[ +{ +"node": "Company Product Offering Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Search Company Website": { +"ai_tool": [ +[ +{ +"node": "Company Product Offering Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Company Product Offering Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Structured Output Parser1": { +"ai_outputParser": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Structured Output Parser2": { +"ai_outputParser": [ +[ +{ +"node": "Company Product Reviews Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Search Product Review Sites": { +"ai_tool": [ +[ +{ +"node": "Company Product Reviews Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Check Company Profiles Exist": { +"ai_tool": [ +[ +{ +"node": "Company Overview Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Competitor Search via Exa.ai": { +"main": [ +[ +{ +"node": "Results to List", +"type": "main", +"index": 0 +} +] +] +}, +"Company Product Reviews Agent": { +"main": [ +[ +{ +"node": "Collect Results", +"type": "main", +"index": 0 +} +] +] +}, +"Company Product Offering Agent": { +"main": [ +[ +{ +"node": "Company Product Reviews Agent", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Set Source Company", +"type": "main", +"index": 0 +} +] +] +} +} +}Automate Competitor Research with Exa.ai, Notion and AI AgentsAutomate Competitor Research with Exa.ai, Notion and AI AgentsAutomate Competitor Research with Exa.ai, Notion and AI Agents \ No newline at end of file diff --git a/Automate Content Generator for WordPress with DeepSeek R1.txt b/Automate Content Generator for WordPress with DeepSeek R1.txt new file mode 100644 index 0000000..5cae8f3 --- /dev/null +++ b/Automate Content Generator for WordPress with DeepSeek R1.txt @@ -0,0 +1,568 @@ +{ +"id": "p5bfwpcRy6LK33Io", +"meta": { +"instanceId": "a4bfc93e975ca233ac45ed7c9227d84cf5a2329310525917adaf3312e10d5462", +"templateCredsSetupCompleted": true +}, +"name": "Automate Content Generator for WordPress with DeepSeek R1", +"tags": [], +"nodes": [ +{ +"id": "c4a6995f-7769-4b77-80ca-1e6bccef77c1", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +-20, +200 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "c76b1458-5130-41e7-b2f2-1cfe22eab536", +"name": "Get Ideas", +"type": "n8n-nodes-base.googleSheets", +"position": [ +200, +200 +], +"parameters": { +"options": {}, +"sheetName": { +"__rl": true, +"mode": "id", +"value": "=Sheet1" +}, +"documentId": { +"__rl": true, +"mode": "id", +"value": "YOURDOCUMENT" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "JYR6a64Qecd6t8Hb", +"name": "Google Sheets account" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "8d17a640-3e15-42e9-9481-e3291d395ccd", +"name": "Set your prompt", +"type": "n8n-nodes-base.set", +"position": [ +420, +200 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3e8d2523-66aa-46fe-adcc-39dc78b9161e", +"name": "prompt", +"type": "string", +"value": "={{ $json.PROMPT }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "4f0e9065-b331-49ed-acd9-77c7c43e89a5", +"name": "Create post on Wordpress", +"type": "n8n-nodes-base.wordpress", +"position": [ +0, +500 +], +"parameters": { +"title": "={{ $json.message.content }}", +"additionalFields": { +"status": "draft", +"content": "={{ $('Generate article with DeepSeek').item.json.message.content }}" +} +}, +"credentials": { +"wordpressApi": { +"id": "OE4AgquSkMWydRqn", +"name": "Wordpress (wp.test.7hype.com)" +} +}, +"typeVersion": 1 +}, +{ +"id": "cb85d980-9d60-4c85-8574-b46e4cc14341", +"name": "Upload image", +"type": "n8n-nodes-base.httpRequest", +"position": [ +420, +500 +], +"parameters": { +"url": "https://YOURSITE.com/wp-json/wp/v2/media", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "binaryData", +"sendHeaders": true, +"authentication": "predefinedCredentialType", +"headerParameters": { +"parameters": [ +{ +"name": "Content-Disposition", +"value": "=attachment; filename=\"copertina-{{ $('Create post on Wordpress').item.json.id }}.jpg\"" +} +] +}, +"inputDataFieldName": "data", +"nodeCredentialType": "wordpressApi" +}, +"credentials": { +"wordpressApi": { +"id": "OE4AgquSkMWydRqn", +"name": "Wordpress (wp.test.7hype.com)" +}, +"wooCommerceApi": { +"id": "vYYrjB5kgHQ0XByZ", +"name": "WooCommerce (wp.test.7hype.com)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "bc71ed8a-fe35-487a-b4cd-6b8c1b256763", +"name": "Set Image", +"type": "n8n-nodes-base.httpRequest", +"position": [ +640, +500 +], +"parameters": { +"url": "=https://wp.test.7hype.com/wp-json/wp/v2/posts/{{ $('Create post on Wordpress').item.json.id }}", +"method": "POST", +"options": {}, +"sendQuery": true, +"authentication": "predefinedCredentialType", +"queryParameters": { +"parameters": [ +{ +"name": "featured_media", +"value": "={{ $json.id }}" +} +] +}, +"nodeCredentialType": "wordpressApi" +}, +"credentials": { +"wordpressApi": { +"id": "OE4AgquSkMWydRqn", +"name": "Wordpress (wp.test.7hype.com)" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "fbed2813-cc64-42a2-994f-3696e9d8d8fe", +"name": "Update Sheet", +"type": "n8n-nodes-base.googleSheets", +"position": [ +880, +500 +], +"parameters": { +"columns": { +"value": { +"DATA": "={{ $now.format('dd/LL/yyyy') }}", +"TITOLO": "={{ $('Generate title with DeepSeek').item.json.message.content }}", +"ID POST": "={{ $('Create post on Wordpress').item.json.id }}", +"row_number": "={{ $('Get Ideas').item.json.row_number }}" +}, +"schema": [ +{ +"id": "DATA", +"type": "string", +"display": true, +"required": false, +"displayName": "DATA", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "PROMPT", +"type": "string", +"display": true, +"required": false, +"displayName": "PROMPT", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "TITOLO", +"type": "string", +"display": true, +"required": false, +"displayName": "TITOLO", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "ID POST", +"type": "string", +"display": true, +"required": false, +"displayName": "ID POST", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "row_number", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "row_number", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"row_number" +], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "update", +"sheetName": { +"__rl": true, +"mode": "list", +"value": "gid=0", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/16VFeCrE5BkMBoA_S5HD-9v7C0sxcXAUiDbq5JvkDqnI/edit#gid=0", +"cachedResultName": "Foglio1" +}, +"documentId": { +"__rl": true, +"mode": "list", +"value": "16VFeCrE5BkMBoA_S5HD-9v7C0sxcXAUiDbq5JvkDqnI", +"cachedResultUrl": "https://docs.google.com/spreadsheets/d/16VFeCrE5BkMBoA_S5HD-9v7C0sxcXAUiDbq5JvkDqnI/edit?usp=drivesdk", +"cachedResultName": "Plan Blog wp.test.7hype.com" +} +}, +"credentials": { +"googleSheetsOAuth2Api": { +"id": "JYR6a64Qecd6t8Hb", +"name": "Google Sheets account" +} +}, +"typeVersion": 4.5 +}, +{ +"id": "8db2b0cb-6d61-4e2d-bfac-e25a0385296d", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-60, +-360 +], +"parameters": { +"color": 3, +"width": 800, +"height": 380, +"content": "## Target\nThis workflow is designed to automatically generate seo-friendly content for wordpress through DeepSeek R1 by giving input ideas on how to structure the article. A cover image is also generated and uploaded with OpenAI DALL-E 3. This flow is designed to be executed automatically (ad \"On a schedule\" node) and thus have a complete editorial plan.\n\nThis process is useful for blog managers who want to automate content creation and publishing.\n\n## Preliminary step\nCreate a google sheet with the following columns:\n- Date\n- Prompt\n- Title\n- Post ID\n\nFill in only the \"Prompt\" column with basic ideas that DeepSeek will work on to generate the content." +}, +"typeVersion": 1 +}, +{ +"id": "ab620659-558d-46f0-ab85-e061af99b743", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +140, +100 +], +"parameters": { +"height": 260, +"content": "Connect with your Google Sheet. This node select only rows for which no content has been generated yet in WordPress" +}, +"typeVersion": 1 +}, +{ +"id": "73b0e640-8ccf-4e29-a0cd-6340db907bbd", +"name": "Generate article with DeepSeek", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +640, +200 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "id", +"value": "=deepseek-reasoner" +}, +"options": { +"maxTokens": 2048 +}, +"messages": { +"values": [ +{ +"content": "=You are an SEO expert, write an article based on this topic:\n{{ $json.prompt }}\n\nInstructions:\n- In the introduction, introduce the topic that will be explored in the rest of the text\n- The introduction should be about 120 words\n- The conclusions should be about 120 words\n- Use the conclusions to summarize everything said in the article and offer a conclusion to the reader\n- Write a maximum of 4-5 chapters and argue them.\n- The chapters should follow a logical flow and not repeat the same concepts.\n- The chapters should be related to each other and not isolated blocks of text. The text should flow and follow a linear logic.\n- Do not start chapters with \"Chapter 1\", \"Chapter 2\", \"Chapter 3\" ... write only the chapter title\n- For the text, use HTML for formatting, but limit yourself to bold, italics, paragraphs and lists.\n- Don't put the output in ```html but only text\n- Don't use markdown for formatting.\n- Go deeper into the topic you're talking about, don't just throw superficial information there\n- In output I want only the HTML format" +} +] +} +}, +"credentials": { +"openAiApi": { +"id": "97Cz4cqyiy1RdcQL", +"name": "DeepSeek" +} +}, +"typeVersion": 1.8 +}, +{ +"id": "6ef4e0d1-6123-4f47-94fb-c06c785ddd92", +"name": "Generate title with DeepSeek", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +880, +200 +], +"parameters": { +"modelId": { +"__rl": true, +"mode": "id", +"value": "=deepseek-reasoner" +}, +"options": { +"maxTokens": 2048 +}, +"messages": { +"values": [ +{ +"content": "=You are an SEO Copywriter and you need to think of a title of maximum 60 characters for the following article:\n{{ $json.message.content }}\n\nInstructions:\n- Use keywords contained in the article\n- Do not use any HTML characters\n- Output only the string containing the title.\n- Do not use quotation marks. The only special characters allowed are \":\" and \",\"" +} +] +} +}, +"credentials": { +"openAiApi": { +"id": "97Cz4cqyiy1RdcQL", +"name": "DeepSeek" +} +}, +"typeVersion": 1.8 +}, +{ +"id": "2ecc8514-c04e-4f8b-9ab3-560f2cf910b0", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +580, +100 +], +"parameters": { +"width": 420, +"height": 260, +"content": "Add your DeepSeek API credential. If you want you can change the model with \"deepseek-chat\"" +}, +"typeVersion": 1 +}, +{ +"id": "196f7799-a6ab-429b-afd3-bcbcbd65da3b", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-20, +420 +], +"parameters": { +"width": 160, +"height": 260, +"content": "Add your WordPress API credential\n" +}, +"typeVersion": 1 +}, +{ +"id": "93c2d359-531a-4cc9-8a18-870c2d6ec62c", +"name": "Generate Image with DALL-E", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +200, +500 +], +"parameters": { +"prompt": "=Generate a real photographic image used as a cover for a blog post:\n\nImage prompt:\n{{ $('Generate title with DeepSeek').item.json.message.content }}, photography, realistic, sigma 85mm f/1.4", +"options": { +"size": "1792x1024", +"style": "natural", +"quality": "hd" +}, +"resource": "image" +}, +"credentials": { +"openAiApi": { +"id": "CDX6QM4gLYanh0P4", +"name": "OpenAi account" +} +}, +"typeVersion": 1.8 +}, +{ +"id": "eec14cd7-fb2b-4f7d-ad94-bcffc1249353", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +420 +], +"parameters": { +"width": 160, +"height": 260, +"content": "Add your OpenAI API credential\n" +}, +"typeVersion": 1 +}, +{ +"id": "4f15679b-bc8f-45b8-b3c4-8b43d7f9bb6f", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +380, +420 +], +"parameters": { +"width": 180, +"height": 260, +"content": "Upload the image on your WordPress via APIs\n" +}, +"typeVersion": 1 +}, +{ +"id": "abe32434-671a-4ac3-a788-fcf5fd0e9435", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +600, +420 +], +"parameters": { +"width": 180, +"height": 260, +"content": "Set the uploaded image with the newly created article\n" +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "315cc8df-bca2-4180-806e-a01407dccc79", +"connections": { +"Get Ideas": { +"main": [ +[ +{ +"node": "Set your prompt", +"type": "main", +"index": 0 +} +] +] +}, +"Set Image": { +"main": [ +[ +{ +"node": "Update Sheet", +"type": "main", +"index": 0 +} +] +] +}, +"Upload image": { +"main": [ +[ +{ +"node": "Set Image", +"type": "main", +"index": 0 +} +] +] +}, +"Set your prompt": { +"main": [ +[ +{ +"node": "Generate article with DeepSeek", +"type": "main", +"index": 0 +} +] +] +}, +"Create post on Wordpress": { +"main": [ +[ +{ +"node": "Generate Image with DALL-E", +"type": "main", +"index": 0 +} +] +] +}, +"Generate Image with DALL-E": { +"main": [ +[ +{ +"node": "Upload image", +"type": "main", +"index": 0 +} +] +] +}, +"Generate title with DeepSeek": { +"main": [ +[ +{ +"node": "Create post on Wordpress", +"type": "main", +"index": 0 +} +] +] +}, +"Generate article with DeepSeek": { +"main": [ +[ +{ +"node": "Generate title with DeepSeek", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Get Ideas", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Customer Support Issue Resolution using AI Text Classifier.txt b/Automate Customer Support Issue Resolution using AI Text Classifier.txt new file mode 100644 index 0000000..a8a2b96 --- /dev/null +++ b/Automate Customer Support Issue Resolution using AI Text Classifier.txt @@ -0,0 +1,1116 @@ +{ +"meta": { +"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" +}, +"nodes": [ +{ +"id": "645799b0-7ddb-4acb-a95d-3b04eadff445", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +1480, +20 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "e2923385-2f73-439c-9d5c-5a3c560993cb", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2040, +420 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c24728f9-73b9-45f7-9c4e-aee872c59714", +"name": "OpenAI Chat Model3", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +3180, +-80 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "0bc19e46-4a65-45fb-9571-d1f00d204c63", +"name": "OpenAI Chat Model4", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2060, +-261 +], +"parameters": { +"model": "gpt-4o-mini", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "0c631234-125d-476b-b97a-2837d6a32f2b", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-272, +-180 +], +"parameters": { +"rule": { +"interval": [ +{} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "96c9931d-d286-42f8-9629-2641eaa368b9", +"name": "Get Issue Comments", +"type": "n8n-nodes-base.jira", +"position": [ +748, +-180 +], +"parameters": { +"options": {}, +"issueKey": "={{ $json.key }}", +"resource": "issueComment", +"operation": "getAll" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "18a2770d-5240-4837-8837-4821f73ec560", +"name": "Close Issue", +"type": "n8n-nodes-base.jira", +"position": [ +2660, +-741 +], +"parameters": { +"issueKey": "={{ $('Get Issue Metadata').item.json.key }}", +"operation": "update", +"updateFields": { +"statusId": { +"__rl": true, +"mode": "list", +"value": "31", +"cachedResultName": "Done" +} +} +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "83e81448-26c7-4c29-a17a-409c53e05881", +"name": "Send Reminder", +"type": "n8n-nodes-base.jira", +"position": [ +3500, +-220 +], +"parameters": { +"comment": "={{ $json.text }}\n(this is an automated message)", +"options": {}, +"issueKey": "={{ $('Get Issue Metadata').item.json.key }}", +"resource": "issueComment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "5fed9245-4af9-4de7-b021-750d2ba39e63", +"name": "Join Comments", +"type": "n8n-nodes-base.aggregate", +"position": [ +928, +-180 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData" +}, +"typeVersion": 1 +}, +{ +"id": "34712dd3-0348-4709-8a68-07279242910c", +"name": "Add Autoclose Message", +"type": "n8n-nodes-base.jira", +"position": [ +2460, +-561 +], +"parameters": { +"comment": "=Autoclosing due to inactivity. Please create a new ticket if you require additional support. Thank you!\n(this is an automated message)", +"options": {}, +"issueKey": "={{ $('Get Issue Metadata').item.json.key }}", +"resource": "issueComment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "c43a3b66-838b-4970-a85f-dc0370437388", +"name": "Ask For Feedback Message", +"type": "n8n-nodes-base.jira", +"position": [ +2460, +-741 +], +"parameters": { +"comment": "=[~accountid:{{ $('Get Issue Metadata').item.json.reporter_accountId }}]\n\nWe think the issue is resolved so we're autoclosing it. If you've been satisified with our service, please leave us a 5 start review here: [link](link/to/review_site)\n\nPlease feel free to create another ticket if you need further assistance.\n(this is an automated message)", +"options": {}, +"issueKey": "={{ $('Get Issue Metadata').item.json.key }}", +"resource": "issueComment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "3223ce45-9e5e-471c-9015-75e9f28088e9", +"name": "Simplify Thread For AI", +"type": "n8n-nodes-base.set", +"position": [ +1108, +-180 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "f65c5971-c90d-47f2-823f-37fd03d8e9c7", +"name": "thread", +"type": "array", +"value": "={{\n$json.data.map(comment => {\n const { accountId, displayName } = comment.author;\n\n const message = comment.body.content.map(item =>\n `<${item.type}>${item.content\n .filter(c => c.text || c.content)\n .map(c => c.content\n ? c.content\n .filter(cc => c.text || c.content)\n .map(cc => cc.text)\n .join(' ')\n : c.text\n )}`\n ).join('');\n return `${displayName} (accountId: ${accountId}) says: ${message}`;\n})\n\n}}" +}, +{ +"id": "7b98b2db-3417-472f-bea2-a7aebe30184c", +"name": "topic", +"type": "string", +"value": "={{\n[\n `title: ${$('Get Issue Metadata').item.json.title}`,\n `original message: ${$('Get Issue Metadata').item.json.description.replaceAll(/\\n/g, ' ')}`,\n `reported by: ${$('Get Issue Metadata').item.json.reporter}`\n].join('\\n')\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "e6f91099-1fe6-4930-8dda-b19330edb599", +"name": "Solution Found?", +"type": "n8n-nodes-base.if", +"position": [ +2440, +220 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "0e71783b-3072-421a-852c-58940d0dd7cd", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ $json.output.solution_found }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "696348a5-c955-47eb-ab44-f56652587944", +"name": "Reply to Issue", +"type": "n8n-nodes-base.jira", +"position": [ +2760, +220 +], +"parameters": { +"comment": "=Hey there!\n{{ $('KnowledgeBase Agent').item.json.output.response }}\nWe'll close this issue now but feel free to create a new one if needed.\n(this is an automated message)", +"options": {}, +"issueKey": "={{ $('Get Issue Metadata').item.json.key }}", +"resource": "issueComment" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "4d4562c7-f5ed-44b8-9292-9c1a75d51173", +"name": "Last Message is Not Bot", +"type": "n8n-nodes-base.if", +"position": [ +3000, +-220 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "6e07d5dc-01b2-4735-8fc1-983fc57dfaaf", +"operator": { +"type": "boolean", +"operation": "true", +"singleValue": true +}, +"leftValue": "={{ !$('Simplify Thread For AI').item.json.thread.last().includes('this is an automated message') }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "e1ca19da-c030-478b-a488-dcb08d9be97e", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +2400, +420 +], +"parameters": { +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"solution_found\": {\n\t\t\t\"type\": \"boolean\"\n\t\t},\n \"short_summary_of_issue\": {\n \"type\": \"string\"\n },\n\t\t\"response\": {\n\t\t\t\"type\": \"string\"\n\t\t}\n\t}\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "596ef421-beb0-4523-a313-3f6ccd9e8f0c", +"name": "Get Issue Metadata", +"type": "n8n-nodes-base.set", +"position": [ +568, +-180 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "200706ea-6936-48ae-a46c-38d6e2eff558", +"name": "key", +"type": "string", +"value": "={{ $json.key }}" +}, +{ +"id": "3e3584bf-dc5c-408a-896c-1660710860f6", +"name": "title", +"type": "string", +"value": "={{ $json.fields.summary }}" +}, +{ +"id": "e1d89014-5e07-4752-9e7c-ae8d4cba6f6e", +"name": "url", +"type": "string", +"value": "={{\n[\n 'https:/',\n $json.self.extractDomain(),\n 'browse',\n $json.key\n ].join('/')\n}}" +}, +{ +"id": "df1cca88-1c57-475d-968e-999f6c25dba7", +"name": "date", +"type": "string", +"value": "={{ DateTime.fromISO($json.fields.created).format('yyyy-MM-dd') }}" +}, +{ +"id": "7fc9c625-e741-43bb-9223-b8024fc86cc7", +"name": "reporter", +"type": "string", +"value": "={{ $json.fields.reporter.displayName }}" +}, +{ +"id": "17bf06ae-fcad-4eb3-add8-11ac85e9a68e", +"name": "reporter_url", +"type": "string", +"value": "={{\n[\n 'https:/',\n $json.fields.reporter.self.extractDomain(),\n 'jira',\n 'people',\n $json.fields.reporter.accountId\n ].join('/')\n}}" +}, +{ +"id": "7624642f-f76b-41ec-b402-280b64d46400", +"name": "reporter_accountId", +"type": "string", +"value": "={{ $json.fields.reporter.accountId }}" +}, +{ +"id": "0fa1d73f-4e8b-435b-a78d-37e95c85c87c", +"name": "description", +"type": "string", +"value": "={{ $json.fields.description }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "23bb0cf8-c682-416c-a809-e9ca6fc480ef", +"name": "Notify Slack Channel", +"type": "n8n-nodes-base.slack", +"position": [ +2600, +380 +], +"parameters": { +"select": "channel", +"blocksUi": "={{\n{\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Hey there 👋\\nI found a zombie ticket that no one has taken a look at yet.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": `*[${$('Get Issue Metadata').item.json.key}] ${$('Get Issue Metadata').item.json.title}*\\n${$('KnowledgeBase Agent').item.json.output.short_summary_of_issue}\\n👤 <${$('Get Issue Metadata').item.json.reporter_url}|${$('Get Issue Metadata').item.json.reporter}> 📅 ${$('Get Issue Metadata').item.json.date} 🔗 <${$('Get Issue Metadata').item.json.url}|Link to Issue>\\n`\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"I couldn't find an answer in the knowledgebase so I've notified the user and closed the ticket. Thanks!\"\n\t\t\t}\n\t\t}\n\t]\n}\n}}", +"channelId": { +"__rl": true, +"mode": "list", +"value": "C07S0NQ04D7", +"cachedResultName": "n8n-jira" +}, +"messageType": "block", +"otherOptions": {} +}, +"credentials": { +"slackApi": { +"id": "VfK3js0YdqBdQLGP", +"name": "Slack account" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "21076f8f-8462-4a5a-8831-709a138639c5", +"name": "Close Issue2", +"type": "n8n-nodes-base.jira", +"position": [ +2920, +220 +], +"parameters": { +"issueKey": "={{ $('Get Issue Metadata').item.json.key }}", +"operation": "update", +"updateFields": { +"statusId": { +"__rl": true, +"mode": "list", +"value": "31", +"cachedResultName": "Done" +} +} +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "6c9b30c5-d061-4b4d-b4fa-596ca0768297", +"name": "Get List of Unresolved Long Lived Issues", +"type": "n8n-nodes-base.jira", +"position": [ +-72, +-180 +], +"parameters": { +"limit": 10, +"options": { +"jql": "status IN (\"To Do\", \"In Progress\") AND created <= -7d" +}, +"operation": "getAll" +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "1c6c2919-c48b-47bb-a975-f184bd9e95dd", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-337.3183708039286, +-425.6402206027777 +], +"parameters": { +"color": 7, +"width": 640.6500163735489, +"height": 484.114789072283, +"content": "## 1. Search For Unresolved Long-lived JIRA Issues\n[Learn more about the JIRA node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.jira)\n\nIn this demonstration, we'll define \"long-lived\" as any issue which is unresolved after 7 days. Adjust to fit your own criteria.\n\nWe'll also use the Execute Workflow node to run the issues separate in parallel. This is a performance optimisation and if not required, the alternative is to use a loop node instead." +}, +"typeVersion": 1 +}, +{ +"id": "f21d95a7-0cef-4110-a3b9-59c562b2ea24", +"name": "Execute Workflow", +"type": "n8n-nodes-base.executeWorkflow", +"position": [ +128, +-180 +], +"parameters": { +"mode": "each", +"options": {}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "e9f9e6e6-c66d-4e50-b4d4-3931b8cf40c9", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +388, +-180 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "91b5e024-6141-47e8-99ff-9ac25df7df48", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +320, +-353.43597793972225 +], +"parameters": { +"color": 7, +"width": 956.5422324510927, +"height": 411.91054640922755, +"content": "## 2. Retrieves and Combine JIRA Issue Comments\n[Learn more about the JIRA node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.jira)\n\nTo provide the necessary information for our AI agents, we'll fetch and combine all the issue's comments along with our issue. This gives a accurate history of the the issues progress (or lack thereof!)." +}, +"typeVersion": 1 +}, +{ +"id": "9b545aa8-d2df-4500-8af0-ee55b0fcc736", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1300, +-381.8893508540474 +], +"parameters": { +"color": 7, +"width": 653.0761795166852, +"height": 583.0290516595711, +"content": "## 3. Classify the Current State of the Issue\n[Learn more about the Text Classifier node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.text-classifier)\n\nToday's AI/LLMs are well suited for solving contextual problems like determining issue state. Here, we can use the text classifier node to analyse the issue as a whole to determine our next move. Almost like a really, really smart Switch node!\n\nThere are 3 branches we want to take: Check if a resolution was reached, blocked issues and auto-resolving when no team member has yet to respond." +}, +"typeVersion": 1 +}, +{ +"id": "abe0da8f-4107-4641-b992-1a31f71ce530", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1980, +-820 +], +"parameters": { +"color": 7, +"width": 896.1509781357872, +"height": 726.4699654775604, +"content": "## 4. Sentiment Analysis on Issue Resolution\n[Read more about the Sentiment Analysis node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.sentimentanalysis)\n\nThe Sentiment Analysis node is a convenient method of assessing\ncustomer satisfaction from resolved issues. Here, when resolution\nis detected as positive, we can ask use the opportunity to\ncapitalise of the favourable experience which in this example,\nis to ask for a review. In the opposite vein, if the exchange has\nbeen negative, we can escalate in an attempt to improve\nthe situation before closing the ticket.\n\nAI can equip teams to provide unrivalled customer support\nwhich can differentiate themselves significantly against\nthe competition." +}, +"typeVersion": 1 +}, +{ +"id": "d9c97501-e2cf-4a7e-86cc-c295d69db939", +"name": "Customer Satisfaction Agent", +"type": "@n8n/n8n-nodes-langchain.sentimentAnalysis", +"position": [ +2060, +-400 +], +"parameters": { +"options": {}, +"inputText": "=issue:\n{{ $('Simplify Thread For AI').item.json.topic }}\n\ncomments:\n{{ $('Simplify Thread For AI').item.json.thread.join('\\n') }}" +}, +"typeVersion": 1 +}, +{ +"id": "2829d591-8347-4683-be10-663872c08546", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1980, +-60 +], +"parameters": { +"color": 7, +"width": 1120.504487917144, +"height": 675.5857025907994, +"content": "## 5. Attempt to Resolve The Issue With KnowledgeBase\n[Read more about the AI Agent node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.agent/)\n\nWhen the issue is unaddressed, we can attempt to resolve the issue automatically using AI. Here an AI agent can easily be deployed with\naccess to knowledge tools to research and generate solutions for the user. Since n8n v1.62.1, AI Tools Agents can attach nodes directly as\ntools providing a very easy way to linking documents to the LLM.\n\nHere, we use both the JIRA tool to search for similar issues and the notion tool to query for product pages. If a solution can be generated,\nwe create a new comment with the solution and attach it to the issue. If not, then we can leave a simple message notifying the user that we could not do so. Finally, we close the issue as no further action can likely be taken in this case." +}, +"typeVersion": 1 +}, +{ +"id": "112c9fd3-c104-4a68-8e58-96a317fef854", +"name": "KnowledgeBase Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +2060, +220 +], +"parameters": { +"text": "=issue:\n{{ $('Simplify Thread For AI').item.json.topic }}\n\ncomments:\n{{ $('Simplify Thread For AI').item.json.thread.join('\\n') }}", +"options": { +"systemMessage": "Help the user answer their question using the company's knowledgebase. Your answer must be based factually on documents retrieved from the knowledge. If no relevant information is found or the information is insufficent to answer the user's query, you must tell the user so and not mislead the user. If you don't know the answer, it is okay to say you don't know." +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.6 +}, +{ +"id": "c27e0679-29a0-45d7-ada7-9727975b5069", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2900, +-421.245651256349 +], +"parameters": { +"color": 7, +"width": 801.0347525891818, +"height": 507.581094640126, +"content": "## 6. Notify for Unanswered Questions or Response Waiting\n[Read more about the Basic LLM Chain node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/)\n\nIn this step, where signals indicate that the issue is not yet ready to be close, we can try to re-engage issue participants by summarize the conversation so far and sending a reminder comment for any pending actions that were requested. This action can help reduce the number of issues which linger for too long." +}, +"typeVersion": 1 +}, +{ +"id": "0a7da82e-789b-401c-80d0-de3ade51942c", +"name": "Issue Reminder Agent", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +3180, +-220 +], +"parameters": { +"text": "=issue:\n{{ $('Simplify Thread For AI').item.json.topic }}\n\ncomments:\n{{ $('Simplify Thread For AI').item.json.thread }}", +"messages": { +"messageValues": [ +{ +"message": "=The user has a pending issue and some time has passed since the last update. Analyse the last message in this thread and generate a short reminder message to add to the issue comments which summarizes and reiterates what pending action or information is required. Return only the message." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.4 +}, +{ +"id": "2847136e-b95b-4906-89af-ceb180abb9b0", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-820, +-560 +], +"parameters": { +"width": 454.99286536248565, +"height": 619.151728428442, +"content": "## Try It Out!\n\n### This n8n template is designed to assist and improve customer support team member capacity by automating the resolution of long-lived and forgotten JIRA issues.\n\n* Schedule Trigger runs daily to check for long-lived unresolved issues and imports them into the workflow.\n* Each Issue is handled as a separate subworkflow by using an execute workflow node. This allows parallel processing.\n* A report is generated from the issue using its comment history allowing the issue to be classified by AI - determining the state and progress of the issue.\n* If determined to be resolved, sentiment analysis is performed to track customer satisfaction. If negative, a slack message is sent to escalate, otherwise the issue is closed automatically.\n* If no response has been initiated, an AI agent will attempt to search and resolve the issue itself using similar resolved issues or from the notion database. If a solution is found, it is posted to the issue and closed.\n* If the issue is blocked and waiting for responses, then a reminder message is added.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!" +}, +"typeVersion": 1 +}, +{ +"id": "9edb0847-5dcf-4357-a1d4-537a126e277b", +"name": "Find Simlar Issues", +"type": "n8n-nodes-base.jiraTool", +"position": [ +2160, +420 +], +"parameters": { +"limit": 4, +"options": { +"jql": "=text ~ \"{{ $fromAI('title', 'the title of the current issue', 'string', '') }}\" AND status IN (\"In Progress\", \"Done\")" +}, +"operation": "getAll", +"descriptionType": "manual", +"toolDescription": "Call this tool to search for similar issues in JIRA." +}, +"credentials": { +"jiraSoftwareCloudApi": { +"id": "IH5V74q6PusewNjD", +"name": "Jira SW Cloud account" +} +}, +"typeVersion": 1 +}, +{ +"id": "573c1b75-35ae-40f0-aa6e-c1372f83569b", +"name": "Query KnowledgeBase", +"type": "n8n-nodes-base.notionTool", +"position": [ +2280, +420 +], +"parameters": { +"text": "={{ $fromAI('search_terms', 'relevant terms to search for information on the current issue', 'string', '') }}", +"limit": 4, +"options": {}, +"operation": "search", +"descriptionType": "manual", +"toolDescription": "Search the knowledgebase for information relevant to the issue." +}, +"credentials": { +"notionApi": { +"id": "iHBHe7ypzz4mZExM", +"name": "Notion account" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "1274f6ff-16d9-4d86-b75a-59755390a07c", +"name": "Report Unhappy Resolution", +"type": "n8n-nodes-base.slack", +"position": [ +2660, +-400 +], +"parameters": { +"text": "=", +"select": "channel", +"blocksUi": "={{\n{\n\t\"blocks\": [\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Hey there 👋\\nI found a unclosed ticket which was resolved but thread overall has a negative sentiment score. Please address or close the ticket.\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": `*[${$('Get Issue Metadata').item.json.key}] ${$('Get Issue Metadata').item.json.title}*\\n${$('KnowledgeBase Agent').item.json.output.short_summary_of_issue}\\n👤 <${$('Get Issue Metadata').item.json.reporter_url}|${$('Get Issue Metadata').item.json.reporter}> 📅 ${$('Get Issue Metadata').item.json.date} 🔗 <${$('Get Issue Metadata').item.json.url}|Link to Issue>\\n`\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"type\": \"divider\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"section\",\n\t\t\t\"text\": {\n\t\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\t\"text\": \"Thanks!\"\n\t\t\t}\n\t\t}\n\t]\n}\n}}", +"channelId": { +"__rl": true, +"mode": "list", +"value": "C07S0NQ04D7", +"cachedResultName": "n8n-jira" +}, +"messageType": "block", +"otherOptions": {} +}, +"credentials": { +"slackApi": { +"id": "VfK3js0YdqBdQLGP", +"name": "Slack account" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "3226d576-c3ae-444a-b0c5-ac797d25dd2e", +"name": "Classify Current Issue State", +"type": "@n8n/n8n-nodes-langchain.textClassifier", +"position": [ +1480, +-140 +], +"parameters": { +"options": {}, +"inputText": "=issue:\n{{ $('Simplify Thread For AI').item.json.topic }}\n\ncomments:\n{{ $('Simplify Thread For AI').item.json.thread.join('\\n') || 'There are no comments' }}", +"categories": { +"categories": [ +{ +"category": "resolved", +"description": "There are human comments and a resolution was found and/or accepted" +}, +{ +"category": "pending more information", +"description": "There are human comments but no resolution has been reached yet" +}, +{ +"category": "still waiting", +"description": "Reporter is still waiting on a response. Ignoring automated messages, there are no comments." +} +] +} +}, +"executeOnce": false, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Join Comments": { +"main": [ +[ +{ +"node": "Simplify Thread For AI", +"type": "main", +"index": 0 +} +] +] +}, +"Reply to Issue": { +"main": [ +[ +{ +"node": "Close Issue2", +"type": "main", +"index": 0 +} +] +] +}, +"Solution Found?": { +"main": [ +[ +{ +"node": "Reply to Issue", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Notify Slack Channel", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "Get List of Unresolved Long Lived Issues", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Classify Current Issue State", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Find Simlar Issues": { +"ai_tool": [ +[ +{ +"node": "KnowledgeBase Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Get Issue Comments": { +"main": [ +[ +{ +"node": "Join Comments", +"type": "main", +"index": 0 +} +] +] +}, +"Get Issue Metadata": { +"main": [ +[ +{ +"node": "Get Issue Comments", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "KnowledgeBase Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model3": { +"ai_languageModel": [ +[ +{ +"node": "Issue Reminder Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model4": { +"ai_languageModel": [ +[ +{ +"node": "Customer Satisfaction Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"KnowledgeBase Agent": { +"main": [ +[ +{ +"node": "Solution Found?", +"type": "main", +"index": 0 +} +] +] +}, +"Query KnowledgeBase": { +"ai_tool": [ +[ +{ +"node": "KnowledgeBase Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"Issue Reminder Agent": { +"main": [ +[ +{ +"node": "Send Reminder", +"type": "main", +"index": 0 +} +] +] +}, +"Notify Slack Channel": { +"main": [ +[ +{ +"node": "Reply to Issue", +"type": "main", +"index": 0 +} +] +] +}, +"Add Autoclose Message": { +"main": [ +[ +{ +"node": "Close Issue", +"type": "main", +"index": 0 +} +] +] +}, +"Simplify Thread For AI": { +"main": [ +[ +{ +"node": "Classify Current Issue State", +"type": "main", +"index": 0 +} +] +] +}, +"Last Message is Not Bot": { +"main": [ +[ +{ +"node": "Issue Reminder Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Ask For Feedback Message": { +"main": [ +[ +{ +"node": "Close Issue", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Get Issue Metadata", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "KnowledgeBase Agent", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Customer Satisfaction Agent": { +"main": [ +[ +{ +"node": "Ask For Feedback Message", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Add Autoclose Message", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Report Unhappy Resolution", +"type": "main", +"index": 0 +} +] +] +}, +"Classify Current Issue State": { +"main": [ +[ +{ +"node": "Customer Satisfaction Agent", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Last Message is Not Bot", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "KnowledgeBase Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Get List of Unresolved Long Lived Issues": { +"main": [ +[ +{ +"node": "Execute Workflow", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Image Validation Tasks using AI Vision.txt b/Automate Image Validation Tasks using AI Vision.txt new file mode 100644 index 0000000..4865920 --- /dev/null +++ b/Automate Image Validation Tasks using AI Vision.txt @@ -0,0 +1,284 @@ +{ +"meta": { +"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" +}, +"nodes": [ +{ +"id": "6c78b4c7-993b-410d-93e7-e11b3052e53b", +"name": "When clicking ‘Test workflow’", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +0, +420 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "c2ab6497-6d6d-483b-bd43-494ae95394c0", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +1440, +600 +], +"parameters": { +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"is_valid\": { \"type\": \"boolean\" },\n \"photo_description\": {\n \"type\": \"string\",\n \"description\": \"describe the appearance of the person(s), object(s) if any and the background in the image. Mention any colours of each if possible.\"\n },\n\t\t\"reasons\": {\n \"type\": \"array\",\n \"items\": { \"type\": \"string\" }\n }\n\t}\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "b23f5298-17c7-49ac-a8ca-78e006b2d294", +"name": "Photo URLs", +"type": "n8n-nodes-base.set", +"position": [ +360, +380 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "6baa3e08-8957-454e-8ee9-d5414a0ff990", +"name": "data", +"type": "array", +"value": "={{\n[\n{\n \"name\": \"portrait_1\",\n \"url\": \"https://drive.google.com/file/d/1zs963iFkO-3g2rKak8Hcy555h55D8gjF/view?usp=sharing\"\n},\n{\n \"name\": \"portrait_2\",\n \"url\": \"https://drive.google.com/file/d/19FyDcs68dZauQSEf6SEulJMag51SPsFy/view?usp=sharing\"\n},\n{\n \"name\": \"portrait_3\",\n \"url\": \"https://drive.google.com/file/d/1gbXjfNYE7Tvuw_riFmHMKoqPPu696VfW/view?usp=sharing\",\n\n},\n{\n \"name\": \"portrait_4\",\n \"url\": \"https://drive.google.com/file/d/1s19hYdxgfMkrnU25l6YIDq-myQr1tQMa/view?usp=sharing\"\n},\n{\n \"name\": \"portrait_5\",\n \"url\": \"https://drive.google.com/file/d/193FqIXJWAKj6O2SmOj3cLBfypHBkgdI5/view?usp=sharing\"\n}\n]\n}}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "8d445f73-dff7-485b-87e2-5b64da09cbf0", +"name": "Photos To List", +"type": "n8n-nodes-base.splitOut", +"position": [ +520, +380 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "data" +}, +"typeVersion": 1 +}, +{ +"id": "7fb3b829-88a7-42ec-abfd-3ddaa042c916", +"name": "Download Photos", +"type": "n8n-nodes-base.googleDrive", +"position": [ +680, +380 +], +"parameters": { +"fileId": { +"__rl": true, +"mode": "url", +"value": "={{ $json.url }}" +}, +"options": {}, +"operation": "download" +}, +"credentials": { +"googleDriveOAuth2Api": { +"id": "yOwz41gMQclOadgu", +"name": "Google Drive account" +} +}, +"typeVersion": 3 +}, +{ +"id": "b8644f6d-691f-49bc-b0fe-33a68c59638d", +"name": "Resize For AI", +"type": "n8n-nodes-base.editImage", +"position": [ +1060, +440 +], +"parameters": { +"width": 1024, +"height": 1024, +"options": {}, +"operation": "resize", +"resizeOption": "onlyIfLarger" +}, +"typeVersion": 1 +}, +{ +"id": "ecb266f2-0d2d-4cbe-a641-26735f0bdf18", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +280, +180 +], +"parameters": { +"color": 7, +"width": 594, +"height": 438, +"content": "## 1. Import Photos To Validate\n[Read more about using Google Drive](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googledrive)\n\nIn this demonstration, we'll import 5 different portraits to test our AI vision model. For convenience, we'll use Google Drive but feel free to swap this out for other sources such as other storage or by using webhooks." +}, +"typeVersion": 1 +}, +{ +"id": "a1034923-0905-4cdd-a6bf-21d28aa3dd71", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +900, +180 +], +"parameters": { +"color": 7, +"width": 774, +"height": 589.25, +"content": "## 2. Verify Passport Photo Validity Using AI Vision Model\n[Learn more about Basic LLM Chain](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nVerifying if a photo is suitable for a passport photo is a great use-case for AI vision and to automate the process is an equally great use-case for using n8n. Here's we've pasted in the UK governments guidelines copied from gov.uk and have asked the AI to validate the incoming photos following those rules. A structured output parser is used to simplify the AI response which can be used to update a database or backend of your choosing." +}, +"typeVersion": 1 +}, +{ +"id": "af231ee5-adff-4d27-ba5f-8c04ddd4892d", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-140, +0 +], +"parameters": { +"width": 386, +"height": 610.0104651162792, +"content": "## Try It Out!\n\n### This workflow takes a portrait and verifies if it makes for a valid passport photo. It achieves this by using an AI vision model following the UK government guidance.\n\nOpenAI's vision model was found to perform well for understanding photographs and so is recommended for this type of workflow. However, any capable vision model should work.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!" +}, +"typeVersion": 1 +}, +{ +"id": "e07e1655-2683-4e21-b2b7-e0c0bfb569c0", +"name": "Passport Photo Validator", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +1240, +440 +], +"parameters": { +"text": "Assess if the image is a valid according to the passport photo criteria as set by the UK Government.", +"messages": { +"messageValues": [ +{ +"message": "=You help verify passport photo validity.\n\n## Rules for digital photos\nhttps://www.gov.uk/photos-for-passports\n\n### The quality of your digital photo\nYour photo must be:\n* clear and in focus\n* in colour\n* unaltered by computer software\n* at least 600 pixels wide and 750 pixels tall\n* at least 50KB and no more than 10MB\n\n### What your digital photo must show\nThe digital photo must:\n* contain no other objects or people\n* be taken against a plain white or light-coloured background\n* be in clear contrast to the background\n* not have ‘red eye’\n* If you’re using a photo taken on your own device, include your head, shoulders and upper body. Do not crop your photo - it will be done for you.\n\nIn your photo you must:\n* be facing forwards and looking straight at the camera\n* have a plain expression and your mouth closed\n* have your eyes open and visible\n* not have hair in front of your eyes\n* not have a head covering (unless it’s for religious or medical reasons)\n* not have anything covering your face\n* not have any shadows on your face or behind you - shadows on light background are okay\n* Do not wear glasses in your photo unless you have to do so. If you must wear glasses, they cannot be sunglasses or tinted glasses, and you must make sure your eyes are not covered by the frames or any glare, reflection or shadow.\n\n### Photos of babies and children\n* Children must be on their own in the picture. Babies must not be holding toys or using dummies.\n* Children under 6 do not have to be looking directly at the camera or have a plain expression.\n* Children under one do not have to have their eyes open. You can support their head with your hand, but your hand must not be visible in the photo.\n* Children under one should lie on a plain light-coloured sheet. Take the photo from above.\n\n" +}, +{ +"type": "HumanMessagePromptTemplate", +"messageType": "imageBinary" +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.4 +}, +{ +"id": "0a36ba22-90b2-4abf-943b-c1cc8e7317d5", +"name": "Google Gemini Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini", +"position": [ +1240, +600 +], +"parameters": { +"options": {}, +"modelName": "models/gemini-1.5-pro-latest" +}, +"credentials": { +"googlePalmApi": { +"id": "dSxo6ns5wn658r8N", +"name": "Google Gemini(PaLM) Api account" +} +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Photo URLs": { +"main": [ +[ +{ +"node": "Photos To List", +"type": "main", +"index": 0 +} +] +] +}, +"Resize For AI": { +"main": [ +[ +{ +"node": "Passport Photo Validator", +"type": "main", +"index": 0 +} +] +] +}, +"Photos To List": { +"main": [ +[ +{ +"node": "Download Photos", +"type": "main", +"index": 0 +} +] +] +}, +"Download Photos": { +"main": [ +[ +{ +"node": "Resize For AI", +"type": "main", +"index": 0 +} +] +] +}, +"Google Gemini Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Passport Photo Validator", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Passport Photo Validator", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"When clicking ‘Test workflow’": { +"main": [ +[ +{ +"node": "Photo URLs", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate LinkedIn Outreach with Notion and OpenAI.txt b/Automate LinkedIn Outreach with Notion and OpenAI.txt new file mode 100644 index 0000000..0ee4e51 --- /dev/null +++ b/Automate LinkedIn Outreach with Notion and OpenAI.txt @@ -0,0 +1,362 @@ +{ +"id": "mb2MU4xOaT3NrvqN", +"meta": { +"instanceId": "e7a28cc5c8c9de1976820e0f309940cf456344d9daf5360a4975186f3d8a107f", +"templateCredsSetupCompleted": true +}, +"name": "Automate LinkedIn Posts with AI", +"tags": [], +"nodes": [ +{ +"id": "7e8ec5cc-0216-4897-8a40-c44f9bbe5a9b", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +580, +540 +], +"parameters": { +"rule": { +"interval": [ +{ +"triggerAtHour": 15 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "dbde804d-9c84-4023-9e05-7506cd38a460", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +760, +225.26841303066982 +], +"parameters": { +"color": 6, +"width": 652.1201853643956, +"height": 542.0867486896091, +"content": "## Fetch the day's post from my Notion database\nA Notion _\"database\"_ is just a table on a Notion Page.\nThis table will have various rows, for which a minimum of three columns are required:\n- Name\n- Status\n- Date\n\nThe Date column is the most important, which will dictate when that row from your Notion table containing the text should be posted.\n\nNOTE: each post is required to have a copy and pasted image!" +}, +"typeVersion": 1 +}, +{ +"id": "95205e81-e28d-48f9-b3fb-bcf361f7799e", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1520, +220 +], +"parameters": { +"width": 860.9829802912225, +"height": 540.7357881640437, +"content": "## Format Post\nSend the post to OpenAI, where it will attempt to ask your assistant how to take the incoming blob of text, and soup it up into something more palpable for LinkedIn engagement." +}, +"typeVersion": 1 +}, +{ +"id": "4bc2a550-a8ad-4b25-ac53-01413277e068", +"name": "Set post status to \"Done\"", +"type": "n8n-nodes-base.notion", +"position": [ +2760, +540 +], +"parameters": { +"pageId": { +"__rl": true, +"mode": "url", +"value": "={{ $('query entries from Notion table for today').item.json.url }}" +}, +"options": {}, +"resource": "databasePage", +"operation": "update", +"propertiesUi": { +"propertyValues": [ +{ +"key": "Status|status", +"statusValue": "Done" +} +] +} +}, +"credentials": { +"notionApi": { +"id": "nBu4zRArkldtNypO", +"name": "Notion account" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "31116f06-72ca-4219-9575-8efaefbff24b", +"name": "Post on LinkedIn", +"type": "n8n-nodes-base.linkedIn", +"position": [ +2500, +540 +], +"parameters": { +"text": "={{ $json.output }}", +"person": "_RmSSZc0jB", +"additionalFields": {}, +"shareMediaCategory": "IMAGE" +}, +"credentials": { +"linkedInOAuth2Api": { +"id": "fozSa4dLS6Jgbn4e", +"name": "LinkedIn account 2" +} +}, +"typeVersion": 1 +}, +{ +"id": "1bf0540d-a180-457a-a7d7-fb74c8119a52", +"name": "Combine text+image", +"type": "n8n-nodes-base.merge", +"position": [ +2100, +540 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "mergeByPosition" +}, +"typeVersion": 2.1 +}, +{ +"id": "f1fdf6f7-a75c-451b-8bce-ea581b4b6197", +"name": "Fetch image from post", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1640, +620 +], +"parameters": { +"url": "={{ $json.url[0] }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "00e2bbcb-bac0-4a7e-9892-59f41a26ce9d", +"name": "Reformat Post Text", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1620, +440 +], +"parameters": { +"text": "=Thank you kindly for your help, please refer to the following LinkedIn post, and output a reformatted version employing thoroughly thought-out paragraph breaks, and lists if present:\n```\n{{ $json.content.join(\" \") }}\n```", +"prompt": "define", +"options": {}, +"resource": "assistant", +"assistantId": { +"__rl": true, +"mode": "list", +"value": "asst_J1KuOx5wTLrjEHuy5q94jEgh", +"cachedResultName": "LinkedIn Post Reviewer" +} +}, +"credentials": { +"openAiApi": { +"id": "Gxn0kNMCREcTNGcB", +"name": "OpenAi account 2" +} +}, +"typeVersion": 1.3 +}, +{ +"id": "119d7fc7-ed62-4a73-916e-8baf19ab1d86", +"name": "get all content from post page", +"type": "n8n-nodes-base.notion", +"position": [ +1020, +540 +], +"parameters": { +"blockId": { +"__rl": true, +"mode": "url", +"value": "={{ $json.url }}" +}, +"resource": "block", +"operation": "getAll", +"returnAll": true +}, +"credentials": { +"notionApi": { +"id": "nBu4zRArkldtNypO", +"name": "Notion account" +} +}, +"typeVersion": 2.2 +}, +{ +"id": "461d4dd2-a91a-4219-bd20-6dd3398d4274", +"name": "Pull together all text blocks + image", +"type": "n8n-nodes-base.aggregate", +"position": [ +1240, +540 +], +"parameters": { +"options": {}, +"fieldsToAggregate": { +"fieldToAggregate": [ +{ +"fieldToAggregate": "content" +}, +{ +"fieldToAggregate": "image.file.url" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "72052eec-c180-4da5-ba15-1a69a7ce6892", +"name": "query entries from Notion table for today", +"type": "n8n-nodes-base.notion", +"position": [ +800, +540 +], +"parameters": { +"filters": { +"conditions": [ +{ +"key": "Date|date", +"date": "={{ $today.format(\"yyyy/mM/dd\") }}", +"condition": "equals" +} +] +}, +"options": {}, +"resource": "databasePage", +"operation": "getAll", +"databaseId": { +"__rl": true, +"mode": "list", +"value": "9aba7f55-a7de-4329-9d5b-6d127937fa49", +"cachedResultUrl": "https://www.notion.so/9aba7f55a7de43299d5b6d127937fa49", +"cachedResultName": "LinkedIn Posts example" +}, +"filterType": "manual" +}, +"credentials": { +"notionApi": { +"id": "nBu4zRArkldtNypO", +"name": "Notion account" +} +}, +"typeVersion": 2.2 +} +], +"active": true, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "35f9b7b6-0e60-495f-826d-af7040e7de1f", +"connections": { +"Post on LinkedIn": { +"main": [ +[ +{ +"node": "Set post status to \"Done\"", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "query entries from Notion table for today", +"type": "main", +"index": 0 +} +] +] +}, +"Combine text+image": { +"main": [ +[ +{ +"node": "Post on LinkedIn", +"type": "main", +"index": 0 +} +] +] +}, +"Reformat Post Text": { +"main": [ +[ +{ +"node": "Combine text+image", +"type": "main", +"index": 0 +} +] +] +}, +"Fetch image from post": { +"main": [ +[ +{ +"node": "Combine text+image", +"type": "main", +"index": 1 +} +] +] +}, +"get all content from post page": { +"main": [ +[ +{ +"node": "Pull together all text blocks + image", +"type": "main", +"index": 0 +} +] +] +}, +"Pull together all text blocks + image": { +"main": [ +[ +{ +"node": "Fetch image from post", +"type": "main", +"index": 0 +}, +{ +"node": "Reformat Post Text", +"type": "main", +"index": 0 +} +] +] +}, +"query entries from Notion table for today": { +"main": [ +[ +{ +"node": "get all content from post page", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Pinterest Analysis & AI-Powered Content Suggestions With Pinterest API.txt b/Automate Pinterest Analysis & AI-Powered Content Suggestions With Pinterest API.txt new file mode 100644 index 0000000..99ddd82 --- /dev/null +++ b/Automate Pinterest Analysis & AI-Powered Content Suggestions With Pinterest API.txt @@ -0,0 +1,527 @@ +{ +"id": "gP9EsxKN5agUGzDS", +"meta": { +"instanceId": "73d9d5380db181d01f4e26492c771d4cb5c4d6d109f18e2621cf49cac4c50763", +"templateCredsSetupCompleted": true +}, +"name": "Automate Pinterest Analysis & AI-Powered Content Suggestions With Pinterest API", +"tags": [], +"nodes": [ +{ +"id": "7f582bb4-97cd-458e-a7b7-b518c5b8a4ca", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +540, +-260 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "95QGJD3XSz0piaNU", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "c6772882-468c-4391-a259-93e52daf49d4", +"name": "Airtable2", +"type": "n8n-nodes-base.airtableTool", +"position": [ +700, +-260 +], +"parameters": { +"id": "=", +"base": { +"__rl": true, +"mode": "list", +"value": "appfsNi1QEhw6WvXK", +"cachedResultUrl": "https://airtable.com/appfsNi1QEhw6WvXK", +"cachedResultName": "Pinterest_Metrics" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tbl9Dxdrwx5QZGFnp", +"cachedResultUrl": "https://airtable.com/appfsNi1QEhw6WvXK/tbl9Dxdrwx5QZGFnp", +"cachedResultName": "Pinterest_Organic_Data" +}, +"options": {} +}, +"credentials": { +"airtableTokenApi": { +"id": "0ApVmNsLu7aFzQD6", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "85ea8bec-14c8-4277-b2e3-eb145db0713a", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +920, +-280 +], +"parameters": { +"model": { +"__rl": true, +"mode": "list", +"value": "gpt-4o-mini" +}, +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "95QGJD3XSz0piaNU", +"name": "OpenAi account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "b8f7d0d6-b58f-4a41-a15d-99f4d838bb8c", +"name": "8:00am Morning Scheduled Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +-660, +-140 +], +"parameters": { +"rule": { +"interval": [ +{ +"daysInterval": 7, +"triggerAtHour": 8 +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "593a320d-825e-42f9-8ab6-adafd5288fa5", +"name": "Pull List of Pinterest Pins From Account", +"type": "n8n-nodes-base.httpRequest", +"position": [ +-340, +-140 +], +"parameters": { +"url": "https://api.pinterest.com/v5/pins", +"options": { +"redirect": { +"redirect": {} +} +}, +"sendBody": true, +"sendHeaders": true, +"bodyParameters": { +"parameters": [ +{} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "Authorization", +"value": "Bearer " +} +] +} +}, +"typeVersion": 4.2 +}, +{ +"id": "1e6d00fe-2b32-4d46-a230-063254ebab74", +"name": "Update Data Field To Include Organic", +"type": "n8n-nodes-base.code", +"position": [ +-20, +-140 +], +"parameters": { +"jsCode": "// Initialize an array to hold the output formatted for Airtable\nconst outputItems = [];\n\nfor (const item of $input.all()) {\n if (item.json.items && Array.isArray(item.json.items)) {\n for (const subItem of item.json.items) {\n // Construct an object with only the required fields for Airtable\n outputItems.push({\n id: subItem.id || null,\n created_at: subItem.created_at || null,\n title: subItem.title || null,\n description: subItem.description || null,\n link: subItem.link || null,\n type: \"Organic\" // Assign the value \"Organic\" to the 'Type' field\n });\n }\n }\n}\n\n// Return the structured output\nreturn outputItems;\n" +}, +"typeVersion": 2 +}, +{ +"id": "539de144-dc67-4b14-b58e-2896edb1c3e6", +"name": "Create Record Within Pinterest Data Table", +"type": "n8n-nodes-base.airtable", +"position": [ +260, +-140 +], +"parameters": { +"base": { +"__rl": true, +"mode": "list", +"value": "appfsNi1QEhw6WvXK", +"cachedResultUrl": "https://airtable.com/appfsNi1QEhw6WvXK", +"cachedResultName": "Pinterest_Metrics" +}, +"table": { +"__rl": true, +"mode": "list", +"value": "tbl9Dxdrwx5QZGFnp", +"cachedResultUrl": "https://airtable.com/appfsNi1QEhw6WvXK/tbl9Dxdrwx5QZGFnp", +"cachedResultName": "Pinterest_Organic_Data" +}, +"columns": { +"value": { +"link": "={{ $json.link }}", +"type": "={{ $json.type }}", +"title": "={{ $json.title }}", +"pin_id": "={{ $json.id }}", +"created_at": "={{ $json.created_at }}", +"description": "={{ $json.description }}" +}, +"schema": [ +{ +"id": "id", +"type": "string", +"display": true, +"removed": false, +"readOnly": true, +"required": false, +"displayName": "id", +"defaultMatch": true +}, +{ +"id": "pin_id", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "pin_id", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "created_at", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "created_at", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "title", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "title", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "description", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "description", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "link", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "link", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "type", +"type": "string", +"display": true, +"removed": false, +"readOnly": false, +"required": false, +"displayName": "type", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "active7DayUsers", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "active7DayUsers", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "sessions", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "sessions", +"defaultMatch": false, +"canBeUsedToMatch": true +}, +{ +"id": "userEngagementDuration", +"type": "string", +"display": true, +"removed": true, +"readOnly": false, +"required": false, +"displayName": "userEngagementDuration", +"defaultMatch": false, +"canBeUsedToMatch": true +} +], +"mappingMode": "defineBelow", +"matchingColumns": [ +"id" +], +"attemptToConvertTypes": false, +"convertFieldsToString": false +}, +"options": {}, +"operation": "upsert" +}, +"credentials": { +"airtableTokenApi": { +"id": "0ApVmNsLu7aFzQD6", +"name": "Airtable Personal Access Token account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "250f5121-437e-4bff-82af-95a156126127", +"name": "Pinterest Analysis AI Agent", +"type": "@n8n/n8n-nodes-langchain.agent", +"position": [ +540, +-440 +], +"parameters": { +"text": "You are a data analysis expert. You will pull data from the table and provide any information in regards to trends in the data. \n\nYour output should be suggestions of new pins that we can post to reach the target audiences. \n\nAnalyze the data and just summary of the pin suggestions that the team should build. ", +"options": {}, +"promptType": "define" +}, +"typeVersion": 1.7 +}, +{ +"id": "181e9d89-c0f9-4de2-bdce-9359b967157c", +"name": "Pinterest Data Analysis Summary LLM", +"type": "@n8n/n8n-nodes-langchain.chainSummarization", +"position": [ +900, +-440 +], +"parameters": { +"options": { +"summarizationMethodAndPrompts": { +"values": { +"prompt": "=Write a concise summary of the following:\n\n\n\"{{ $json.output }}\"\n\n\nCONCISE SUMMARY:" +} +} +} +}, +"typeVersion": 2 +}, +{ +"id": "432e7bd7-36b4-4903-8e93-c8bd6e140a04", +"name": "Send Marketing Trends & Pinterest Analysis To Marketing Manager", +"type": "n8n-nodes-base.gmail", +"position": [ +1220, +-440 +], +"webhookId": "f149c1b5-c028-4dff-9d22-a72951f2ef91", +"parameters": { +"sendTo": "john.n.foster1@gmail.com", +"message": "={{ $json.response.text }}", +"options": {}, +"subject": "Pinterest Trends & Suggestions" +}, +"credentials": { +"gmailOAuth2": { +"id": "pIXP1ZseBP4Z5CCp", +"name": "Gmail account" +} +}, +"executeOnce": true, +"typeVersion": 2.1 +}, +{ +"id": "dadfb22a-b1d3-459d-a332-5a2c52fd4ca0", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-740, +-320 +], +"parameters": { +"color": 5, +"width": 280, +"height": 440, +"content": "Scheduled trigger at 8:00am to start the workflow. \n\nThis can be updated to your schedule preference as an email with marketing trends can be sent to best fit one's schedule. " +}, +"typeVersion": 1 +}, +{ +"id": "3b156d97-11bf-4d8a-9bd9-c1e23a0592d8", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-420, +-300 +], +"parameters": { +"color": 6, +"width": 860, +"height": 360, +"content": "Scheduled trigger begin process to gather Pinterest Pin data and store them within Airtable. This data can be referenced or analyzed accordingly. \n\n*If you would like to bring in Pinterest Ads data, the data is already labeled as Organic.\n\nThis is perfect for those who are creating content calendars to understand content scheduling." +}, +"typeVersion": 1 +}, +{ +"id": "65586422-a631-477b-833d-5c445b1be744", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +480, +-580 +], +"parameters": { +"color": 4, +"width": 940, +"height": 460, +"content": "AI Agent will go through Pinterest Pins and analyze any data and trends to be able to reach target audience. The data is then summarized within the Summary LLM.\n\nThe summarized results are then sent to the Marketing Manager within an email to help lead content creation efforts. " +}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "d6f64ee7-ae49-4a6b-8bf8-9a709c580357", +"connections": { +"Airtable2": { +"ai_tool": [ +[ +{ +"node": "Pinterest Analysis AI Agent", +"type": "ai_tool", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Pinterest Analysis AI Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "Pinterest Data Analysis Summary LLM", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Pinterest Analysis AI Agent": { +"main": [ +[ +{ +"node": "Pinterest Data Analysis Summary LLM", +"type": "main", +"index": 0 +} +] +] +}, +"8:00am Morning Scheduled Trigger": { +"main": [ +[ +{ +"node": "Pull List of Pinterest Pins From Account", +"type": "main", +"index": 0 +} +] +] +}, +"Pinterest Data Analysis Summary LLM": { +"main": [ +[ +{ +"node": "Send Marketing Trends & Pinterest Analysis To Marketing Manager", +"type": "main", +"index": 0 +} +] +] +}, +"Update Data Field To Include Organic": { +"main": [ +[ +{ +"node": "Create Record Within Pinterest Data Table", +"type": "main", +"index": 0 +}, +{ +"node": "Pinterest Analysis AI Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Pull List of Pinterest Pins From Account": { +"main": [ +[ +{ +"node": "Update Data Field To Include Organic", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Sales Meeting Prep with AI & APIFY Sent To WhatsApp.txt b/Automate Sales Meeting Prep with AI & APIFY Sent To WhatsApp.txt new file mode 100644 index 0000000..881b09e --- /dev/null +++ b/Automate Sales Meeting Prep with AI & APIFY Sent To WhatsApp.txt @@ -0,0 +1,1859 @@ +{ +"meta": { +"instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9" +}, +"nodes": [ +{ +"id": "201ef455-2d65-4563-8ec1-318211b1fa6a", +"name": "Get Message Contents", +"type": "n8n-nodes-base.gmail", +"position": [ +2080, +500 +], +"webhookId": "fa1d496f-17fa-4e50-bae9-84ca85ed4502", +"parameters": { +"simple": false, +"options": {}, +"messageId": "={{ $json.id }}", +"operation": "get" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1 +}, +{ +"id": "ded010af-e977-4c47-87dd-8221d601af74", +"name": "Simplify Emails", +"type": "n8n-nodes-base.set", +"position": [ +2240, +500 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "2006c806-42db-4457-84c2-35f59ed39018", +"name": "date", +"type": "string", +"value": "={{ $json.date }}" +}, +{ +"id": "872278d2-b97c-45ba-a9d3-162f154fe7dc", +"name": "subject", +"type": "string", +"value": "={{ $json.subject }}" +}, +{ +"id": "282f03e9-1d0f-4a17-b9ed-75b44171d4ee", +"name": "text", +"type": "string", +"value": "={{ $json.text }}" +}, +{ +"id": "9421776c-ff53-4490-b0e1-1e610534ba25", +"name": "from", +"type": "string", +"value": "={{ $json.from.value[0].name }} ({{ $json.from.value[0].address }})" +}, +{ +"id": "3b6716e8-5582-4da3-ae9d-e8dd1afad530", +"name": "to", +"type": "string", +"value": "={{ $json.to.value[0].name }} ({{ $json.to.value[0].address }})" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "816bf787-ff9c-4b97-80ac-4b0c6ae5638b", +"name": "Check For Upcoming Meetings", +"type": "n8n-nodes-base.googleCalendar", +"position": [ +526, +-180 +], +"parameters": { +"limit": 1, +"options": { +"orderBy": "startTime", +"timeMax": "={{ $now.toUTC().plus(1, 'hour') }}", +"timeMin": "={{ $now.toUTC() }}", +"singleEvents": true +}, +"calendar": { +"__rl": true, +"mode": "list", +"value": "c_5792bdf04bc395cbcbc6f7b754268245a33779d36640cc80a357711aa2f09a0a@group.calendar.google.com", +"cachedResultName": "n8n-events" +}, +"operation": "getAll" +}, +"credentials": { +"googleCalendarOAuth2Api": { +"id": "kWMxmDbMDDJoYFVK", +"name": "Google Calendar account" +} +}, +"typeVersion": 1.2 +}, +{ +"id": "234d5c79-bf40-44bb-8829-c6ccf8648359", +"name": "OpenAI Chat Model2", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +920, +-20 +], +"parameters": { +"model": "gpt-4o-2024-08-06", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "445aa0f4-d41a-4d46-aa2f-e79a9cdb04b5", +"name": "Extract Attendee Information", +"type": "@n8n/n8n-nodes-langchain.informationExtractor", +"position": [ +920, +-180 +], +"parameters": { +"text": "=start: {{ $json.start.dateTime }}\nmeeting url: {{ $json.hangoutLink }}\nsummary: {{ $json.summary }}\ndescription: {{ $json.description }}\norganiser: {{ $json.organizer.displayName }} ({{ $json.organizer.email }})\nattendees: {{ $json.attendees.filter(item => !item.organizer).map(item => item.email).join(',') }}", +"options": { +"systemPromptTemplate": "You are an expert extraction algorithm. Try to link any information found in the description to help fill in the attendee details.\nIf you do not know the value of an attribute asked to extract, you may omit the attribute's value." +}, +"schemaType": "manual", +"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"attendees\": {\n \"type\": \"array\",\n \"description\": \"list of attendees excluding the meeting organiser\",\n \"items\": {\n\t\t\t\"type\": \"object\",\n\t\t\t\"properties\": {\n\t\t\t \"name\": { \"type\": \"string\" },\n \"email\": { \"type\": \"string\" },\n \"linkedin_url\": { \"type\": \"string\" }\n\t\t\t}\n }\n\t\t}\n\t}\n}" +}, +"typeVersion": 1 +}, +{ +"id": "390743d8-acfd-4951-8901-212f162dcbb4", +"name": "Execute Workflow Trigger", +"type": "n8n-nodes-base.executeWorkflowTrigger", +"position": [ +920, +580 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "ea9c76a0-40a0-413a-a93a-ad99069d0d91", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2460, +640 +], +"parameters": { +"model": "gpt-4o-2024-08-06", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "8d9df9e4-1815-44a2-a6fc-a9af42a77153", +"name": "Get Last Correspondence", +"type": "n8n-nodes-base.gmail", +"position": [ +1740, +500 +], +"webhookId": "b00c960c-3689-4fa1-9f0f-7d6c9479f0c6", +"parameters": { +"limit": 1, +"filters": { +"sender": "={{ $json.email }}" +}, +"operation": "getAll" +}, +"credentials": { +"gmailOAuth2": { +"id": "Sf5Gfl9NiFTNXFWb", +"name": "Gmail account" +} +}, +"typeVersion": 2.1, +"alwaysOutputData": true +}, +{ +"id": "23c7161f-60e2-4a99-9279-ff1dca5efc1c", +"name": "OpenAI Chat Model1", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +4020, +1320 +], +"parameters": { +"model": "gpt-4o-2024-08-06", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "9ab535aa-bd8c-4bd6-a7a0-f7182d8d7123", +"name": "OpenAI Chat Model3", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +2720, +-20 +], +"parameters": { +"model": "gpt-4o-2024-08-06", +"options": {} +}, +"credentials": { +"openAiApi": { +"id": "8gccIjcuf3gvaoEr", +"name": "OpenAi account" +} +}, +"typeVersion": 1 +}, +{ +"id": "410acb11-a16c-4abd-9f10-7582168d100e", +"name": "WhatsApp Business Cloud", +"type": "n8n-nodes-base.whatsApp", +"position": [ +3360, +-140 +], +"parameters": { +"textBody": "={{ $json.text }}", +"operation": "send", +"phoneNumberId": "477115632141067", +"requestOptions": {}, +"additionalFields": {}, +"recipientPhoneNumber": "44123456789" +}, +"credentials": { +"whatsAppApi": { +"id": "9SFJPeqrpChOkAmw", +"name": "WhatsApp account" +} +}, +"typeVersion": 1 +}, +{ +"id": "a7e8195d-eb73-4acb-aae1-eb04f8290d24", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +180, +-400 +], +"parameters": { +"color": 7, +"width": 616.7897454470152, +"height": 449.1424626006906, +"content": "## 1. Periodically Search For Upcoming Meetings\n[Read about the Scheduled Trigger](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger)\n\nLet's use the Scheduled Trigger node to trigger our Assistant to notify about upcoming meetings. Here, we'll set it for 1 hour intervals to check for meetings scheduled in our Google Calendar. You may need to play with the intervals and frequency depending on how many meetings you typically have." +}, +"typeVersion": 1 +}, +{ +"id": "1aebb209-e440-4ef2-8527-381e5e70b4ea", +"name": "Schedule Trigger", +"type": "n8n-nodes-base.scheduleTrigger", +"position": [ +326, +-180 +], +"parameters": { +"rule": { +"interval": [ +{ +"field": "hours" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "95758053-fcc2-45c6-96c2-ec0bf89bcb82", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +820, +-520 +], +"parameters": { +"color": 7, +"width": 655.5654775604146, +"height": 670.4114154200236, +"content": "## 2. Extract Attendee Details From Invite\n[Learn more about the Information Extractor node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.information-extractor/)\n\nOnce we have our upcoming meeting, it'll be nice to prepare for it by reminding the user what the meeting is about and some context with the attendees. This will be the goal this template and of our assistant! However, first we'll need to extract some contact information of the attendees to do so.\n\nFor this demonstration, we'll assume that attendee's email and LinkedIn profile URLs are included in the meeting invite. We'll extract this information for each attendee using the Information Extractor node. This convenient node uses AI to parse and extract which saves us from writing complex pattern matching code otherwise.\n\nIn your own scenario, feel free to use your CRM to get this information instead." +}, +"typeVersion": 1 +}, +{ +"id": "bd17aed0-9c96-4301-b09b-e61a03ebc1ac", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1500, +-520 +], +"parameters": { +"color": 7, +"width": 1020.0959898041108, +"height": 670.8210817031078, +"content": "## 3. Fetch Recent Correspondance & LinkedIn Activity\n[Learn more about the Execute Workflow node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflow)\n\nAs both email fetching and LinkedIn scraping actions are quite complex, we'll split them out as subworkflow executions. Doing so (in my honest opinion), helps with development and maintainability of the template. Here, we'll make perform the research for all applicable attendees by making 2 calls to the subworkflow and merging them back into a single node at the end.\n\nHead over to the subworkflow (see below - step 3a) to see how we pull the summaries from Gmail and LinkedIn." +}, +"typeVersion": 1 +}, +{ +"id": "ae804039-32e0-4d2d-a2ef-a6e8d65f7ce2", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2547.540603371386, +-440 +], +"parameters": { +"color": 7, +"width": 610.3630186140072, +"height": 582.1201380897592, +"content": "## 4. Generate Pre-Meeting Notification\n[Read more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nNow that we have (1) our upcoming meeting details and (2) recent email and/or Linkedin summaries about our attendee, let's feed them into our LLM node to generate the best pre-meeting notification ever seen! Of course, we'll need to keep it short as we intend to send this notification via WhatsApp message but should you choose to use another channel such as email, feel free to adjust the length of the message which suits." +}, +"typeVersion": 1 +}, +{ +"id": "045eb1d9-fd80-4f9c-8218-ae66583d0186", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3180, +-360 +], +"parameters": { +"color": 7, +"width": 466.8967433831988, +"height": 454.24485615650235, +"content": "## 5. Send Notification via WhatsApp\n[Learn more about the WhatsApp node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.whatsapp)\n\nThe WhatsApp node is a super convenient way to send messages to WhatsApp which is one of the many messaging apps supported by n8n out of the box. Not using WhatsApp? Simply swap this our for Twilio, Telegram, Slack and others." +}, +"typeVersion": 1 +}, +{ +"id": "46d35c68-88d7-445f-9834-b8b37ce90619", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1740, +260 +], +"parameters": { +"color": 7, +"width": 519.1145893777881, +"height": 190.5042226526524, +"content": "## 3.2: Fetch Last Email Correspondance\n[Learn more about Gmail node](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.gmail)\n\nFetching our attendee's last email will definitely help the user \"pick up\" from when they last last off. To do this, we'll assume a Gmail user and use the Gmail node to filter messages by the attendee's email address." +}, +"typeVersion": 1 +}, +{ +"id": "fe1c751c-4879-482b-bb6f-89df23e1faa8", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1740, +860 +], +"parameters": { +"color": 7, +"width": 667.8619481635637, +"height": 259.7914017217902, +"content": "## 3.4 Scraping LinkedIn With [Apify.com](https://www.apify.com?fpr=414q6)\n[Learn more about Apify.com for Web Scraping](https://www.apify.com?fpr=414q6)\n\nTo get the attendee's recent LinkedIn activity, we'll need a webscraper capable of rendering the user's LinkedIn profile. We'll use [Apify.com](https://www.apify.com?fpr=414q6) which is a commercial web scraping service but has a very generous monthly free tier ($5/mo).\n\nWhile Apify offers a number of dedicated LinkedIn scrapers, we'll build our own which works by impersonating our own LinkedIn account using our login cookie - this can be obtained by inspecting network requests when logged into Linkedin. **Add your LinkedIn Cookie to the node below!**" +}, +"typeVersion": 1 +}, +{ +"id": "a648cf7d-b859-4fec-8ae7-6450c70e6333", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +920, +310 +], +"parameters": { +"color": 7, +"width": 572.0305871208889, +"height": 231.49547088049098, +"content": "## 3.1 Attendee Researcher SubWorkflow\n[Learn more about using Execute Workflow Trigger](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.executeworkflowtrigger/)\n\nThe Attendee Researcher SubWorkflow's aims to collect and summarize both an attendee's last correspondance with the user (if applicable) and the attendee's LinkedIn profile (if available). It uses the router pattern to handle both branches allowing for shorter execution chains. Using the Switch node, this subworkflow is either triggered to fetch emails or scrape LinkedIn but never both simultaneously." +}, +"typeVersion": 1 +}, +{ +"id": "8a8dbe4f-86b1-41a4-9b7e-3affdee8e524", +"name": "Return LinkedIn Success", +"type": "n8n-nodes-base.set", +"position": [ +4360, +1180 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "fc4b63a7-ad4d-49ff-9d42-715760910f6a", +"name": "linkedin_summary", +"type": "string", +"value": "={{ $json.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "537a399b-1f78-440b-abc4-ad2e91c5950a", +"name": "Return LinkedIn Error", +"type": "n8n-nodes-base.set", +"position": [ +2380, +1320 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "bf5a0781-3bad-4f63-a49c-273b03204747", +"name": "linkedin_summary", +"type": "string", +"value": "No activities found." +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "a68e7df7-8467-46e2-8ea8-fcf270755d12", +"name": "Return Email Error", +"type": "n8n-nodes-base.set", +"position": [ +2080, +680 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9a7efc9e-26b0-48c9-83aa-ae989f20b1df", +"name": "email_summary", +"type": "string", +"value": "No correspondance found." +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "00df2b18-22ca-48d6-b053-12fe502effc5", +"name": "Return Email Success", +"type": "n8n-nodes-base.set", +"position": [ +2800, +500 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "fc4b63a7-ad4d-49ff-9d42-715760910f6a", +"name": "email_summary", +"type": "object", +"value": "={{ $json.text }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "cdae9f9f-11c0-4f26-9ba1-5d5ed279ebfc", +"name": "Set Route Email", +"type": "n8n-nodes-base.set", +"position": [ +1600, +-260 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ Object.assign({ \"route\": \"email\" }, $json) }}" +}, +"typeVersion": 3.4 +}, +{ +"id": "b01371f6-8871-4ad9-866d-888e22e7908e", +"name": "Set Route Linkedin", +"type": "n8n-nodes-base.set", +"position": [ +1600, +-100 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ Object.assign({ \"route\": \"linkedin\" }, $json) }}" +}, +"typeVersion": 3.4 +}, +{ +"id": "c4907171-b239-46a6-a0b0-6bf66570005f", +"name": "Router", +"type": "n8n-nodes-base.switch", +"position": [ +1100, +580 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "email", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.route }}", +"rightValue": "email" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "linkedin", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "ba71a258-de67-4f61-a24a-33c86bd4c4f5", +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.route }}", +"rightValue": "linkedin" +} +] +}, +"renameOutput": true +} +] +}, +"options": {} +}, +"typeVersion": 3.2 +}, +{ +"id": "45554355-57ad-464d-b768-5b00d707fc58", +"name": "Return LinkedIn Error1", +"type": "n8n-nodes-base.set", +"position": [ +1440, +870 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "bf5a0781-3bad-4f63-a49c-273b03204747", +"name": "linkedin_summary", +"type": "string", +"value": "No activities found." +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "05b04c17-eeeb-42f2-8d94-bc848889f17c", +"name": "Has Emails?", +"type": "n8n-nodes-base.if", +"position": [ +1900, +500 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "ff11640a-33e4-4695-a62c-7dcab57f0ae5", +"operator": { +"type": "object", +"operation": "empty", +"singleValue": true +}, +"leftValue": "={{ $json }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "c24aca66-6222-46ae-bb9b-1838b01f3100", +"name": "Return Email Error1", +"type": "n8n-nodes-base.set", +"position": [ +1440, +700 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9a7efc9e-26b0-48c9-83aa-ae989f20b1df", +"name": "email_summary", +"type": "string", +"value": "No correspondance found." +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "22f3ccbf-19a2-4ca5-ba23-f91963b52c0a", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2560, +920 +], +"parameters": { +"color": 7, +"width": 682.7350931085596, +"height": 219.59936012669806, +"content": "## 3.5: Extract LinkedIn Profile & Recent Activity\n[Learn more about the HTML node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.html)\n\nOnce we have our scraped LinkedIn profile, it's just a simple case of parsing and extracting the relevant sections from the page.\nFor the purpose of our workflow, we'll only need the \"About\" and \"Activity\" sections which we'll pull out of the page using a series of HTML nodes. Feel free to extract other sections to suit your needs! Once extracted, we'll combine the about and activities data in preparation of sending it to our LLM." +}, +"typeVersion": 1 +}, +{ +"id": "49b1fc8f-1259-4596-84b0-b37fae1c098c", +"name": "Sections To List", +"type": "n8n-nodes-base.splitOut", +"position": [ +2720, +1180 +], +"parameters": { +"options": { +"destinationFieldName": "data" +}, +"fieldToSplitOut": "sections" +}, +"typeVersion": 1 +}, +{ +"id": "875b278d-44c6-4315-87e3-459a90799a9b", +"name": "Set LinkedIn Cookie", +"type": "n8n-nodes-base.set", +"position": [ +1800, +1180 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "b4354c00-cc1a-4a55-8b44-6ba4854cc6ba", +"name": "linkedin_profile_url", +"type": "string", +"value": "={{ $json.linkedin_url }}" +}, +{ +"id": "4888db89-2573-4246-8ab9-c106a7fe5f38", +"name": "linkedin_cookies", +"type": "string", +"value": "" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "91da49ab-86a1-4539-b673-106b9edaeae9", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1400, +1240 +], +"parameters": { +"color": 3, +"width": 308.16846950517856, +"height": 110.18457997698513, +"content": "### Be aware of LinkedIn T&Cs!\nFor production, you may want to consider not using your main Linkedin account if you can help it!" +}, +"typeVersion": 1 +}, +{ +"id": "7abd390f-36a6-49af-b190-5bb720bd2ae8", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1740, +1152 +], +"parameters": { +"width": 209.84856156501735, +"height": 301.5806674338321, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n### 🚨 Input Required!\nYou need to add your cuurent linkedIn Cookies here to continue." +}, +"typeVersion": 1 +}, +{ +"id": "40dfb438-76c2-40b5-8945-94dcf7cafcf7", +"name": "Attendees to List", +"type": "n8n-nodes-base.splitOut", +"position": [ +1260, +-180 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "output.attendees" +}, +"typeVersion": 1 +}, +{ +"id": "cc7f8416-6ea1-4425-a320-3f8217d2ad4e", +"name": "Merge Attendee with Summaries", +"type": "n8n-nodes-base.set", +"position": [ +2160, +-180 +], +"parameters": { +"mode": "raw", +"options": {}, +"jsonOutput": "={{ Object.assign({}, $('Attendees to List').item.json, $json) }}" +}, +"typeVersion": 3.4 +}, +{ +"id": "459c5f2b-5dd5-491f-8bed-475ae5af7ac0", +"name": "Has Email Address?", +"type": "n8n-nodes-base.if", +"position": [ +1280, +580 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1382e335-bfae-4665-a2ee-a05496a7b463", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.email }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "610e9849-f06c-4534-a269-d1982dcab259", +"name": "Has LinkedIn URL?", +"type": "n8n-nodes-base.if", +"position": [ +1280, +750 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "1382e335-bfae-4665-a2ee-a05496a7b463", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.linkedin_url }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "43e5192e-c1b0-4d71-8d0e-aa466aa9930c", +"name": "Get Correspondance", +"type": "n8n-nodes-base.executeWorkflow", +"onError": "continueRegularOutput", +"position": [ +1780, +-260 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": true +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "4662f928-d38b-42e1-8a70-5676eb638ce1", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +2000, +-180 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "3eaf5d5b-d99c-4f9f-beaa-53b859bf482e", +"name": "Aggregate Attendees", +"type": "n8n-nodes-base.aggregate", +"position": [ +2340, +-180 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData", +"destinationFieldName": "attendees" +}, +"typeVersion": 1 +}, +{ +"id": "752afdd3-0561-4e53-8b18-391741a2f43b", +"name": "Activities To Array", +"type": "n8n-nodes-base.aggregate", +"position": [ +3680, +1360 +], +"parameters": { +"options": {}, +"aggregate": "aggregateAllItemData", +"destinationFieldName": "activity" +}, +"typeVersion": 1 +}, +{ +"id": "a35dc751-62a0-4f5c-92cb-2801d060c613", +"name": "Extract Profile Metadata", +"type": "n8n-nodes-base.html", +"position": [ +2560, +1180 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"dataPropertyName": "body", +"extractionValues": { +"values": [ +{ +"key": "name", +"cssSelector": "h1" +}, +{ +"key": "tagline", +"cssSelector": ".pv-text-details__left-panel--full-width .text-body-medium" +}, +{ +"key": "location", +"cssSelector": ".pv-text-details__left-panel--full-width + div .text-body-small" +}, +{ +"key": "num_connections", +"cssSelector": "a[href=\"/mynetwork/invite-connect/connections/\"]" +}, +{ +"key": "num_followers", +"cssSelector": "a[href=\"https://www.linkedin.com/feed/followers/\"]" +}, +{ +"key": "sections", +"cssSelector": "section[data-view-name]", +"returnArray": true, +"returnValue": "html" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "5685ec9f-c219-41b4-94d7-787daef8a628", +"name": "Activities To List", +"type": "n8n-nodes-base.splitOut", +"position": [ +3360, +1360 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "activity" +}, +"typeVersion": 1 +}, +{ +"id": "71240827-3e0d-4276-afb0-9ed72878ea4c", +"name": "APIFY Web Scraper", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2000, +1180 +], +"parameters": { +"url": "https://api.apify.com/v2/acts/apify~web-scraper/run-sync-get-dataset-items", +"options": {}, +"jsonBody": "={\n \"startUrls\": [\n {\n \"url\": \"{{ $json.linkedin_profile_url }}\",\n \"method\": \"GET\"\n }\n ],\n \"initialCookies\": [\n {\n \"name\": \"li_at\",\n \"value\": \"{{ $json.linkedin_cookies.match(/li_at=([^;]+)/)[1] }}\",\n \"domain\": \".www.linkedin.com\"\n }\n ],\n \"breakpointLocation\": \"NONE\",\n \"browserLog\": false,\n \"closeCookieModals\": false,\n \"debugLog\": false,\n \"downloadCss\": false,\n \"downloadMedia\": false,\n \"excludes\": [\n {\n \"glob\": \"/**/*.{png,jpg,jpeg,pdf}\"\n }\n ],\n \"headless\": true,\n \"ignoreCorsAndCsp\": false,\n \"ignoreSslErrors\": false,\n \n \"injectJQuery\": true,\n \"keepUrlFragments\": false,\n \"linkSelector\": \"a[href]\",\n \"maxCrawlingDepth\": 1,\n \"maxPagesPerCrawl\": 1,\n \"maxRequestRetries\": 1,\n \"maxResultsPerCrawl\": 1,\n \"pageFunction\": \"// The function accepts a single argument: the \\\"context\\\" object.\\n// For a complete list of its properties and functions,\\n// see https://apify.com/apify/web-scraper#page-function \\nasync function pageFunction(context) {\\n\\n await new Promise(res => { setTimeout(res, 6000) });\\n // This statement works as a breakpoint when you're trying to debug your code. Works only with Run mode: DEVELOPMENT!\\n // debugger; \\n\\n // jQuery is handy for finding DOM elements and extracting data from them.\\n // To use it, make sure to enable the \\\"Inject jQuery\\\" option.\\n const $ = context.jQuery;\\n const title = $('title').first().text();\\n\\n // Clone the body to avoid modifying the original content\\n const bodyClone = $('body').clone();\\n bodyClone.find('iframe, img, script, style, object, embed, noscript, svg, video, audio').remove();\\n const body = bodyClone.html();\\n\\n // Return an object with the data extracted from the page.\\n // It will be stored to the resulting dataset.\\n return {\\n url: context.request.url,\\n title,\\n body\\n };\\n}\",\n \"postNavigationHooks\": \"// We need to return array of (possibly async) functions here.\\n// The functions accept a single argument: the \\\"crawlingContext\\\" object.\\n[\\n async (crawlingContext) => {\\n // ...\\n },\\n]\",\n \"preNavigationHooks\": \"// We need to return array of (possibly async) functions here.\\n// The functions accept two arguments: the \\\"crawlingContext\\\" object\\n// and \\\"gotoOptions\\\".\\n[\\n async (crawlingContext, gotoOptions) => {\\n // ...\\n },\\n]\\n\",\n \"proxyConfiguration\": {\n \"useApifyProxy\": true\n },\n \"runMode\": \"PRODUCTION\",\n \n \"useChrome\": false,\n \"waitUntil\": [\n \"domcontentloaded\"\n ],\n \"globs\": [],\n \"pseudoUrls\": [],\n \"proxyRotation\": \"RECOMMENDED\",\n \"maxConcurrency\": 50,\n \"pageLoadTimeoutSecs\": 60,\n \"pageFunctionTimeoutSecs\": 60,\n \"maxScrollHeightPixels\": 5000,\n \"customData\": {}\n}", +"sendBody": true, +"specifyBody": "json", +"authentication": "genericCredentialType", +"genericAuthType": "httpQueryAuth" +}, +"credentials": { +"httpQueryAuth": { +"id": "cO2w8RDNOZg8DRa8", +"name": "Apify API" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "01659121-44f9-4d53-b973-cea29a8b0301", +"name": "Get Activity Details", +"type": "n8n-nodes-base.html", +"position": [ +3520, +1360 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"dataPropertyName": "activity", +"extractionValues": { +"values": [ +{ +"key": "header", +"attribute": "aria-label", +"cssSelector": ".feed-mini-update-optional-navigation-context-wrapper", +"returnValue": "attribute" +}, +{ +"key": "url", +"attribute": "href", +"cssSelector": ".feed-mini-update-optional-navigation-context-wrapper", +"returnValue": "attribute" +}, +{ +"key": "content", +"cssSelector": ".inline-show-more-text--is-collapsed" +}, +{ +"key": "num_reactions", +"cssSelector": ".social-details-social-counts__reactions-count" +}, +{ +"key": "num_comments", +"cssSelector": ".social-details-social-counts__comments" +}, +{ +"key": "num_reposts", +"cssSelector": ".social-details-social-counts__item--truncate-text" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "420a3a3e-ca99-49fb-b6b7-e9757f27b5d4", +"name": "Get Sections", +"type": "n8n-nodes-base.html", +"position": [ +2880, +1180 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"extractionValues": { +"values": [ +{ +"key": "title", +"cssSelector": "h2 [aria-hidden=true]" +}, +{ +"key": "content", +"cssSelector": "*", +"returnValue": "html" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "4983c987-79a7-4725-9913-630a71608f41", +"name": "Get About Section", +"type": "n8n-nodes-base.set", +"position": [ +3040, +1180 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "79d7943f-45a5-456c-a15b-cef53903409d", +"name": "html", +"type": "string", +"value": "={{\n$input.all()\n .find(input => input.json.title.toLowerCase().trim() === 'about')\n .json\n .content\n}}" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "0e8bed5b-a622-4dbd-a11e-24df5d68f038", +"name": "Get Activity Section", +"type": "n8n-nodes-base.set", +"position": [ +3040, +1360 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "79d7943f-45a5-456c-a15b-cef53903409d", +"name": "html", +"type": "string", +"value": "={{\n$input.all()\n .find(input => input.json.title.toLowerCase().trim() === 'activity')\n .json\n .content\n}}" +} +] +} +}, +"executeOnce": true, +"typeVersion": 3.4 +}, +{ +"id": "5dd2677f-a4fc-447f-af7d-28e90dda46e8", +"name": "Extract Activities", +"type": "n8n-nodes-base.html", +"position": [ +3200, +1360 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"dataPropertyName": "html", +"extractionValues": { +"values": [ +{ +"key": "activity", +"cssSelector": ".profile-creator-shared-feed-update__mini-container", +"returnArray": true, +"returnValue": "html" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "1a32808f-e465-47ef-b8bd-52b19c26ff1a", +"name": "Merge1", +"type": "n8n-nodes-base.merge", +"position": [ +3860, +1180 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "6e452337-55a3-4466-a094-ec9106b36498", +"name": "Is Scrape Successful?", +"type": "n8n-nodes-base.if", +"position": [ +2180, +1180 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "3861abc7-7699-4459-b983-0c8b33e090b5", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json.body }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "51a79d99-46af-4951-a99e-64f1d59f556e", +"name": "Extract About", +"type": "n8n-nodes-base.html", +"position": [ +3200, +1180 +], +"parameters": { +"options": {}, +"operation": "extractHtmlContent", +"dataPropertyName": "html", +"extractionValues": { +"values": [ +{ +"key": "about", +"cssSelector": "body" +} +] +} +}, +"typeVersion": 1.2 +}, +{ +"id": "d943fbde-f8fc-42b1-8b7e-f73735b81394", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +3860, +940 +], +"parameters": { +"color": 7, +"width": 508.12647286359606, +"height": 212.26880753952497, +"content": "## 3.6 Summarize LinkedIn For Attendee\n[Read more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nFinally, we'll use the Basic LLM node to summarize our attendee's LinkedIn profile and recent activity. Our goal here is to identify and send back interesting tidbits of information which may be relevant to the meeting as well as inform the user. Should you require different criteria, simply edit the summarizer to get the response you need." +}, +"typeVersion": 1 +}, +{ +"id": "b64bbfb0-ebd6-4fe7-9c02-3c1b72407df5", +"name": "Sticky Note12", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2460, +270 +], +"parameters": { +"color": 7, +"width": 593.8676556715506, +"height": 196.6490014749014, +"content": "## 3.3: Summarize Correspondance For Attendee\n[Read more about the Basic LLM node](https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm)\n\nNext, we'll generate a shorter version of the email(s) using the Basic LLM node - useful if the email was part of a large chain. The goal here is, if applicable, to remind the user of the conversion with this attendee and highlight any expectations which might be set before going into the meeting." +}, +"typeVersion": 1 +}, +{ +"id": "a2dd5060-dd12-463b-8bbe-327ed691bdb9", +"name": "Get LinkedIn Profile & Activity", +"type": "n8n-nodes-base.executeWorkflow", +"onError": "continueRegularOutput", +"position": [ +1780, +-100 +], +"parameters": { +"mode": "each", +"options": { +"waitForSubWorkflow": true +}, +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $workflow.id }}" +} +}, +"typeVersion": 1.1 +}, +{ +"id": "fde0fa35-e692-4ca9-83ef-14e527f2f8d2", +"name": "Sticky Note13", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-320, +-660 +], +"parameters": { +"width": 453.4804561790962, +"height": 588.3011632094225, +"content": "## Try It Out!\n\n### This workflow builds an AI meeting assistant who sends information-dense pre-meeting notifications for a user's upcoming meetings. This template is ideal for busy professional who is constantly on the move and wants to save time and make an impression.\n\n### How It Works\n* A scheduled trigger fires hourly and checks for upcoming meetings within the hour.\n* When found, a search for last correspondence and LinkedIn profile + recent activity is performed for each attendee.\n* Using both available correspondance and/or Linkedin profile, an AI/LLM is used to summarize this information and generate a short notification message which should help the user prepare for the meeting.\n* The notification is finally sent to the user's WhatsApp.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!" +}, +"typeVersion": 1 +}, +{ +"id": "f2f19824-9865-465b-a612-7d3215209c79", +"name": "Correspondance Recap Agent", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +2460, +500 +], +"parameters": { +"text": "=from: {{ $json.from }}\nto: {{ $json.to }}\ndate: {{ $json.date }}\nsubject: {{ $json.subject }}\ntext:\n{{ $json.text }}", +"messages": { +"messageValues": [ +{ +"message": "=You are helping the \"to\" user recap the last correspondance they had in this email thread. Summarize succiently what was discussed, changed or agreed to help the user prepare for their upcoming meeting." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.4 +}, +{ +"id": "42641933-edf6-4b01-a17f-8cda2be7a093", +"name": "Attendee Research Agent", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +2720, +-180 +], +"parameters": { +"text": "=meeting date: {{ $('Check For Upcoming Meetings').item.json.start.dateTime }}\nmeeting url: {{ $('Check For Upcoming Meetings').item.json.hangoutLink }}\nmeeting summary: {{ $('Check For Upcoming Meetings').first().json.summary }}\nmeeting description: {{ $('Check For Upcoming Meetings').item.json.description }}\nmeeting with: {{ $json.attendees.map(item => item.name).join(',') }}\n---\n{{\n$json.attendees.map(item => {\n return\n`attendee name: ${item.name}\n${item.name}'s last correspondance: ${item.email_summary.replaceAll('\\n', ' ') || `We have not had any correspondance with ${item.name}`}\n${item.name}'s linkedin profile: ${item.linkedin_summary.replaceAll('\\n', ' ') || `We were unable to find the linkedin profile for ${$json.name}`}\n`\n}).join('\\n---\\n')\n}}", +"messages": { +"messageValues": [ +{ +"message": "=You are a personal meeing assistant.\nYou are helping to remind user of an upcoming meeting with {{ $json.attendees.map(item => item.name).join(',') }} (aka \"the attendee(s)\"}. You will structure your notification using the following guidance:\n1. Start by providing the meeting summary, mentioning the date, with whom and providing the meeting link.\n2. For each attendee, give a short bullet point summary of their last correspondance. Assess if the correspondance has any relevance to the meeting and if so, identify any important todos or items which should be mentioned during the meeting. Additionally, give a short bullet point summary of attendee's recent activity which makes for good talking points. These need not be relevant to the meeting.\n\nWrite your response in a casual tone as if sending a SMS message to the user. USe bullet points where appropriate." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.4 +}, +{ +"id": "1916515d-8b85-4da9-ac17-1c08485cdf04", +"name": "LinkedIn Summarizer Agent", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"position": [ +4020, +1180 +], +"parameters": { +"text": "=### name\n{{ $('Extract Profile Metadata').item.json.name }}\n### about\n\"{{ $('Extract Profile Metadata').item.json.tagline }}\"\n{{ $json.about.replaceAll('\\n', ' ')}}\n### recent activity\n{{\n$json.activity.map((item, idx) => {\n return [\n item.header.replace('View full post.', ''),\n `(${item.url})`,\n ' - ',\n item.content.replaceAll('\\n', ' ').replaceAll('…show more', '')\n ].join(' ')\n}).join('\\n---\\n')\n}}", +"messages": { +"messageValues": [ +{ +"message": "=Summarize briefly the person and their recent activities as seen in the given feed and highlight noteworthy awards or achievements which make for good talking points." +} +] +}, +"promptType": "define" +}, +"typeVersion": 1.4 +} +], +"pinData": {}, +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "Merge Attendee with Summaries", +"type": "main", +"index": 0 +} +] +] +}, +"Merge1": { +"main": [ +[ +{ +"node": "LinkedIn Summarizer Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Router": { +"main": [ +[ +{ +"node": "Has Email Address?", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Has LinkedIn URL?", +"type": "main", +"index": 0 +} +] +] +}, +"Has Emails?": { +"main": [ +[ +{ +"node": "Get Message Contents", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Return Email Error", +"type": "main", +"index": 0 +} +] +] +}, +"Get Sections": { +"main": [ +[ +{ +"node": "Get About Section", +"type": "main", +"index": 0 +}, +{ +"node": "Get Activity Section", +"type": "main", +"index": 0 +} +] +] +}, +"Extract About": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"Set Route Email": { +"main": [ +[ +{ +"node": "Get Correspondance", +"type": "main", +"index": 0 +} +] +] +}, +"Simplify Emails": { +"main": [ +[ +{ +"node": "Correspondance Recap Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Schedule Trigger": { +"main": [ +[ +{ +"node": "Check For Upcoming Meetings", +"type": "main", +"index": 0 +} +] +] +}, +"Sections To List": { +"main": [ +[ +{ +"node": "Get Sections", +"type": "main", +"index": 0 +} +] +] +}, +"APIFY Web Scraper": { +"main": [ +[ +{ +"node": "Is Scrape Successful?", +"type": "main", +"index": 0 +} +] +] +}, +"Attendees to List": { +"main": [ +[ +{ +"node": "Set Route Email", +"type": "main", +"index": 0 +}, +{ +"node": "Set Route Linkedin", +"type": "main", +"index": 0 +} +] +] +}, +"Get About Section": { +"main": [ +[ +{ +"node": "Extract About", +"type": "main", +"index": 0 +} +] +] +}, +"Has LinkedIn URL?": { +"main": [ +[ +{ +"node": "Set LinkedIn Cookie", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Return LinkedIn Error1", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Correspondance Recap Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Activities To List": { +"main": [ +[ +{ +"node": "Get Activity Details", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Activities": { +"main": [ +[ +{ +"node": "Activities To List", +"type": "main", +"index": 0 +} +] +] +}, +"Get Correspondance": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +}, +"Has Email Address?": { +"main": [ +[ +{ +"node": "Get Last Correspondence", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Return Email Error1", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model1": { +"ai_languageModel": [ +[ +{ +"node": "LinkedIn Summarizer Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model2": { +"ai_languageModel": [ +[ +{ +"node": "Extract Attendee Information", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"OpenAI Chat Model3": { +"ai_languageModel": [ +[ +{ +"node": "Attendee Research Agent", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Set Route Linkedin": { +"main": [ +[ +{ +"node": "Get LinkedIn Profile & Activity", +"type": "main", +"index": 0 +} +] +] +}, +"Activities To Array": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 1 +} +] +] +}, +"Aggregate Attendees": { +"main": [ +[ +{ +"node": "Attendee Research Agent", +"type": "main", +"index": 0 +} +] +] +}, +"Set LinkedIn Cookie": { +"main": [ +[ +{ +"node": "APIFY Web Scraper", +"type": "main", +"index": 0 +} +] +] +}, +"Get Activity Details": { +"main": [ +[ +{ +"node": "Activities To Array", +"type": "main", +"index": 0 +} +] +] +}, +"Get Activity Section": { +"main": [ +[ +{ +"node": "Extract Activities", +"type": "main", +"index": 0 +} +] +] +}, +"Get Message Contents": { +"main": [ +[ +{ +"node": "Simplify Emails", +"type": "main", +"index": 0 +} +] +] +}, +"Is Scrape Successful?": { +"main": [ +[ +{ +"node": "Extract Profile Metadata", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Return LinkedIn Error", +"type": "main", +"index": 0 +} +] +] +}, +"Attendee Research Agent": { +"main": [ +[ +{ +"node": "WhatsApp Business Cloud", +"type": "main", +"index": 0 +} +] +] +}, +"Get Last Correspondence": { +"main": [ +[ +{ +"node": "Has Emails?", +"type": "main", +"index": 0 +} +] +] +}, +"Execute Workflow Trigger": { +"main": [ +[ +{ +"node": "Router", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Profile Metadata": { +"main": [ +[ +{ +"node": "Sections To List", +"type": "main", +"index": 0 +} +] +] +}, +"LinkedIn Summarizer Agent": { +"main": [ +[ +{ +"node": "Return LinkedIn Success", +"type": "main", +"index": 0 +} +] +] +}, +"Correspondance Recap Agent": { +"main": [ +[ +{ +"node": "Return Email Success", +"type": "main", +"index": 0 +} +] +] +}, +"Check For Upcoming Meetings": { +"main": [ +[ +{ +"node": "Extract Attendee Information", +"type": "main", +"index": 0 +} +] +] +}, +"Extract Attendee Information": { +"main": [ +[ +{ +"node": "Attendees to List", +"type": "main", +"index": 0 +} +] +] +}, +"Merge Attendee with Summaries": { +"main": [ +[ +{ +"node": "Aggregate Attendees", +"type": "main", +"index": 0 +} +] +] +}, +"Get LinkedIn Profile & Activity": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +} +} +} \ No newline at end of file diff --git a/Automate Screenshots with URLbox & Analyze them with AI.txt b/Automate Screenshots with URLbox & Analyze them with AI.txt new file mode 100644 index 0000000..7852c5b --- /dev/null +++ b/Automate Screenshots with URLbox & Analyze them with AI.txt @@ -0,0 +1,233 @@ +{ +"id": "wDD4XugmHIvx3KMT", +"meta": { +"instanceId": "149cdf730f0c143663259ddc6124c9c26e824d8d2d059973b871074cf4bda531" +}, +"name": "Analyze Screenshots with AI", +"tags": [], +"nodes": [ +{ +"id": "6d7f34b8-6203-4512-a428-7b5a18c63db6", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +240, +1100 +], +"parameters": { +"width": 373.2796418305297, +"height": 381.1230421279239, +"content": "## Setup \n**For Testing use the Setup node to put in test name & url.**\n\nIf you want to use this workflow in production, you can expand it to load data from other sources like a DB or Google Sheet" +}, +"typeVersion": 1 +}, +{ +"id": "ae568c65-e8f6-45bb-9c96-a870da1fc7d6", +"name": "Setup", +"type": "n8n-nodes-base.set", +"position": [ +360, +1320 +], +"parameters": { +"values": { +"string": [ +{ +"name": "website_name", +"value": "=n8n" +}, +{ +"name": "url", +"value": "https://n8n.io/" +} +] +}, +"options": {} +}, +"typeVersion": 2 +}, +{ +"id": "ca9f0357-a596-4453-b351-fdd8d47c81ad", +"name": "URLbox API Request", +"type": "n8n-nodes-base.httpRequest", +"position": [ +780, +1120 +], +"parameters": { +"url": "https://api.urlbox.io/v1/render/sync", +"method": "POST", +"options": {}, +"sendBody": true, +"sendHeaders": true, +"bodyParameters": { +"parameters": [ +{ +"name": "url", +"value": "={{ $json.url }}" +}, +{ +"name": "full_page", +"value": true +} +] +}, +"headerParameters": { +"parameters": [ +{ +"name": "Authorization", +"value": "YOUR_API_KEY" +} +] +} +}, +"retryOnFail": true, +"typeVersion": 4.1 +}, +{ +"id": "3caffa3c-657a-4f74-a3cb-daf7beb67890", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +640, +920 +], +"parameters": { +"width": 373.2796418305297, +"height": 381.1230421279239, +"content": "## URLbox API call \n[URLbox](https://urlbox.com/) is a Screenshot API. With this API you can automate making screenshots based on website url's.\n\nYou have to replace the Placeholder with your API Key" +}, +"typeVersion": 1 +}, +{ +"id": "d2b81b41-1497-4733-8130-67f8de0acff4", +"name": "Analyze the Screenshot", +"type": "@n8n/n8n-nodes-langchain.openAi", +"position": [ +1220, +1120 +], +"parameters": { +"text": "=Your Input is a Screenshot of a Website.\nDescribe the content of the Website in one sentence.", +"options": {}, +"resource": "image", +"imageUrls": "renderURL", +"operation": "analyze" +}, +"typeVersion": 1.1 +}, +{ +"id": "68d86931-69bb-4b78-a7fe-44969172672f", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1080, +920 +], +"parameters": { +"width": 373.2796418305297, +"height": 381.1230421279239, +"content": "## Analyze the Screenshot \nAnalyze the screenshot using OpenAI.\n\nAdd your OpenAI Credentials on the top of the node.\n\nThe prompt is an example. Change it based on what you want to extract from the screenshot." +}, +"typeVersion": 1 +}, +{ +"id": "8a22fca5-7f06-45fb-a03f-585a7eb35b40", +"name": "Merge Name & Description", +"type": "n8n-nodes-base.merge", +"position": [ +1620, +1300 +], +"parameters": { +"mode": "combine", +"options": {}, +"combinationMode": "mergeByPosition" +}, +"typeVersion": 2.1 +}, +{ +"id": "4f902a0a-ee93-4190-9b1e-ab3fa15eb4aa", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1480, +1200 +], +"parameters": { +"width": 371.85912137154685, +"height": 300.15337596590155, +"content": "## Merge\nMerge the description with the name of the website & the url." +}, +"typeVersion": 1 +}, +{ +"id": "8b3eb3f4-b31a-48f0-94bb-35379d07a81f", +"name": "Manual Execution", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +20, +1320 +], +"parameters": {}, +"typeVersion": 1 +} +], +"active": false, +"pinData": {}, +"settings": { +"executionOrder": "v1" +}, +"versionId": "ff37faa1-c61c-44be-89f0-62f8e1b8317c", +"connections": { +"Setup": { +"main": [ +[ +{ +"node": "URLbox API Request", +"type": "main", +"index": 0 +}, +{ +"node": "Merge Name & Description", +"type": "main", +"index": 1 +} +] +] +}, +"Manual Execution": { +"main": [ +[ +{ +"node": "Setup", +"type": "main", +"index": 0 +} +] +] +}, +"URLbox API Request": { +"main": [ +[ +{ +"node": "Analyze the Screenshot", +"type": "main", +"index": 0 +} +] +] +}, +"Analyze the Screenshot": { +"main": [ +[ +{ +"node": "Merge Name & Description", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/Build Your Own Image Search Using AI Object Detection, CDN and ElasticSearchBuild Your Own Image Search Using AI Object Detection, CDN and ElasticSearch.txt b/Build Your Own Image Search Using AI Object Detection, CDN and ElasticSearchBuild Your Own Image Search Using AI Object Detection, CDN and ElasticSearch.txt new file mode 100644 index 0000000..46c0e2b --- /dev/null +++ b/Build Your Own Image Search Using AI Object Detection, CDN and ElasticSearchBuild Your Own Image Search Using AI Object Detection, CDN and ElasticSearch.txt @@ -0,0 +1,477 @@ +{ +"meta": { +"instanceId": "26ba763460b97c249b82942b23b6384876dfeb9327513332e743c5f6219c2b8e" +}, +"nodes": [ +{ +"id": "6359f725-1ede-4b05-bc19-05a7e85c0865", +"name": "When clicking \"Test workflow\"", +"type": "n8n-nodes-base.manualTrigger", +"position": [ +680, +292 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528", +"name": "Fetch Source Image", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1000, +292 +], +"parameters": { +"url": "={{ $json.source_image }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "9b1b94cf-3a7d-4c43-ab6c-8df9824b5667", +"name": "Split Out Results Only", +"type": "n8n-nodes-base.splitOut", +"position": [ +1428, +323 +], +"parameters": { +"options": {}, +"fieldToSplitOut": "result" +}, +"typeVersion": 1 +}, +{ +"id": "fcbaf6c3-2aee-4ea1-9c5e-2833dd7a9f50", +"name": "Filter Score >= 0.9", +"type": "n8n-nodes-base.filter", +"position": [ +1608, +323 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "367d83ef-8ecf-41fe-858c-9bfd78b0ae9f", +"operator": { +"type": "number", +"operation": "gte" +}, +"leftValue": "={{ $json.score }}", +"rightValue": 0.9 +} +] +} +}, +"typeVersion": 2 +}, +{ +"id": "954ce7b0-ef82-4203-8706-17cfa5e5e3ff", +"name": "Crop Object From Image", +"type": "n8n-nodes-base.editImage", +"position": [ +2080, +432 +], +"parameters": { +"width": "={{ $json.box.xmax - $json.box.xmin }}", +"height": "={{ $json.box.ymax - $json.box.ymin }}", +"options": { +"format": "jpeg", +"fileName": "={{ $binary.data.fileName.split('.')[0].urlEncode()+'-'+$json.label.urlEncode() + '-' + $itemIndex }}.jpg" +}, +"operation": "crop", +"positionX": "={{ $json.box.xmin }}", +"positionY": "={{ $json.box.ymin }}" +}, +"typeVersion": 1 +}, +{ +"id": "40027456-4bf9-4eea-8d71-aa28e69b29e5", +"name": "Set Variables", +"type": "n8n-nodes-base.set", +"position": [ +840, +292 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "9e95d951-8530-4a80-bd00-6bb55623a71f", +"name": "CLOUDFLARE_ACCOUNT_ID", +"type": "string", +"value": "" +}, +{ +"id": "66807a90-63a1-4d4e-886e-e8abf3019a34", +"name": "model", +"type": "string", +"value": "@cf/facebook/detr-resnet-50" +}, +{ +"id": "a13ccde6-e6e3-46f4-afa3-2134af7bc765", +"name": "source_image", +"type": "string", +"value": "https://images.pexels.com/photos/2293367/pexels-photo-2293367.jpeg?auto=compress&cs=tinysrgb&w=600" +}, +{ +"id": "0734fc55-b414-47f7-8b3e-5c880243f3ed", +"name": "elasticsearch_index", +"type": "string", +"value": "n8n-image-search" +} +] +} +}, +"typeVersion": 3.3 +}, +{ +"id": "c3d8c5e3-546e-472c-9e6e-091cf5cee3c3", +"name": "Use Detr-Resnet-50 Object Classification", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1248, +324 +], +"parameters": { +"url": "=https://api.cloudflare.com/client/v4/accounts/{{ $('Set Variables').item.json.CLOUDFLARE_ACCOUNT_ID }}/ai/run/{{ $('Set Variables').item.json.model }}", +"method": "POST", +"options": {}, +"sendBody": true, +"contentType": "binaryData", +"authentication": "predefinedCredentialType", +"inputDataFieldName": "data", +"nodeCredentialType": "cloudflareApi" +}, +"credentials": { +"cloudflareApi": { +"id": "qOynkQdBH48ofOSS", +"name": "Cloudflare account" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18", +"name": "Upload to Cloudinary", +"type": "n8n-nodes-base.httpRequest", +"position": [ +2380, +380 +], +"parameters": { +"url": "https://api.cloudinary.com/v1_1/daglih2g8/image/upload", +"method": "POST", +"options": {}, +"sendBody": true, +"sendQuery": true, +"contentType": "multipart-form-data", +"authentication": "genericCredentialType", +"bodyParameters": { +"parameters": [ +{ +"name": "file", +"parameterType": "formBinaryData", +"inputDataFieldName": "data" +} +] +}, +"genericAuthType": "httpQueryAuth", +"queryParameters": { +"parameters": [ +{ +"name": "upload_preset", +"value": "n8n-workflows-preset" +} +] +} +}, +"credentials": { +"httpQueryAuth": { +"id": "sT9jeKzZiLJ3bVPz", +"name": "Cloudinary API" +} +}, +"typeVersion": 4.2 +}, +{ +"id": "3c4e1f04-a0ba-4cce-b82a-aa3eadc4e7e1", +"name": "Create Docs In Elasticsearch", +"type": "n8n-nodes-base.elasticsearch", +"position": [ +2580, +380 +], +"parameters": { +"indexId": "={{ $('Set Variables').item.json.elasticsearch_index }}", +"options": {}, +"fieldsUi": { +"fieldValues": [ +{ +"fieldId": "image_url", +"fieldValue": "={{ $json.secure_url.replace('upload','upload/f_auto,q_auto') }}" +}, +{ +"fieldId": "source_image_url", +"fieldValue": "={{ $('Set Variables').item.json.source_image }}" +}, +{ +"fieldId": "label", +"fieldValue": "={{ $('Crop Object From Image').item.json.label }}" +}, +{ +"fieldId": "metadata", +"fieldValue": "={{ JSON.stringify(Object.assign($('Crop Object From Image').item.json, { filename: $json.original_filename })) }}" +} +] +}, +"operation": "create", +"additionalFields": {} +}, +"credentials": { +"elasticsearchApi": { +"id": "dRuuhAgS7AF0mw0S", +"name": "Elasticsearch account" +} +}, +"typeVersion": 1 +}, +{ +"id": "292c9821-c123-44fa-9ba1-c37bf84079bc", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +620, +120 +], +"parameters": { +"color": 7, +"width": 541.1455500767354, +"height": 381.6388867600897, +"content": "## 1. Get Source Image\n[Read more about setting variables for your workflow](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set)\n\nFor this demo, we'll manually define an image to process. In production however, this image can come from a variety of sources such as drives, webhooks and more." +}, +"typeVersion": 1 +}, +{ +"id": "863271dc-fb9d-4211-972d-6b57336073b4", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1180, +80 +], +"parameters": { +"color": 7, +"width": 579.7748008857744, +"height": 437.4680103498263, +"content": "## 2. Use Detr-Resnet-50 Object Classification\n[Learn more about Cloudflare Workers AI](https://developers.cloudflare.com/workers-ai/)\n\nNot all AI workflows need an LLM! As in this example, we're using a non-LLM vision model to parse the source image and return what objects are contained within. The image search feature we're building will be based on the objects in the image making for a much more granular search via object association.\n\nWe'll use the Cloudflare Workers AI service which conveniently provides this model via API use." +}, +"typeVersion": 1 +}, +{ +"id": "b73b45da-0436-4099-b538-c6b3b84822f2", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1800, +260 +], +"parameters": { +"color": 7, +"width": 466.35460775498495, +"height": 371.9272151757119, +"content": "## 3. Crop Objects Out of Source Image\n[Read more about Editing Images in n8n](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.editimage)\n\nWith our objects identified by their bounding boxes, we can \"cut\" them out of the source image as separate images." +}, +"typeVersion": 1 +}, +{ +"id": "465bd842-8a35-49d8-a9ff-c30d164620db", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2300, +180 +], +"parameters": { +"color": 7, +"width": 478.20345439832454, +"height": 386.06196032653685, +"content": "## 4. Index Object Images In ElasticSearch\n[Read more about using ElasticSearch](https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.elasticsearch)\n\nBy storing the newly created object images externally and indexing them in Elasticsearch, we now have a foundation for our Image Search service which queries by object association." +}, +"typeVersion": 1 +}, +{ +"id": "6a04b4b5-7830-410d-9b5b-79acb0b1c78b", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1800, +-220 +], +"parameters": { +"color": 7, +"width": 328.419768654291, +"height": 462.65463700396174, +"content": "Fig 1. Result of Classification\n![image of classification](https://res.cloudinary.com/daglih2g8/image/upload/f_auto,q_auto,w_300/v1/n8n-workflows/ywtzjcmqrypihci1npgh)" +}, +"typeVersion": 1 +}, +{ +"id": "8f607951-ba41-4362-8323-e8b4b96ad122", +"name": "Fetch Source Image Again", +"type": "n8n-nodes-base.httpRequest", +"position": [ +1880, +432 +], +"parameters": { +"url": "={{ $('Set Variables').item.json.source_image }}", +"options": {} +}, +"typeVersion": 4.2 +}, +{ +"id": "6933f67d-276b-4908-8602-654aa352a68b", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +220, +120 +], +"parameters": { +"width": 359.6648027457353, +"height": 352.41026669883723, +"content": "## Try It Out!\n### This workflow does the following:\n* Downloads an image\n* Uses an object classification AI model to identify objects in the image.\n* Crops the objects out from the original image into new image files.\n* Indexes the image's object in an Elasticsearch Database to enable image search.\n\n### Need Help?\nJoin the [Discord](https://discord.com/invite/XPKeKXeB7d) or ask in the [Forum](https://community.n8n.io/)!\n\nHappy Hacking!" +}, +"typeVersion": 1 +}, +{ +"id": "35615ed5-43e8-43f0-95fe-1f95a1177d69", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +800, +280 +], +"parameters": { +"width": 172.9365918827757, +"height": 291.6881468483679, +"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n🚨**Required**\n* Set your variables here first!" +}, +"typeVersion": 1 +} +], +"pinData": {}, +"connections": { +"Set Variables": { +"main": [ +[ +{ +"node": "Fetch Source Image", +"type": "main", +"index": 0 +} +] +] +}, +"Fetch Source Image": { +"main": [ +[ +{ +"node": "Use Detr-Resnet-50 Object Classification", +"type": "main", +"index": 0 +} +] +] +}, +"Filter Score >= 0.9": { +"main": [ +[ +{ +"node": "Fetch Source Image Again", +"type": "main", +"index": 0 +} +] +] +}, +"Upload to Cloudinary": { +"main": [ +[ +{ +"node": "Create Docs In Elasticsearch", +"type": "main", +"index": 0 +} +] +] +}, +"Crop Object From Image": { +"main": [ +[ +{ +"node": "Upload to Cloudinary", +"type": "main", +"index": 0 +} +] +] +}, +"Split Out Results Only": { +"main": [ +[ +{ +"node": "Filter Score >= 0.9", +"type": "main", +"index": 0 +} +] +] +}, +"Fetch Source Image Again": { +"main": [ +[ +{ +"node": "Crop Object From Image", +"type": "main", +"index": 0 +} +] +] +}, +"When clicking \"Test workflow\"": { +"main": [ +[ +{ +"node": "Set Variables", +"type": "main", +"index": 0 +} +] +] +}, +"Use Detr-Resnet-50 Object Classification": { +"main": [ +[ +{ +"node": "Split Out Results Only", +"type": "main", +"index": 0 +} +] +] +} +} +} \ No newline at end of file diff --git a/📚 Auto-generate documentation for n8n workflows with GPT and Docsify.txt b/📚 Auto-generate documentation for n8n workflows with GPT and Docsify.txt new file mode 100644 index 0000000..8fb523f --- /dev/null +++ b/📚 Auto-generate documentation for n8n workflows with GPT and Docsify.txt @@ -0,0 +1,2003 @@ +{ +"id": "VY4TXYGmqth57Een", +"meta": { +"instanceId": "fb924c73af8f703905bc09c9ee8076f48c17b596ed05b18c0ff86915ef8a7c4a", +"templateCredsSetupCompleted": true +}, +"name": "Docsify example", +"tags": [], +"nodes": [ +{ +"id": "f41906c3-ee4c-4333-bfd5-426f82ba4bd9", +"name": "CONFIG", +"type": "n8n-nodes-base.set", +"position": [ +660, +60 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "b48986ec-f58d-4a7f-afba-677edcb28d31", +"name": "project_path", +"type": "string", +"value": "./.n8n/test_docs" +}, +{ +"id": "cf632419-f839-4045-922c-03784bb3ae07", +"name": "instance_url", +"type": "string", +"value": "={{$env[\"N8N_PROTOCOL\"]}}://{{$env[\"N8N_HOST\"]}}" +}, +{ +"id": "7a7c70a6-1853-4ca7-b5b1-e36bb0e190d0", +"name": "HTML_headers", +"type": "string", +"value": "= \n \n \n \n " +}, +{ +"id": "1e785afe-f05f-4e51-a164-f341da81ccac", +"name": "HTML_styles_editor", +"type": "string", +"value": "= " +}, +{ +"id": "37e22865-7b6b-438d-83a0-dc680d4775cc", +"name": "HTML_docsify_include", +"type": "string", +"value": "= " +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "75cdf7fc-3dfa-49c1-bdbf-01d8be08aaa4", +"name": "Convert to File", +"type": "n8n-nodes-base.convertToFile", +"position": [ +4020, +1600 +], +"parameters": { +"options": {}, +"operation": "toText", +"sourceProperty": "workflowdata" +}, +"typeVersion": 1.1 +}, +{ +"id": "3868011e-8374-496a-b3f5-4cbf7bde4e56", +"name": "HasFile?", +"type": "n8n-nodes-base.if", +"position": [ +2400, +880 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "2d9feb22-49d1-4354-9b0b-b82da2b20678", +"operator": { +"type": "number", +"operation": "gt" +}, +"leftValue": "={{ Object.keys($json).length }}", +"rightValue": 0 +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "0bf2317b-2534-4022-9a16-395d4b44680c", +"name": "Extract from File", +"type": "n8n-nodes-base.extractFromFile", +"position": [ +2660, +860 +], +"parameters": { +"options": {}, +"operation": "text", +"destinationKey": "workflowdata" +}, +"typeVersion": 1 +}, +{ +"id": "4b44a7f3-09bf-46a8-9520-247993af654b", +"name": "Main Page", +"type": "n8n-nodes-base.html", +"position": [ +4660, +-100 +], +"parameters": { +"html": "\n\n \n{{ $('CONFIG').first().json.HTML_headers }}\n \n
Please wait...
\n \n{{ $('CONFIG').first().json.HTML_docsify_include }}\n \n" +}, +"typeVersion": 1.2 +}, +{ +"id": "28c29cec-7efd-4f05-bf53-ac08cc3834a1", +"name": "Instance overview", +"type": "n8n-nodes-base.html", +"position": [ +4660, +160 +], +"parameters": { +"html": "# Your n8n instance workflows:\n\n| Workflow | Status | Docs | Created | Updated | Nodes | Triggers |\n|----------|:------:|------|---------|---------|-------|----------|\n{{ $jmespath($input.all(),'[].json.content').join('\\n') }}" +}, +"executeOnce": true, +"typeVersion": 1.2 +}, +{ +"id": "3e8eb52e-8d35-4aa3-a485-6674d67720dc", +"name": "Sort-workflows", +"type": "n8n-nodes-base.sort", +"position": [ +2080, +160 +], +"parameters": { +"options": {}, +"sortFieldsUi": { +"sortField": [ +{ +"order": "descending", +"fieldName": "updatedAt" +} +] +} +}, +"typeVersion": 1 +}, +{ +"id": "2178e1cf-90b8-4779-9b5c-3d6180823c95", +"name": "doc action", +"type": "n8n-nodes-base.switch", +"position": [ +1740, +1080 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "view", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "ee386c7d-1abe-4864-bb3a-a19d3816c906", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.query.action }}", +"rightValue": "view" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "edit", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "aa1a33ee-ac38-4ea4-9a4c-d355e7de1312", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.query.action }}", +"rightValue": "edit" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "recreate", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "676c36e1-4c88-4314-9317-abc877ff3d17", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.query.action }}", +"rightValue": "recreate" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "save", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "164314cf-7d99-4716-9949-b9196ce47959", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.query.action }}", +"rightValue": "save" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra" +} +}, +"typeVersion": 3.2 +}, +{ +"id": "7f4aab9b-b7e8-4920-98e8-af8f504a1333", +"name": "Empty Set", +"type": "n8n-nodes-base.set", +"position": [ +2000, +960 +], +"parameters": { +"options": {} +}, +"typeVersion": 3.4 +}, +{ +"id": "1f35bc3e-29d7-47a2-a1c7-cf6052d99993", +"name": "Load Doc File", +"type": "n8n-nodes-base.readWriteFile", +"position": [ +1900, +860 +], +"parameters": { +"options": {}, +"fileSelector": "={{ $('CONFIG').first().json.project_path }}/{{ $json.params.file }}" +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "c0805f50-8f8c-49ba-b0c7-6768bf89798c", +"name": "Respond with markdown", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +4920, +1040 +], +"parameters": { +"options": { +"responseCode": 200, +"responseHeaders": { +"entries": [ +{ +"name": "Content-Type", +"value": "text/markdown" +} +] +} +}, +"respondWith": "text", +"responseBody": "={{ $json.html }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "9c7a18b9-a081-4162-94f4-e125d666cbcc", +"name": "Respond with HTML", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +4920, +860 +], +"parameters": { +"options": { +"responseCode": 200, +"responseHeaders": { +"entries": [ +{ +"name": "Content-Type", +"value": "text/html" +} +] +} +}, +"respondWith": "text", +"responseBody": "={{ $json.html }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "50944148-eb7c-4c28-99c5-478ddb2596f2", +"name": "Save New Doc File", +"type": "n8n-nodes-base.readWriteFile", +"position": [ +4180, +1600 +], +"parameters": { +"options": {}, +"fileName": "={{ $('CONFIG').first().json.project_path }}/{{ $('CONFIG').first().json.params.file }}", +"operation": "write" +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "6d7e0dcf-d12b-4428-9c5e-ef7fb2c6be28", +"name": "Blank Doc File", +"type": "n8n-nodes-base.set", +"position": [ +4000, +1080 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "b168d9b1-1a13-4915-b59b-8a17258fd9cc", +"name": "workflowdata", +"type": "string", +"value": "=# {{ $json.name }}\n\n## Workflow Description\n!> Please write what is this workflow doing\n\n## Workflow schematic\n\n```mermaid\n{{ $json.mermaidChart }}\n```\n\n## Any further information\n\n> You can also add tables like this:\n\n| Parameter | Value |\n|-----------|-------|\n| Created | {{ $json.createdAt }} |\n| Last updated | {{ $json.updatedAt }} |\n| Author | {{ $json.shared[0].project.name }} |\n\n" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "778a97eb-f7a2-4537-81fc-979dc6c674a2", +"name": "Fetch Single Workflow1", +"type": "n8n-nodes-base.n8n", +"position": [ +2820, +1200 +], +"parameters": { +"operation": "get", +"workflowId": { +"__rl": true, +"mode": "id", +"value": "={{ $('CONFIG').first().json.params.file.replaceAll('docs_','').split('.md')[0] }}" +}, +"requestOptions": {} +}, +"credentials": { +"n8nApi": { +"id": "eW7IdTFt4ARJbEwR", +"name": "Ted n8n account" +} +}, +"typeVersion": 1 +}, +{ +"id": "092b8c67-77f9-4d4b-aa26-8f0e3ea3ed29", +"name": "Fill Workflow Table", +"type": "n8n-nodes-base.set", +"position": [ +2280, +160 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "3bed44f3-7fa6-4d28-8a6e-7074ca354cd6", +"name": "content", +"type": "string", +"value": "=| [{{ `${$json.name.replace(/[|\\\\[\\]`_*{}()<>#+-]/g, '\\\\$&')}` }}]({{ `${$('CONFIG').first().json.instance_url}/workflow/${$json.id}` }} \"Click to open workflow in n8n\") | {{ $json.active ? '[:green_circle:](# \"Active\")' : '[:white_circle:](# \"Inactive\")' }} | [:book:]({{ `docs_${$json.id}?action=view` }} \"View docs\") [:memo:]({{ `docs_${$json.id}.md?action=edit` }} \":ignore Edit\") [:arrows_counterclockwise:]({{ `docs_${$json.id}?action=recreate` }} \"Recreate docs\") | {{ `${new Date($json.createdAt).toISOString().replace('T', ' ').slice(0, 16)}` }} | {{ `${new Date($json.updatedAt).toISOString().replace('T', ' ').slice(0, 16)}` }} | {{ $json.nodes.length }} | {{ $json.nodes.filter(n => n.type.includes('Trigger')).length }} |" +} +] +} +}, +"executeOnce": false, +"typeVersion": 3.4 +}, +{ +"id": "18c58a09-0dfe-4cb4-ae7f-503957eabadb", +"name": "Basic LLM Chain", +"type": "@n8n/n8n-nodes-langchain.chainLlm", +"onError": "continueRegularOutput", +"position": [ +3480, +1200 +], +"parameters": { +"text": "=Here's the workflow data:\n{{Object.assign(\n Object.fromEntries(Object.entries($json).filter(([key]) => !['staticData', 'pinData'].includes(key))),\n {nodes: $json.nodes.map(node => Object.fromEntries(Object.entries(node).filter(([key]) => !['id', 'position'].includes(key))))}\n).toJsonString() }}", +"messages": { +"messageValues": [ +{ +"message": "=Your task is to generate simple workflow documentation for the n8n workflows. The user will provide a JSON structure. Reply \nin JSON format in 2 sections: workflow_desription and nodes_settings. Important! Each json key should be a simple markdown text without any additional comments or remarks from your end.\n\nInstruction for `workflow_desription`:\n```\n## Section header with H2\n\\n\n> subline with who created workflow and when, when it was last edited and the status (active / inactive as the green / grey round emoji). Also, when the documentation was generated. Now is: {{ $now }}.\n\\n\\n\nShould contain a description of the workflow. in a couple of paragraphs. Use direct voice without the fluff\n```\n\nInstruction for `nodes_settings`:\n```\n## Section header with H2.\n\\n\n### Node 1 name as H3 title\n - For each node make a bullet list with the main node configs. Ignore irrelevant configs. Enclose each config value in code backticks (`). Look:\n - Parameter 1 name: `Parameter 1 value`\n - Parameter 2 name: `Parameter 2 value`\n\\n\\n\n### Node 2 name as H3 title\n - For each node make a bullet list with the main node configs. Ignore irrelevant configs. Enclose each config value in code backticks (`). Look:\n - Parameter 1 name: `Parameter 1 value`\n - Parameter 2 name: `Parameter 2 value`\n\\n\\n\n```" +} +] +}, +"promptType": "define", +"hasOutputParser": true +}, +"typeVersion": 1.4, +"alwaysOutputData": false +}, +{ +"id": "9bc58cd3-a55e-4cda-95b5-7fa8dc0e7076", +"name": "OpenAI Chat Model", +"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", +"position": [ +3480, +1360 +], +"parameters": { +"model": "gpt-4-turbo", +"options": { +"timeout": 120000, +"temperature": 0.2 +} +}, +"credentials": { +"openAiApi": { +"id": "rveqdSfp7pCRON1T", +"name": "Ted's Tech Talks OpenAi" +} +}, +"typeVersion": 1 +}, +{ +"id": "38fb6192-b8ce-4241-a9fe-aebda09aa8d5", +"name": "Structured Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserStructured", +"position": [ +3820, +1360 +], +"parameters": { +"jsonSchemaExample": "{\n\t\"workflow_description\": \"## Workflow overview\\n\\n>some additiona info\\n\\nWorkflow desctiption\",\n\t\"nodes_settings\": \"## Nodes settings\\n\\n###Node name 1\\n\\n- Setting 1\\n- Setting 2###Node name 2\\n\\n- Setting 1\\n- Setting 2\"\n}" +}, +"typeVersion": 1.2 +}, +{ +"id": "29261bbb-dbbb-44df-b99d-bb084df7d846", +"name": "Auto-fixing Output Parser", +"type": "@n8n/n8n-nodes-langchain.outputParserAutofixing", +"position": [ +3580, +1360 +], +"parameters": { +"options": {} +}, +"typeVersion": 1 +}, +{ +"id": "086a57cf-a2b4-4f32-8ca6-38546e4856c1", +"name": "Respond with main page HTML", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +4920, +-100 +], +"parameters": { +"options": { +"responseCode": 200, +"responseHeaders": { +"entries": [ +{ +"name": "Content-Type", +"value": "text/html" +} +] +} +}, +"respondWith": "text", +"responseBody": "={{ $json.html }}" +}, +"typeVersion": 1.1 +}, +{ +"id": "fdbfe60b-e677-4897-ab1a-9a9f506bba27", +"name": "Workflow Tags", +"type": "n8n-nodes-base.html", +"position": [ +4660, +500 +], +"parameters": { +"html": "- **Click to filter by tag:**\n{{ [...new Set($jmespath($input.all(),'[].json.tags[].name'))].map(tag => `- [${tag}](tag-${encodeURIComponent(tag)})`).join('\\n') }}" +}, +"executeOnce": true, +"typeVersion": 1.2 +}, +{ +"id": "94a258ed-c07c-42d4-8d37-3395fad205b0", +"name": "No Operation, do nothing", +"type": "n8n-nodes-base.noOp", +"position": [ +1740, +1880 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "c35ca075-52e7-4c2f-9891-f709afe36e52", +"name": "Merge", +"type": "n8n-nodes-base.merge", +"position": [ +3140, +1100 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition", +"numberInputs": 3 +}, +"typeVersion": 3 +}, +{ +"id": "55a1e32f-b20c-4b1f-9d6f-9bc4ec221fab", +"name": "Fallback file name", +"type": "n8n-nodes-base.html", +"position": [ +4660, +1900 +], +"parameters": { +"html": "> File: {{ $json.params.file }}" +}, +"typeVersion": 1.2 +}, +{ +"id": "3eef159b-99ad-4c9a-82f4-13bf16972521", +"name": "mkdir", +"type": "n8n-nodes-base.executeCommand", +"position": [ +2100, +1060 +], +"parameters": { +"command": "=mkdir -p {{$('CONFIG').first().json.project_path}}" +}, +"typeVersion": 1 +}, +{ +"id": "15fda233-925b-4a4d-964e-1916c0cd39a2", +"name": "Merge1", +"type": "n8n-nodes-base.merge", +"position": [ +2240, +880 +], +"parameters": { +"mode": "chooseBranch" +}, +"typeVersion": 3 +}, +{ +"id": "3e6c9243-d5f7-4f04-8231-9994963df36d", +"name": "Edit Page", +"type": "n8n-nodes-base.html", +"position": [ +4660, +860 +], +"parameters": { +"html": "\n\n \n{{ $('CONFIG').first().json.HTML_headers }}\n{{ $('CONFIG').first().json.HTML_styles_editor }}\n \n \n
\n
\n \n \n
\n
\n \n
\n
\n
\n
\n
\n \n\n{{ $('CONFIG').first().json.HTML_docsify_include }}\n \n" +}, +"typeVersion": 1.2 +}, +{ +"id": "71e136d5-bb5b-4eab-8cab-bfc50ea2a5a5", +"name": "Workflow md content", +"type": "n8n-nodes-base.html", +"position": [ +4660, +1040 +], +"parameters": { +"html": "{{ $json.workflowdata }}" +}, +"executeOnce": true, +"typeVersion": 1.2 +}, +{ +"id": "6cb6f3b8-de65-43a5-9df3-48299ba7fcce", +"name": "Is Action Edit?1", +"type": "n8n-nodes-base.if", +"position": [ +3300, +1100 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "856cdb3b-a187-4db5-b77b-43ee086780ee", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.query.action }}", +"rightValue": "edit" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "aff9ed71-bb49-4170-9ae3-5f05f89bab05", +"name": "Is Action Edit?2", +"type": "n8n-nodes-base.if", +"position": [ +4180, +880 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "e3648023-8cb7-4b82-bd35-1ba196458327", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.query.action }}", +"rightValue": "edit" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "7b3d31a9-ee01-4bce-bc5b-78161536999d", +"name": "Generate Mermaid Chart", +"type": "n8n-nodes-base.code", +"position": [ +3000, +1260 +], +"parameters": { +"jsCode": "const workflow = $input.first().json;\n\n// Extract nodes from the workflow\nconst nodes = workflow.nodes || [];\n\n// Node types to exclude\nconst excludedNodeTypes = ['n8n-nodes-base.stickyNote'];\n\n// Define shapes and their corresponding brackets\n// https://mermaid.js.org/syntax/flowchart.html\nconst shapes = {\n 'rect': ['[', ']'],\n 'rhombus': ['{', '}'],\n 'circle': ['((', '))'],\n 'hexagon': ['{{', '}}'],\n 'subroutine': ['[[', ']]'],\n 'parallelogram': ['[\\/', '\\/]'],\n 'wait': ['(', ')']\n // Add more shapes here as needed\n};\n\n// Define special shapes for specific node types\nconst specialShapes = {\n 'n8n-nodes-base.if': 'rhombus',\n 'n8n-nodes-base.switch': 'rhombus',\n 'n8n-nodes-base.code': 'subroutine',\n 'n8n-nodes-base.executeWorkflow': 'subroutine',\n 'n8n-nodes-base.httpRequest':'parallelogram',\n 'n8n-nodes-base.wait':'wait'\n // List more special node types\n};\n\n// Function to get the shape for a node type\nfunction getNodeShape(nodeType) {\n return specialShapes[nodeType] || 'rect';\n}\n\n// Create a map of node names to their \"EL\" identifiers, disabled status, and shape\nconst nodeMap = {};\nlet nodeCounter = 1;\nnodes.forEach((node) => {\n if (!excludedNodeTypes.includes(node.type)) {\n const shape = getNodeShape(node.type);\n nodeMap[node.name] = {\n id: `EL${nodeCounter}`,\n disabled: node.disabled || false,\n shape: shape,\n brackets: shapes[shape] || shapes['rect'] // Default to rect if shape not found\n };\n nodeCounter++;\n }\n});\n\n// Function to convert special characters to HTML entities\nfunction convertToHTMLEntities(str) {\n return str.replaceAll('\"',\"'\").replace(/[^\\w\\s-]/g, function(char) {\n return '&#' + char.charCodeAt(0) + ';';\n });\n}\n\n// Function to format node text (with strike-through if disabled)\nfunction formatNodeText(nodeName, isDisabled) {\n const escapedName = convertToHTMLEntities(nodeName);\n return isDisabled ? `${escapedName}` : escapedName;\n}\n\n// Generate connections and isolated nodes\nconst connections = [];\nconst isolatedNodes = new Set(Object.keys(nodeMap));\n\nif (workflow.connections) {\n Object.entries(workflow.connections).forEach(([sourceName, targetConnections]) => {\n Object.entries(targetConnections).forEach(([connectionType, targets]) => {\n targets.forEach(targetArray => {\n targetArray.forEach(target => {\n const sourceNode = nodeMap[sourceName];\n const targetNode = nodeMap[target.node];\n if (sourceNode && targetNode) {\n let connectionLine = ` ${sourceNode.id}${sourceNode.brackets[0]}${formatNodeText(sourceName, sourceNode.disabled)}${sourceNode.brackets[1]}`;\n if (connectionType === 'main') {\n connectionLine += ` -->`;\n } else {\n connectionLine += ` -.- |${connectionType}|`;\n }\n connectionLine += ` ${targetNode.id}${targetNode.brackets[0]}${formatNodeText(target.node, targetNode.disabled)}${targetNode.brackets[1]}`;\n connections.push(connectionLine);\n isolatedNodes.delete(sourceName);\n isolatedNodes.delete(target.node);\n }\n });\n });\n });\n });\n}\n\n// Add isolated nodes to the connections array\nisolatedNodes.forEach(nodeName => {\n const node = nodeMap[nodeName];\n connections.push(` ${node.id}${node.brackets[0]}${formatNodeText(nodeName, node.disabled)}${node.brackets[1]}`);\n});\n\n// Generate the Mermaid flowchart string\nconst mermaidChart = `---\nconfig:\n look: neo\n theme: default\n---\nflowchart LR\n${connections.join('\\n')}`;\n\n// Output the result\nreturn {\n json: {\n mermaidChart: mermaidChart\n }\n};" +}, +"typeVersion": 2 +}, +{ +"id": "77a35cd5-cb8f-4ac5-a699-dff5e65cda09", +"name": "Merge2", +"type": "n8n-nodes-base.merge", +"position": [ +3840, +1140 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "f8119590-e9d7-4513-9da4-fa911165baff", +"name": "Generated Doc", +"type": "n8n-nodes-base.set", +"position": [ +4000, +1240 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "7693348d-5129-4a07-809d-b0619b9fc44b", +"name": "workflowdata", +"type": "string", +"value": "=# {{ $json.name }}\n\n{{ $json?.output?.workflow_description || \"## \" }}\n\n## Workflow schematic\n\n```mermaid\n{{ $json.mermaidChart }}\n```\n\n{{ $json?.output?.nodes_settings || \"## \" }}" +} +] +} +}, +"typeVersion": 3.4 +}, +{ +"id": "92565206-6cf2-4243-9143-4f6def4b524d", +"name": "Passthrough", +"type": "n8n-nodes-base.noOp", +"position": [ +2100, +1240 +], +"parameters": {}, +"typeVersion": 1 +}, +{ +"id": "73081fc3-9554-4a12-b985-da02b356616f", +"name": "Merge3", +"type": "n8n-nodes-base.merge", +"position": [ +3140, +880 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "f50e72f8-9027-4ca7-9df7-700e828f48eb", +"name": "Merge4", +"type": "n8n-nodes-base.merge", +"position": [ +960, +-100 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "306820ac-7c87-45c2-b76f-55d772ac7300", +"name": "Merge5", +"type": "n8n-nodes-base.merge", +"position": [ +960, +240 +], +"parameters": { +"mode": "combine", +"options": {}, +"combineBy": "combineByPosition" +}, +"typeVersion": 3 +}, +{ +"id": "96fd7265-7920-453f-8309-bdbd10880d03", +"name": "Edit Fields", +"type": "n8n-nodes-base.set", +"position": [ +2100, +1600 +], +"parameters": { +"options": {}, +"assignments": { +"assignments": [ +{ +"id": "8bc55c5b-e09a-459b-bbb6-ed5f70d4f353", +"name": "workflowdata", +"type": "string", +"value": "={{ $json.body.content }}" +} +] +}, +"includeOtherFields": true +}, +"typeVersion": 3.4 +}, +{ +"id": "2fffb547-1c11-4663-aed5-29b9557e8738", +"name": "Is Action Save?", +"type": "n8n-nodes-base.if", +"position": [ +4540, +1600 +], +"parameters": { +"options": {}, +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "e3648023-8cb7-4b82-bd35-1ba196458327", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json?.query?.action }}", +"rightValue": "save" +}, +{ +"id": "a44c9cc5-5717-4c34-978b-e644219a9cc1", +"operator": { +"type": "string", +"operation": "exists", +"singleValue": true +}, +"leftValue": "={{ $json?.query?.action }}", +"rightValue": "" +} +] +} +}, +"typeVersion": 2.2 +}, +{ +"id": "15825037-a8e2-4fbc-b529-2bf89810a116", +"name": "Merge6", +"type": "n8n-nodes-base.merge", +"position": [ +4360, +1700 +], +"parameters": { +"mode": "chooseBranch", +"useDataOfInput": 2 +}, +"typeVersion": 3 +}, +{ +"id": "b47f18a4-9b59-4278-890d-b6f6c596c554", +"name": "Respond OK on Save", +"type": "n8n-nodes-base.respondToWebhook", +"position": [ +4920, +1580 +], +"parameters": { +"options": { +"responseCode": 200 +}, +"respondWith": "noData" +}, +"typeVersion": 1.1 +}, +{ +"id": "273dfd58-abef-49b7-8f12-5abc3d3515a6", +"name": "single workflow", +"type": "n8n-nodes-base.webhook", +"position": [ +240, +240 +], +"webhookId": "135bc21f-c7d0-4afe-be73-f984d444b43b", +"parameters": { +"path": "/:file", +"options": {}, +"responseMode": "responseNode", +"multipleMethods": true +}, +"typeVersion": 2 +}, +{ +"id": "a7d7ee50-1420-475b-9028-0c80e1ae2241", +"name": "Sticky Note", +"type": "n8n-nodes-base.stickyNote", +"position": [ +140, +-242.54375384615383 +], +"parameters": { +"width": 296.5956923076922, +"height": 277.9529846153844, +"content": "## Main Docsify webhook\nIn response, n8n serves the main html page with the [Docsify JS library](https://docsify.js.org/)" +}, +"typeVersion": 1 +}, +{ +"id": "b7c4b82a-9722-48ae-ab6a-4335981356ad", +"name": "Sticky Note1", +"type": "n8n-nodes-base.stickyNote", +"position": [ +-77.62340912473337, +108.96056004923076 +], +"parameters": { +"width": 509.1040245093486, +"height": 287.9568584558579, +"content": "## Single page requests\n* Docsify may request default pages (i.e. `readme.md` or a `summary.md`)\n* GET request for the workflow documentation pages\n* POST request for saving manually edited doc page" +}, +"typeVersion": 1 +}, +{ +"id": "18e1f4c5-3652-4244-9a09-cd7a498a9310", +"name": "Sticky Note2", +"type": "n8n-nodes-base.stickyNote", +"position": [ +460, +-240.54580345183416 +], +"parameters": { +"color": 3, +"width": 489.50636350106504, +"height": 462.9720128227216, +"content": "## EDIT THIS!\n* `project_path` to link to a writable directory that is accessible to n8n\n* update `instance_url` when running in the cloud version. If using in self-hosted mode, make sure N8N_PROTOCOL and N8N_HOST .env variables are correct" +}, +"typeVersion": 1 +}, +{ +"id": "d505d2ec-33e9-4983-8265-ff55f0df3da8", +"name": "file types", +"type": "n8n-nodes-base.switch", +"position": [ +1180, +240 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": ".md", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "endsWith" +}, +"leftValue": "={{ $json.params.file.toLowerCase() }}", +"rightValue": ".md" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra", +"renameFallbackOutput": "unknown" +} +}, +"typeVersion": 3.2 +}, +{ +"id": "59362792-4a3e-4f97-95e2-d7b33b870e1d", +"name": "Sticky Note3", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4620, +-245.7696645512633 +], +"parameters": { +"width": 446.67466982248516, +"height": 309.89805271694365, +"content": "## Construct main HTML page and send it back to the user\n* `HTML_headers` and `HTML_docsify_include` are stored in the CONFIG node for the page simplicity" +}, +"typeVersion": 1 +}, +{ +"id": "83189146-4d1f-454e-9591-bdbfda676683", +"name": "Get All Workflows", +"type": "n8n-nodes-base.n8n", +"position": [ +1880, +160 +], +"parameters": { +"filters": { +"tags": "={{ decodeURIComponent(($json.params.file?.match(/^tag-(.+)\\.md$/))?.[1] || '') }}" +}, +"requestOptions": {} +}, +"credentials": { +"n8nApi": { +"id": "eW7IdTFt4ARJbEwR", +"name": "Ted n8n account" +} +}, +"typeVersion": 1, +"alwaysOutputData": true +}, +{ +"id": "39aa6017-a0ef-4f05-81b8-cfc9bb2fcc20", +"name": "Sticky Note4", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +20.913927466176517 +], +"parameters": { +"width": 820.1843305645202, +"height": 307.51990359708003, +"content": "## Serve main Markdown table with the workflow overview\n*NOTE! Here we don't reply with HTML content. Only Markdown elements are sent back and processed by the JS library*\n* Create an overall table when `README.md` (the home page) is requested\n* Create a table with a subset of workflows when a tag from a navigation pane is selected" +}, +"typeVersion": 1 +}, +{ +"id": "2d087c25-b998-4abc-b0ce-ede8e62e28b4", +"name": "md files", +"type": "n8n-nodes-base.switch", +"position": [ +1440, +180 +], +"parameters": { +"rules": { +"values": [ +{ +"outputKey": "README.md", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"operator": { +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.params.file }}", +"rightValue": "README.md" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "docs", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "c1c1aecc-8faa-47ea-b831-4674c3c0db61", +"operator": { +"type": "string", +"operation": "contains" +}, +"leftValue": "={{ $json.params.file }}", +"rightValue": "docs_" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "summary.md", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "fde643c9-31cd-4cbd-b4de-99a8ad6202af", +"operator": { +"name": "filter.operator.equals", +"type": "string", +"operation": "equals" +}, +"leftValue": "={{ $json.params.file }}", +"rightValue": "summary.md" +} +] +}, +"renameOutput": true +}, +{ +"outputKey": "tags", +"conditions": { +"options": { +"version": 2, +"leftValue": "", +"caseSensitive": true, +"typeValidation": "strict" +}, +"combinator": "and", +"conditions": [ +{ +"id": "df4bc9f8-9285-49a6-b31c-d7173bf42901", +"operator": { +"type": "string", +"operation": "startsWith" +}, +"leftValue": "={{ $json.params.file }}", +"rightValue": "tag-" +} +] +}, +"renameOutput": true +} +] +}, +"options": { +"fallbackOutput": "extra" +} +}, +"typeVersion": 3.2 +}, +{ +"id": "08524df2-d555-42ca-8440-57ca5a780b74", +"name": "Get Workflow tags", +"type": "n8n-nodes-base.n8n", +"position": [ +1880, +500 +], +"parameters": { +"filters": {}, +"requestOptions": {} +}, +"credentials": { +"n8nApi": { +"id": "eW7IdTFt4ARJbEwR", +"name": "Ted n8n account" +} +}, +"typeVersion": 1 +}, +{ +"id": "06e383dc-b1ea-4c97-9ee4-c07084ffc4cc", +"name": "Sticky Note5", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1780, +360 +], +"parameters": { +"width": 817.6163848212657, +"height": 288.20835077550953, +"content": "## Serve left pane content\n* Here all workflows are fetched again when `summary.md` file is requested.\n\nIt contains Markdown for the left navigation pane: a list of all tags" +}, +"typeVersion": 1 +}, +{ +"id": "c28ae282-7d83-42dd-8714-30d26b0f20af", +"name": "Sticky Note6", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1700, +1780 +], +"parameters": { +"width": 367.8950651848079, +"height": 262.5093167050718, +"content": "## Handle missing pages\nServe the Markdown content with the requested file name for edge cases, i.e. any unexpected files" +}, +"typeVersion": 1 +}, +{ +"id": "6441cf8f-dace-45fb-984e-aa9e0589e495", +"name": "Sticky Note7", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1020, +729 +], +"parameters": { +"color": 6, +"width": 4161.578473434268, +"height": 1142.0268674813442, +"content": "# Main functionality here\n\n## * View existing documentation\n## * Auto-generate doc page if no file available\n## * Re-created autodoc page\n## * Edit doc page: LIVE Markdown editor included!\n## * Save edited file. WARNING! No authentication" +}, +"typeVersion": 1 +}, +{ +"id": "9116a4eb-18c6-4ec2-84e8-9a0b920d5c19", +"name": "Sticky Note8", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4460, +751 +], +"parameters": { +"width": 652.3100890494833, +"height": 268.0620091282372, +"content": "## Custom markdown editor\nThis is another HTML page for the live Markdown editor\n* `Mermaid.js` is supported\n* Docsify preview on edit\n* Save or Cancel buttons" +}, +"typeVersion": 1 +}, +{ +"id": "920c1edb-29ad-4952-9e30-9020146ed88a", +"name": "Sticky Note9", +"type": "n8n-nodes-base.stickyNote", +"position": [ +4000, +1501 +], +"parameters": { +"width": 522.870786668288, +"height": 348.0868581511653, +"content": "## Save new file\nOnce the doc page is generated or edited manually, a Markdown files is saved in the directory" +}, +"typeVersion": 1 +}, +{ +"id": "cff4d2be-f627-4c7d-9f7a-093f6f9b2c27", +"name": "Sticky Note10", +"type": "n8n-nodes-base.stickyNote", +"position": [ +1887, +758 +], +"parameters": { +"width": 639.8696984316115, +"height": 429.7891698152571, +"content": "## Load existing doc file\nCheck the existing file when the View or Edit button is pressed\n" +}, +"typeVersion": 1 +}, +{ +"id": "b7f01785-99c7-47b2-967a-b7456bb8f562", +"name": "Sticky Note11", +"type": "n8n-nodes-base.stickyNote", +"position": [ +2786.9421822644376, +1023 +], +"parameters": { +"width": 1369.2986733206085, +"height": 466.42237140646773, +"content": "## If the file is not available, then:\n* either auto-generate new doc\n* prepare a basic template for editing" +}, +"typeVersion": 1 +}, +{ +"id": "6953bf0c-3122-4d80-9e74-1c07a892bf31", +"name": "docsify", +"type": "n8n-nodes-base.webhook", +"position": [ +240, +-100 +], +"webhookId": "8b719afe-8be3-4cd5-84ed-aca521b31a89", +"parameters": { +"path": "135bc21f-c7d0-4afe-be73-f984d444b43b", +"options": {}, +"responseMode": "responseNode" +}, +"typeVersion": 2 +} +], +"active": true, +"pinData": {}, +"settings": { +"callerPolicy": "workflowsFromSameOwner", +"executionOrder": "v1", +"executionTimeout": 120, +"saveManualExecutions": true, +"saveDataSuccessExecution": "all" +}, +"versionId": "eee9144a-c7a0-4947-874b-728d9e8618b7", +"connections": { +"Merge": { +"main": [ +[ +{ +"node": "Is Action Edit?1", +"type": "main", +"index": 0 +} +] +] +}, +"mkdir": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 1 +} +] +] +}, +"CONFIG": { +"main": [ +[ +{ +"node": "Merge4", +"type": "main", +"index": 1 +}, +{ +"node": "Merge5", +"type": "main", +"index": 0 +} +] +] +}, +"Merge1": { +"main": [ +[ +{ +"node": "HasFile?", +"type": "main", +"index": 0 +} +] +] +}, +"Merge2": { +"main": [ +[ +{ +"node": "Generated Doc", +"type": "main", +"index": 0 +} +] +] +}, +"Merge3": { +"main": [ +[ +{ +"node": "Is Action Edit?2", +"type": "main", +"index": 0 +} +] +] +}, +"Merge4": { +"main": [ +[ +{ +"node": "Main Page", +"type": "main", +"index": 0 +} +] +] +}, +"Merge5": { +"main": [ +[ +{ +"node": "file types", +"type": "main", +"index": 0 +} +] +] +}, +"Merge6": { +"main": [ +[ +{ +"node": "Is Action Save?", +"type": "main", +"index": 0 +} +] +] +}, +"docsify": { +"main": [ +[ +{ +"node": "CONFIG", +"type": "main", +"index": 0 +}, +{ +"node": "Merge4", +"type": "main", +"index": 0 +} +] +] +}, +"HasFile?": { +"main": [ +[ +{ +"node": "Extract from File", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Fetch Single Workflow1", +"type": "main", +"index": 0 +} +] +] +}, +"md files": { +"main": [ +[ +{ +"node": "Get All Workflows", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "doc action", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get Workflow tags", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Get All Workflows", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "No Operation, do nothing", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Page": { +"main": [ +[ +{ +"node": "Respond with HTML", +"type": "main", +"index": 0 +} +] +] +}, +"Empty Set": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"Main Page": { +"main": [ +[ +{ +"node": "Respond with main page HTML", +"type": "main", +"index": 0 +} +] +] +}, +"doc action": { +"main": [ +[ +{ +"node": "mkdir", +"type": "main", +"index": 0 +}, +{ +"node": "Load Doc File", +"type": "main", +"index": 0 +}, +{ +"node": "Passthrough", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "mkdir", +"type": "main", +"index": 0 +}, +{ +"node": "Load Doc File", +"type": "main", +"index": 0 +}, +{ +"node": "Passthrough", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "mkdir", +"type": "main", +"index": 0 +}, +{ +"node": "Empty Set", +"type": "main", +"index": 0 +}, +{ +"node": "Passthrough", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Edit Fields", +"type": "main", +"index": 0 +} +] +] +}, +"file types": { +"main": [ +[ +{ +"node": "md files", +"type": "main", +"index": 0 +} +] +] +}, +"Edit Fields": { +"main": [ +[ +{ +"node": "Convert to File", +"type": "main", +"index": 0 +}, +{ +"node": "Merge6", +"type": "main", +"index": 1 +} +] +] +}, +"Passthrough": { +"main": [ +[ +{ +"node": "Merge3", +"type": "main", +"index": 1 +}, +{ +"node": "Merge", +"type": "main", +"index": 0 +} +] +] +}, +"Generated Doc": { +"main": [ +[ +{ +"node": "Convert to File", +"type": "main", +"index": 0 +}, +{ +"node": "Is Action Edit?2", +"type": "main", +"index": 0 +} +] +] +}, +"Load Doc File": { +"main": [ +[ +{ +"node": "Merge1", +"type": "main", +"index": 0 +} +] +] +}, +"Workflow Tags": { +"main": [ +[ +{ +"node": "Respond with markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Blank Doc File": { +"main": [ +[ +{ +"node": "Is Action Edit?2", +"type": "main", +"index": 0 +} +] +] +}, +"Sort-workflows": { +"main": [ +[ +{ +"node": "Fill Workflow Table", +"type": "main", +"index": 0 +} +] +] +}, +"Basic LLM Chain": { +"main": [ +[ +{ +"node": "Merge2", +"type": "main", +"index": 1 +} +] +] +}, +"Convert to File": { +"main": [ +[ +{ +"node": "Save New Doc File", +"type": "main", +"index": 0 +} +] +] +}, +"Is Action Save?": { +"main": [ +[ +{ +"node": "Respond OK on Save", +"type": "main", +"index": 0 +} +] +] +}, +"single workflow": { +"main": [ +[ +{ +"node": "CONFIG", +"type": "main", +"index": 0 +}, +{ +"node": "Merge5", +"type": "main", +"index": 1 +} +], +[ +{ +"node": "CONFIG", +"type": "main", +"index": 0 +}, +{ +"node": "Merge5", +"type": "main", +"index": 1 +} +] +] +}, +"Is Action Edit?1": { +"main": [ +[ +{ +"node": "Blank Doc File", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Basic LLM Chain", +"type": "main", +"index": 0 +}, +{ +"node": "Merge2", +"type": "main", +"index": 0 +} +] +] +}, +"Is Action Edit?2": { +"main": [ +[ +{ +"node": "Edit Page", +"type": "main", +"index": 0 +} +], +[ +{ +"node": "Workflow md content", +"type": "main", +"index": 0 +} +] +] +}, +"Extract from File": { +"main": [ +[ +{ +"node": "Merge3", +"type": "main", +"index": 0 +} +] +] +}, +"Get All Workflows": { +"main": [ +[ +{ +"node": "Sort-workflows", +"type": "main", +"index": 0 +} +] +] +}, +"Get Workflow tags": { +"main": [ +[ +{ +"node": "Workflow Tags", +"type": "main", +"index": 0 +} +] +] +}, +"Instance overview": { +"main": [ +[ +{ +"node": "Respond with markdown", +"type": "main", +"index": 0 +} +] +] +}, +"OpenAI Chat Model": { +"ai_languageModel": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_languageModel", +"index": 0 +}, +{ +"node": "Auto-fixing Output Parser", +"type": "ai_languageModel", +"index": 0 +} +] +] +}, +"Save New Doc File": { +"main": [ +[ +{ +"node": "Merge6", +"type": "main", +"index": 0 +} +] +] +}, +"Fallback file name": { +"main": [ +[ +{ +"node": "Respond with markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Fill Workflow Table": { +"main": [ +[ +{ +"node": "Instance overview", +"type": "main", +"index": 0 +} +] +] +}, +"Workflow md content": { +"main": [ +[ +{ +"node": "Respond with markdown", +"type": "main", +"index": 0 +} +] +] +}, +"Fetch Single Workflow1": { +"main": [ +[ +{ +"node": "Generate Mermaid Chart", +"type": "main", +"index": 0 +}, +{ +"node": "Merge", +"type": "main", +"index": 1 +} +] +] +}, +"Generate Mermaid Chart": { +"main": [ +[ +{ +"node": "Merge", +"type": "main", +"index": 2 +} +] +] +}, +"No Operation, do nothing": { +"main": [ +[ +{ +"node": "Fallback file name", +"type": "main", +"index": 0 +} +] +] +}, +"Structured Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Auto-fixing Output Parser", +"type": "ai_outputParser", +"index": 0 +} +] +] +}, +"Auto-fixing Output Parser": { +"ai_outputParser": [ +[ +{ +"node": "Basic LLM Chain", +"type": "ai_outputParser", +"index": 0 +} +] +] +} +} +} \ No newline at end of file