{ "meta": { "instanceId": "workflow-b790b0bf", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:53.529229", "updatedAt": "2025-09-29T07:07:53.529240", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production" }, "nodes": [ { "id": "f4322829-1799-4954-a75a-b40e95f41c10", "name": "Get Last Week's Messages", "type": "n8n-nodes-base.slack", "position": [ -2200, -160 ], "webhookId": "8078218a-7edc-4e0b-9b4d-9860bd309877", "parameters": { "filters": { "oldest": "={{ $now.minus('1', 'week') }}", "inclusive": false }, "resource": "channel", "channelId": { "__rl": true, "mode": "list", "value": "C06RS1WPUQ6", "cachedResultName": "general" }, "operation": "history", "returnAll": true }, "credentials": { "slackApi": { "id": "VfK3js0YdqBdQLGP", "name": "Slack account" } }, "typeVersion": 2.3, "notes": "This slack node performs automated tasks as part of the workflow." }, { "id": "f0e89c19-ee1f-4a4d-8176-c222c18e0514", "name": "Simplify Message", "type": "n8n-nodes-base.set", "position": [ -1320, 380 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "547e8934-e6f2-47f0-b8a0-c60bd9d8a0c3", "name": "ts", "type": "string", "value": "={{ $json.ts }}" }, { "id": "22473b44-b1d9-4b85-b0d9-1a54c5511ff4", "name": "userId", "type": "string", "value": "={{ $('Get User').first().json.id }}" }, { "id": "2059b147-8b12-42c9-bee8-488dc11a0bf7", "name": "userName", "type": "string", "value": "={{ $('Get User').first().json.name }}" }, { "id": "34440ea6-ee99-4cd4-9e1c-cf561d335180", "name": "type", "type": "string", "value": "={{ $json.type }}" }, { "id": "ff1155c5-43e1-4e0e-82a8-9e013a7f1db1", "name": "text", "type": "string", "value": "={{ $json.text.replace(/(<@[^>]+>)/ig, '').trim() }}" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "1293a7cf-1467-432f-b7ed-606146618808", "name": "Group By User", "type": "n8n-nodes-base.code", "position": [ -2000, -160 ], "parameters": { "jsCode": "const keyByUser = $input.all()\n .map(item => item.json)\n .reduce((acc, message) => {\n return {\n ...acc,\n [message.user]: Array.isArray(acc[message.user])\n ? acc[message.user].concat(message)\n : [message]\n }\n }, {});\n\nreturn {\n data: Object\n .keys(keyByUser)\n .map(key => keyByUser[key])\n};" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "681a2368-9688-4ebd-bb88-f48c7ccb3e54", "name": "Split Out", "type": "n8n-nodes-base.splitOut", "position": [ -1800, -160 ], "parameters": { "options": {}, "fieldToSplitOut": "data" }, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow." }, { "id": "38a5e6b0-ba4a-4aaa-93f2-ec2a73e5e1af", "name": "Messages to Items", "type": "n8n-nodes-base.code", "position": [ -1540, 380 ], "parameters": { "jsCode": "return Object.values($('Switch').first().json.data)" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "066e40ef-91d7-4db0-95bb-2027c9251a23", "name": "Get User", "type": "n8n-nodes-base.slack", "position": [ -1760, 380 ], "webhookId": "042e9c13-5038-433a-98dc-8b6d83c015de", "parameters": { "user": { "__rl": true, "mode": "id", "value": "={{ $json.data['0'].user }}" }, "resource": "user" }, "credentials": { "slackApi": { "id": "VfK3js0YdqBdQLGP", "name": "Slack account" } }, "typeVersion": 2.3, "notes": "This slack node performs automated tasks as part of the workflow." }, { "id": "c5d0b4d1-94eb-4e14-9985-85d384d6d96f", "name": "Aggregate", "type": "n8n-nodes-base.aggregate", "position": [ -1100, 380 ], "parameters": { "options": {}, "aggregate": "aggregateAllItemData", "destinationFieldName": "messages" }, "typeVersion": 1, "notes": "This aggregate node performs automated tasks as part of the workflow." }, { "id": "47537a27-90d9-4edc-b9f4-66205bc4a4c2", "name": "Split Out1", "type": "n8n-nodes-base.splitOut", "position": [ -1760, 780 ], "parameters": { "options": {}, "fieldToSplitOut": "data.messages" }, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow." }, { "id": "6fdd0fc0-c563-46a3-afb2-48853d3e6cef", "name": "Get Thread", "type": "n8n-nodes-base.slack", "position": [ -1100, 780 ], "webhookId": "c3ef27dc-2648-4f91-b329-89a7fa833797", "parameters": { "ts": "={{ $json.ts }}", "filters": {}, "resource": "channel", "channelId": { "__rl": true, "mode": "list", "value": "C06RS1WPUQ6", "cachedResultName": "general" }, "operation": "replies" }, "credentials": { "slackApi": { "id": "VfK3js0YdqBdQLGP", "name": "Slack account" } }, "typeVersion": 2.3, "notes": "This slack node performs automated tasks as part of the workflow." }, { "id": "0fc6664f-9076-4525-acaa-0f5009de2611", "name": "Aggregate1", "type": "n8n-nodes-base.aggregate", "position": [ -440, 860 ], "parameters": { "options": {}, "aggregate": "aggregateAllItemData", "destinationFieldName": "replies" }, "typeVersion": 1, "notes": "This aggregate node performs automated tasks as part of the workflow." }, { "id": "caf963e5-3d5b-42d8-88ce-1fb5bf03a528", "name": "Simplify Thread Comments", "type": "n8n-nodes-base.set", "position": [ -660, 780 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "82bc8cbe-c606-4717-b29d-2d8acc149271", "name": "ts", "type": "string", "value": "={{ $json.ts }}" }, { "id": "8fcc957d-aa9f-47df-99e8-560228fde30f", "name": "userId", "type": "string", "value": "={{ $json.user }}" }, { "id": "e6c6deb3-c3ba-4452-be7c-1a0c42c5dc2c", "name": "userName", "type": "string", "value": "" }, { "id": "31d1206d-ecbd-48d3-a00a-845fd53d1cfa", "name": "type", "type": "string", "value": "={{ $json.type }}" }, { "id": "da126e6c-8dfc-41aa-991a-231b3cb3004b", "name": "text", "type": "string", "value": "={{ $json.text }}" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "aab0ae1c-50da-49e5-a373-c32b39108041", "name": "Filter", "type": "n8n-nodes-base.filter", "position": [ -880, 780 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "a6d43072-380e-40f2-985b-faeffdaffdce", "operator": { "type": "string", "operation": "notEquals" }, "leftValue": "={{ $('Split Out1').item.json.ts }}", "rightValue": "={{ $json.ts }}" } ] } }, "typeVersion": 2.2, "alwaysOutputData": true, "notes": "This filter node performs automated tasks as part of the workflow." }, { "id": "35cdb470-a9eb-4544-999c-5360dda0f1a3", "name": "Message Ref", "type": "n8n-nodes-base.noOp", "position": [ -1320, 780 ], "parameters": {}, "typeVersion": 1, "notes": "This noOp node performs automated tasks as part of the workflow." }, { "id": "95500787-7965-4951-a729-615feb636021", "name": "Split Out2", "type": "n8n-nodes-base.splitOut", "position": [ -1320, 1080 ], "parameters": { "options": {}, "fieldToSplitOut": "replyUsers" }, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow." }, { "id": "250d61cc-120d-4c0c-8220-f9a68a90b667", "name": "Map Reply UserIds", "type": "n8n-nodes-base.set", "position": [ -1760, 1160 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "dda6e3d8-0097-4621-9619-07cf39e93018", "name": "replyUsers", "type": "array", "value": "={{\n$json.data.messages\n .flatMap(item => item.replies.flatMap(reply => reply.userId))\n .compact()\n .unique()\n}}" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "3358736b-fc6e-4e18-9a58-4ffc59308055", "name": "Get Reply Users", "type": "n8n-nodes-base.slack", "position": [ -1100, 1080 ], "webhookId": "c9ad7c7e-2c48-4c24-9255-e04ab26252ab", "parameters": { "user": { "__rl": true, "mode": "id", "value": "={{ $json.replyUsers }}" }, "resource": "user" }, "credentials": { "slackApi": { "id": "VfK3js0YdqBdQLGP", "name": "Slack account" } }, "typeVersion": 2.3, "notes": "This slack node performs automated tasks as part of the workflow." }, { "id": "e98acd0f-f1e3-47f4-ae9c-7259462cf231", "name": "Google Gemini Chat Model", "type": "n8n-nodes-base.noOp", "position": [ -120, 1380 ], "parameters": { "options": {}, "modelName": "models/gemini-2.0-flash" }, "credentials": { "googlePalmApi": { "id": "dSxo6ns5wn658r8N", "name": "Google Gemini(PaLM) Api account" } }, "typeVersion": 1, "notes": "This lmChatGoogleGemini node performs automated tasks as part of the workflow." }, { "id": "0ffb9b87-43db-4417-8c37-384a33cbb830", "name": "Summarise Threads", "type": "n8n-nodes-base.noOp", "position": [ -220, 1160 ], "parameters": { "text": "=## Message\n{{ $json.userName }} (<@{{ $json.userId }}>) says at {{ new DateTime(parseFloat($json.ts)*1000).format('d MMM HH:mma') }}:\n> {{ $json.text }}\n\n## {{ ($json.replies ?? []).compact().length }} Replies\n{{\n($json.replies ?? [])\n .compact()\n .map(reply => ({\n ...reply,\n userName: $('Reply Users').item.json.data\n .find(user => user.id === reply.userId)?.name\n }))\n .map(reply =>\n `* ${new DateTime(parseFloat($json.ts)*1000).format('d MMM HH:mma')}, ${reply.userName} (<@${reply.userId}>) replies: ${reply.text}`\n)\n .join('\\n')\n \n}}", "messages": { "messageValues": [ { "message": "=Summarize the topic of the slack message and the resulting conversation from the replies (if any). Highlight any achievements, accomplishments, attempts or challenges mentioned." } ] }, "promptType": "define" }, "typeVersion": 1.6, "notes": "This chainLlm node performs automated tasks as part of the workflow." }, { "id": "678a48ec-acb1-4c42-b8c9-d4cd762e4a2a", "name": "Aggregate2", "type": "n8n-nodes-base.aggregate", "position": [ 160, 1160 ], "parameters": { "options": {}, "aggregate": "aggregateAllItemData" }, "typeVersion": 1, "notes": "This aggregate node performs automated tasks as part of the workflow." }, { "id": "ab39b117-e1bd-495f-a92d-fb79973b3601", "name": "Aggregate Reply Users", "type": "n8n-nodes-base.aggregate", "position": [ -880, 1080 ], "parameters": { "options": {}, "aggregate": "aggregateAllItemData" }, "typeVersion": 1, "notes": "This aggregate node performs automated tasks as part of the workflow." }, { "id": "c71b7ca6-8245-4262-b2f1-abea511390d6", "name": "Reply Users", "type": "n8n-nodes-base.set", "position": [ -660, 1160 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "9f721cde-2d36-40ee-b7d8-a920695157a9", "name": "data", "type": "array", "value": "={{ $json.data ?? [] }}" } ] } }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "4b2c452b-4e68-4536-aa58-a85fd586c606", "name": "Google Gemini Chat Model1", "type": "n8n-nodes-base.noOp", "position": [ -460, 0 ], "parameters": { "options": {}, "modelName": "models/gemini-2.0-flash" }, "credentials": { "googlePalmApi": { "id": "dSxo6ns5wn658r8N", "name": "Google Gemini(PaLM) Api account" } }, "typeVersion": 1, "notes": "This lmChatGoogleGemini node performs automated tasks as part of the workflow." }, { "id": "d65b4f27-52ab-4c29-8692-ee2835fddd17", "name": "Loop Over Items", "type": "n8n-nodes-base.splitInBatches", "position": [ -1540, 780 ], "parameters": { "options": {} }, "typeVersion": 3, "notes": "This splitInBatches node performs automated tasks as part of the workflow." }, { "id": "cfb55c7f-a89d-4ce4-8709-31e5e119c6ee", "name": "Aggregate3", "type": "n8n-nodes-base.set", "position": [ -1320, 580 ], "parameters": { "mode": "raw", "options": {}, "jsonOutput": "={{\n{\n ...$('Split Out1').item.json,\n replies: $json.replies.filter(reply => reply.ts)\n}\n}}\n" }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "8b70e30c-99d5-4086-85aa-e6cfcc7f14e7", "name": "Aggregate4", "type": "n8n-nodes-base.aggregate", "position": [ -1100, 580 ], "parameters": { "options": {}, "aggregate": "aggregateAllItemData" }, "typeVersion": 1, "notes": "This aggregate node performs automated tasks as part of the workflow." }, { "id": "1cef5853-d301-49cb-9f58-c1a9128b8b33", "name": "When Executed by Another Workflow", "type": "n8n-nodes-base.executeWorkflowTrigger", "position": [ -2200, 780 ], "parameters": { "workflowInputs": { "values": [ { "name": "action" }, { "name": "data", "type": "object" } ] } }, "typeVersion": 1.1, "notes": "This executeWorkflowTrigger node performs automated tasks as part of the workflow." }, { "id": "b30c2433-3bfe-480f-a4bd-8c41900802a2", "name": "Switch", "type": "n8n-nodes-base.switch", "position": [ -1980, 780 ], "parameters": { "rules": { "values": [ { "outputKey": "YOUR_CREDENTIAL_HERE", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "fa924990-9f6e-40c4-aaec-50d4f5927414", "operator": { "type": "string", "operation": "equals" }, "leftValue": "={{ $json.action }}", "rightValue": "users" } ] }, "renameOutput": true }, { "outputKey": "YOUR_CREDENTIAL_HERE", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "26ce01b2-9e5b-43e8-926d-9d726c9ca74d", "operator": { "name": "filter.operator.equals", "type": "string", "operation": "equals" }, "leftValue": "={{ $json.action }}", "rightValue": "message_replies" } ] }, "renameOutput": true }, { "outputKey": "YOUR_CREDENTIAL_HERE", "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "45fd7264-6ac3-4bbd-8a91-c4cfb33b4545", "operator": { "name": "filter.operator.equals", "type": "string", "operation": "equals" }, "leftValue": "={{ $json.action }}", "rightValue": "message_summarize" } ] }, "renameOutput": true } ] }, "options": {} }, "typeVersion": 3.2, "notes": "This switch node performs automated tasks as part of the workflow." }, { "id": "b05735c3-4beb-4a80-8297-85e952e81270", "name": "Map Users to Messages", "type": "n8n-nodes-base.executeWorkflow", "position": [ -1520, -160 ], "parameters": { "mode": "each", "options": {}, "workflowId": { "__rl": true, "mode": "id", "value": "={{ $workflow.id }}" }, "workflowInputs": { "value": { "data": "={{ $json }}", "action": "users" }, "schema": [ { "id": "action", "type": "string", "display": true, "required": false, "displayName": "action", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "data", "type": "object", "display": true, "required": false, "displayName": "data", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": true } }, "typeVersion": 1.2, "notes": "This executeWorkflow node performs automated tasks as part of the workflow." }, { "id": "28ed52b2-b0c3-4f19-b394-347c8ff9e323", "name": "Get User Info", "type": "n8n-nodes-base.set", "position": [ -880, 380 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "17344879-1e10-4738-8db0-6e0daddea920", "name": "user", "type": "object", "value": "={{\n{\n id: $('Get User').item.json.id,\n team_id: $('Get User').item.json.team_id,\n name: $('Get User').item.json.name,\n is_bot: $('Get User').item.json.is_bot\n}\n}}" } ] }, "includeOtherFields": true }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "bbd7c77e-2405-4e63-ae38-f064beafab9c", "name": "Fetch Message Replies", "type": "n8n-nodes-base.executeWorkflow", "position": [ -1300, -160 ], "parameters": { "mode": "each", "options": {}, "workflowId": { "__rl": true, "mode": "id", "value": "={{ $workflow.id }}" }, "workflowInputs": { "value": { "data": "={{ $json }}", "action": "message_replies" }, "schema": [ { "id": "action", "type": "string", "display": true, "removed": false, "required": false, "displayName": "action", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "data", "type": "object", "display": true, "removed": false, "required": false, "displayName": "data", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": true } }, "typeVersion": 1.2, "notes": "This executeWorkflow node performs automated tasks as part of the workflow." }, { "id": "edf34e72-04b4-4fed-a3af-42dec1c7ed17", "name": "Has ReplyUsers?", "type": "n8n-nodes-base.if", "position": [ -1540, 1160 ], "parameters": { "options": {}, "conditions": { "options": { "version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "813d9fea-9de0-4151-aa45-d38a42f808b8", "operator": { "type": "array", "operation": "notEmpty", "singleValue": true }, "leftValue": "={{ $json.replyUsers }}", "rightValue": "" } ] } }, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow." }, { "id": "dc9c6cf0-c627-4311-9160-62204e9b67e0", "name": "Messages to Items1", "type": "n8n-nodes-base.code", "position": [ -440, 1160 ], "parameters": { "jsCode": "return $('Switch').first().json.data.messages" }, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow." }, { "id": "0b830a49-c77e-41f3-8d70-47a26bfe0a0e", "name": "Aggregate Results", "type": "n8n-nodes-base.set", "position": [ -760, -160 ], "parameters": { "mode": "raw", "options": {}, "jsonOutput": "={{\n{\n ...$('Map Users to Messages').item.json,\n messages: $('Fetch Message Replies').item.json.data\n .map((message,idx) => ({\n ...message,\n summary: $json.data[idx].text,\n }))\n}\n}}" }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "b0c66c7f-0fed-465c-8933-7b803c9b3b64", "name": "Team Member Weekly Report Agent", "type": "n8n-nodes-base.noOp", "position": [ -560, -160 ], "parameters": { "text": "={{\n$json.messages\n .map((message,idx) =>\n `${message.userName} (<@${message.userId}>) posted on ${new Date(parseFloat(message.ts) * 1000).format('d MMM')}:\\n> \\\"${message.text}\\\".\\nThe summary of this thread is as follows:\\n${message.summary.replaceAll('\\n', ' ')}`\n )\n .join('\\n---\\n')\n}}", "messages": { "messageValues": [ { "message": "=Your are energetic assistant who produces weekly mini-reports on team members by analysing their slack messages from last week and posts these reports on the following Monday.\nThere has already been some work done to collect and summarise each thread made by the user within the last week.\nYour task is to summarize all the threads by this user and any interactions with other users involved and produce a mini report to share with other team members.\nFocus on wins and challenges.\nAim to motivate and call out any outstanding concerns where appropriate.\nWelcome any new team members who may have joined and say good bye to those who may have left." } ] }, "promptType": "define" }, "typeVersion": 1.6, "notes": "This chainLlm node performs automated tasks as part of the workflow." }, { "id": "e4a487ae-8d71-4fe6-a760-7a0fb95a8fac", "name": "Merge with Results", "type": "n8n-nodes-base.set", "position": [ -60, -160 ], "parameters": { "mode": "raw", "options": {}, "jsonOutput": "={{\n{\n ...$('Aggregate Results').item.json,\n report: $json.text,\n}\n}}" }, "typeVersion": 3.4, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "06736a5c-7450-406a-ad3a-08a368d1addf", "name": "Team Weekly Report Agent", "type": "n8n-nodes-base.noOp", "position": [ 160, -160 ], "parameters": { "text": "={{\n$input.all()\n .map(item => item.json)\n .map(item =>\n`user: ${item.user.name} <@${item.user.id}>\nmessage count: ${item.messages.length}\nreport: ${item.report.replaceAll('\\n', ' ')}`\n ).join('\\n---\\n')\n}}", "messages": { "messageValues": [ { "message": "=Your are energetic assistant who produces a team-wide weekly report from all activity of all team members in the prior last week and posts this single report on the following Monday.\nThere has already been some work done to collect individual reports from team members.\nYour task is generate a report covering the team to prepare and motivate them for the upcoming week.\nFocus on wins and challenges if available.\nLook out for similar activities between members and make a connection if possible.\nAim to motivate and call out any outstanding concerns where appropriate.\nWelcome any new team members who may have joined and say good bye to those who may have left." } ] }, "promptType": "define" }, "executeOnce": true, "typeVersion": 1.6, "notes": "This chainLlm node performs automated tasks as part of the workflow." }, { "id": "eef36957-9bf0-4be3-95a8-73bbefdc0c85", "name": "Google Gemini Chat Model2", "type": "n8n-nodes-base.noOp", "position": [ 240, 0 ], "parameters": { "options": {}, "modelName": "models/gemini-2.0-flash" }, "credentials": { "googlePalmApi": { "id": "dSxo6ns5wn658r8N", "name": "Google Gemini(PaLM) Api account" } }, "typeVersion": 1, "notes": "This lmChatGoogleGemini node performs automated tasks as part of the workflow." }, { "id": "bfa5c99f-cd8f-4d34-9e6d-9ed476c87d22", "name": "Post Report in Team Channel", "type": "n8n-nodes-base.slack", "position": [ 820, -160 ], "webhookId": "3613b3ca-fc98-427f-8903-a5996ff7552e", "parameters": { "text": "={{ $json.text }}", "select": "channel", "channelId": { "__rl": true, "mode": "list", "value": "C06RS1WPUQ6", "cachedResultName": "general" }, "otherOptions": {} }, "credentials": { "slackApi": { "id": "VfK3js0YdqBdQLGP", "name": "Slack account" } }, "typeVersion": 2.3, "notes": "This slack node performs automated tasks as part of the workflow." }, { "id": "b9a11c72-de41-4a45-85a0-672cf54ef152", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ -2460, -440 ], "parameters": { "color": 7, "width": 820, "height": 520, "content": "## 1. Fetch All Activity from Last Week\n[Learn more about the Slack node]({{ $env.WEBHOOK_URL }}\n\nWe'll start by fetching all activity in our team channel over the last 7 days and group them by the message author. We can do this using the Slack node with a DateTime filter. This will give us the raw data to pick apart and analyse for reporting purposes." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "8afc048f-ce06-46c3-916f-cbcf14bcfe2b", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ -1620, -440 ], "parameters": { "color": 7, "width": 760, "height": 520, "content": "## 2. Summarise Messages Threads & Conversations\n[Learn more about the Execute Workflow node]({{ $env.WEBHOOK_URL }}\n\nWe'll do some more data mining by fetching all replies for each of these top level channel messages. By doing so, we get the full context of the conversation and can hopefully pick up some decisions, discoveries or concerns to add to our report. This data mining does require juggling a lot of \"items\" which becomes hard to manage so we'll use subworkflows to simplify this work.\n\nOnce the data mining is complete, we can summarize each thread with AI and ensure we're capturing only the significant events which are report-worthy." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "c9a7358c-fbe7-435a-b435-d7b07599bdc6", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ -840, -440 ], "parameters": { "color": 7, "width": 660, "height": 620, "content": "## 3. Generate Activity Reports for Each Team Member\n[Learn more about the Basic LLM node]({{ $env.WEBHOOK_URL }}\n\nWith our summarized threads which are grouped per user, we can aggregate them and give them to the AI again to generate a weekly report for the team member. This could include their wins, challenges, learnings or decisions - it really is up to you as to what the report looks like.\n\nA fun part of this output is getting to decide the tone of voice and delivery of the report. Don't be a bore and consider adding some personality and flair!" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "add32ef0-b515-44e6-a234-0a0fa77f4e84", "name": "Summarize Message Threads", "type": "n8n-nodes-base.executeWorkflow", "position": [ -1080, -160 ], "parameters": { "mode": "each", "options": {}, "workflowId": { "__rl": true, "mode": "id", "value": "={{ $workflow.id }}" }, "workflowInputs": { "value": { "data": "={{\n{\n ...$('Map Users to Messages').item.json,\n messages: $json.data\n}\n}}", "action": "message_summarize" }, "schema": [ { "id": "action", "type": "string", "display": true, "removed": false, "required": false, "displayName": "action", "defaultMatch": false, "canBeUsedToMatch": true }, { "id": "data", "type": "object", "display": true, "removed": false, "required": false, "displayName": "data", "defaultMatch": false, "canBeUsedToMatch": true } ], "mappingMode": "defineBelow", "matchingColumns": [], "attemptToConvertTypes": false, "convertFieldsToString": true } }, "typeVersion": 1.2, "notes": "This executeWorkflow node performs automated tasks as part of the workflow." }, { "id": "17f2f45e-2c95-4b3c-b6db-a2881ae88964", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [ -160, -440 ], "parameters": { "color": 7, "width": 680, "height": 620, "content": "## 4. Generate Final Report for Whole Team\n[Learn more about the Basic LLM node]({{ $env.WEBHOOK_URL }}\n\nIn this step, we go one level higher and aggregate all individual team member reports together into a big team report. In this way, the overview can group similar activities and generalise activities in a broader sense. The message output will also be shorter which some may find easier to digest." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "18cc7fa7-603c-4165-97c6-80d72fd4a9a6", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [ 540, -440 ], "parameters": { "color": 7, "width": 680, "height": 620, "content": "## 5. Post Report on Team Channel (on Monday Morning!)\n[Learn more about the Slack node]({{ $env.WEBHOOK_URL }}\n\nFinally, we can post the weekly report in the team channel. This is a great way to automate quick recaps for the team after the weekend break, get others back on track if they've been away or update client team who may pop in now and again to collaborate." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "9cd8bdd6-5fc7-4e44-bcd0-058bc5d11335", "name": "Sticky Note5", "type": "n8n-nodes-base.stickyNote", "position": [ -2460, 360 ], "parameters": { "color": 7, "width": 560, "height": 340, "content": "## 5. SubWorkflows\n[Read more about Execute Workflow Trigger]({{ $env.WEBHOOK_URL }}\n\nIncorporating Subworkflows into your main workflow is an advanced technique and sometimes necessary if you're working with a lot of nested items or loops.\n\nIn this scenario, we perform quite a few lookups to get the data we need; users, messages and replies, which in template terms would require many loop nodes to string together. However, when you nest loops nodes within loop nodes, item reference becomes difficult to keep track of.\n\nUsing subworkflows, we can break down each loop into a separate execution which handles items and item references in a simpler, linear way. The result is predictable data flow throughout our template. " }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "6f6fc730-5fc8-4dcc-b86d-e3b2f0e792a0", "name": "Monday @ 6am", "type": "n8n-nodes-base.scheduleTrigger", "position": [ -2400, -160 ], "parameters": { "rule": { "interval": [ { "field": "cronExpression", "expression": "0 6 * * 1" } ] } }, "typeVersion": 1.2, "notes": "This scheduleTrigger node performs automated tasks as part of the workflow." }, { "id": "ab94557c-debb-425c-ac83-62e39e43d28b", "name": "Sticky Note6", "type": "n8n-nodes-base.stickyNote", "position": [ -2940, -1380 ], "parameters": { "width": 420, "height": 1460, "content": "## Try It Out!\n### This n8n template lets you summarize individual team member activity on slack for the past week and generates a report.\n\nFor remote teams, chat is a crucial communication tool to ensure work gets done but with so many conversations happening at once and in multiple threads, ideas, information and decisions usually live in the moment and get lost just as quickly - and all together forgotten by the weekend!\n\nUsing this template, this doesn't have to be the case. Have AI crawl through last week's activity, summarize all threads and generate a casual and snappy report to bring the team back into focus for the current week. A project manager's dream!\n\n### How it works\n* A scheduled trigger is set to run every Monday at 6am to gather all team channel messages within the last week.\n* Each message thread are grouped by user and data mined for replies.\n* Combined, an AI analyses the raw messages to pull out interesting observations and highlights.\n* The summarized threads of the user are then combined together and passed to another AI agent to generate a higher level overview of their week. These are referred to as the individual reports.\n* Next, all individual reports are summarized together into a team weekly report. This allows understanding of group and similar activities.\n* Finally, the team weekly report is posted back to the channel. The timing is important as it should be the first message of the week and ready for the team to glance over coffee.\n\n### How to use\n* Ideally works best per project and where most of the comms happens on a single channel. Avoid combining channels and instead duplicate this workflow for more channels.\n* You may need to filter for specific team members if you want specific team updates.\n* Customise the report to suit your organisation, team or the channel. You may prefer to be more formal if clients or external stakeholders are also present.\n\n### Requirements\n* Slack for chat platform\n* Gemini for LLM\n\n### Customising this workflow\n* If the slack channel is busy enough already, consider posting the final report to email.\n* Pull in project metrics to include in your report. As extra context, it may be interesting to tie the messages to production performance.\n* Use an AI Agent to query for knowledgebase or tickets relevant to the messages. This may be useful for attaching links or references to add context.\n\n### Need Help?\nJoin the [Discord]({{ $env.WEBHOOK_URL }} or ask in the [Forum]({{ $env.WEBHOOK_URL }}\n\nHappy Hacking!" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "error-d0beee67", "name": "Error Handler", "type": "n8n-nodes-base.stopAndError", "typeVersion": 1, "position": [ 1000, 400 ], "parameters": { "message": "Workflow execution error", "options": {} } } ], "pinData": {}, "connections": { "f4322829-1799-4954-a75a-b40e95f41c10": { "main": [ [ { "node": "error-handler-f4322829-1799-4954-a75a-b40e95f41c10-116c59b0", "type": "main", "index": 0 } ] ] }, "066e40ef-91d7-4db0-95bb-2027c9251a23": { "main": [ [ { "node": "error-handler-066e40ef-91d7-4db0-95bb-2027c9251a23-32b18a16", "type": "main", "index": 0 } ] ] }, "6fdd0fc0-c563-46a3-afb2-48853d3e6cef": { "main": [ [ { "node": "error-handler-6fdd0fc0-c563-46a3-afb2-48853d3e6cef-59293381", "type": "main", "index": 0 } ] ] }, "3358736b-fc6e-4e18-9a58-4ffc59308055": { "main": [ [ { "node": "error-handler-3358736b-fc6e-4e18-9a58-4ffc59308055-11544dff", "type": "main", "index": 0 } ] ] }, "e98acd0f-f1e3-47f4-ae9c-7259462cf231": { "main": [ [ { "node": "error-handler-e98acd0f-f1e3-47f4-ae9c-7259462cf231-0e6c1050", "type": "main", "index": 0 } ] ] }, "4b2c452b-4e68-4536-aa58-a85fd586c606": { "main": [ [ { "node": "error-handler-4b2c452b-4e68-4536-aa58-a85fd586c606-defc2fb7", "type": "main", "index": 0 } ] ] }, "eef36957-9bf0-4be3-95a8-73bbefdc0c85": { "main": [ [ { "node": "error-handler-eef36957-9bf0-4be3-95a8-73bbefdc0c85-f6c2568c", "type": "main", "index": 0 } ] ] }, "bfa5c99f-cd8f-4d34-9e6d-9ed476c87d22": { "main": [ [ { "node": "error-handler-bfa5c99f-cd8f-4d34-9e6d-9ed476c87d22-95fa42b5", "type": "main", "index": 0 } ] ] } }, "name": "Slack Workflow", "settings": { "executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000 }, "description": "Automated workflow: Slack Workflow. This workflow integrates 17 different services: filter, stickyNote, code, lmChatGoogleGemini, scheduleTrigger. It contains 55 nodes and follows best practices for error handling and security.", "tags": [ "automation", "n8n", "production-ready", "excellent", "optimized" ], "notes": "Excellent quality workflow: Slack Workflow. This workflow has been optimized for production use with comprehensive error handling, security, and documentation." }