{
  "nodes": [
    {
      "id": "38fa9013-e16e-45b1-8f10-f56d77ed8925",
      "name": "Get many messages in Gmail",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        176,
        288
      ],
      "parameters": {
        "filters": {
          "sender": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Sender', ``, 'string') }}",
          "receivedAfter": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Received_After', ``, 'string') }}"
        },
        "operation": "getAll",
        "returnAll": "=5"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "54604c11-6cec-4ec7-9f47-2582512c3699",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -64,
        256
      ],
      "parameters": {
        "sessionKey": "1",
        "sessionIdType": "customKey"
      },
      "typeVersion": 1.3
    },
    {
      "id": "aa8bbe08-5d3f-4ae7-8b8e-772c1b9ff54b",
      "name": "Get many notes in Pipedrive",
      "type": "n8n-nodes-base.pipedriveTool",
      "position": [
        304,
        352
      ],
      "parameters": {
        "resource": "note",
        "operation": "getAll",
        "additionalFields": {}
      },
      "credentials": {
        "pipedriveApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6ecef126-97f9-4471-9dd8-3fedc8b62f46",
      "name": "Search for messages in Slack",
      "type": "n8n-nodes-base.slackTool",
      "position": [
        464,
        288
      ],
      "parameters": {
        "query": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Search_Query', ``, 'string') }}",
        "options": {
          "searchChannel": [
            "all-pollupdotnet"
          ]
        },
        "operation": "search",
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "2bee405b-84a1-45ac-9ad7-dab44e7eff42",
      "name": "Structured Output Parser1",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1136,
        240
      ],
      "parameters": {
        "jsonSchemaExample": "[\n\t{\"original_text\": \"\",\n\t\"signals\": [\"\", \"\"]\n}]"
      },
      "typeVersion": 1.3
    },
    {
      "id": "281968cd-d3ce-4768-b93f-207ce58afe79",
      "name": "Structured Output Parser2",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1488,
        240
      ],
      "parameters": {
        "jsonSchemaExample": "[\n  {\n    \"label\": \"Billing\",\n    \"count\": 8,\n    \"examples\": [\n      \"Unable to update billing info due to error 502\",\n      \"Invoice shows wrong amount\"\n    ]\n  }\n]"
      },
      "typeVersion": 1.3
    },
    {
      "id": "23961b86-28a8-4ad3-a9bf-28c16c80329d",
      "name": "Create a ticket in Zendesk",
      "type": "n8n-nodes-base.zendeskTool",
      "position": [
        1760,
        240
      ],
      "parameters": {
        "description": "={{ $fromAI('description', ``, 'string') }}",
        "additionalFields": {
          "subject": "={{ $fromAI('subject', ``, 'string') }}"
        }
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "10f31278-688b-47b1-9f1c-d1b6e461775e",
      "name": "Send a message in Gmail",
      "type": "n8n-nodes-base.gmailTool",
      "position": [
        1872,
        304
      ],
      "parameters": {
        "sendTo": "=thomas@pollup.net",
        "message": "={{ $fromAI('Message', ``, 'string') }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $fromAI('Subject', ``, 'string') }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "0fbfe83a-d1ee-460d-8c89-0d841b09cf5a",
      "name": "Data agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        240,
        16
      ],
      "parameters": {
        "text": "=- Get te 5 last emails sent after {{Date.now() - 7 * 24 * 60 * 60 * 1000}}. Return only the Subject and the snippet.\n- Get **ALL** the messages from Slack return the user ID as customerId.\n- Get **ALL** the notes from Pipedrive. Return person_id as the customerId\n- Get **ALL** the tickets from Zendesk. Return requester_id as customerId",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "df85a2a7-1fcb-4360-8574-1104f81db94e",
      "name": "Clustering agent",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1200,
        16
      ],
      "parameters": {
        "text": "=Prompt:\nYou will receive a set of short customer feedback signals.\nYour task: group them by shared topic or problem and assign each group a clear, human-readable label.\n\nRules:\n\t\u2022\tLabels should be broad enough to cover all items in the group, but still actionable (e.g. Billing, Onboarding, Performance, Feature Requests).\n\t\u2022\tAvoid vague labels like General Feedback unless no pattern exists.\n\t\u2022\tEach cluster must include:\n\t\u2022\tLabel\n\t\u2022\tCount of items\n\t\u2022\tRepresentative examples (1\u20133 feedback snippets).\n\n {{ JSON.stringify($json.output) }}",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "98aa8893-5fb3-44a8-84ef-e2cf8c9c3632",
      "name": "Signals agent",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        832,
        16
      ],
      "parameters": {
        "text": "=Prompt:\nYou are analyzing raw customer feedback from multiple sources (Gmail, Slack, Pipedrive, Zendesk).\nYour task: compress the \"text\" of each feedback into a concise signal (1\u20132 sentences max) that captures the core issue, request, or sentiment without losing meaning.\n\nRules:\n\t\u2022\tStrip away greetings, signatures, and filler.\n\t\u2022\tKeep specific product terms, error codes, or feature names if present.\n\t\u2022\tNeutral, factual tone (don\u2019t add assumptions).\n\t\u2022\tIf the text is vague, summarize it at the same level of vagueness.\n\t\u2022\tOutput only the summary text, no extra commentary.\n\nExample:\n\t\u2022\tInput: \u201cHi team, I\u2019ve tried three times to update my billing info but the system keeps failing with error 502. Can someone help?\u201d\n\t\u2022\tOutput: Customer unable to update billing info due to repeated error 502. \n\nHere is the content:\n{{ JSON.stringify($json.output) }}",
        "batching": {
          "batchSize": 5
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.7
    },
    {
      "id": "96afc994-3436-4091-b611-b263c5bfcfe4",
      "name": "Create a database page in Notion",
      "type": "n8n-nodes-base.notionTool",
      "position": [
        2080,
        240
      ],
      "parameters": {
        "title": "={{ $fromAI('title', ``, 'string') }}",
        "simple": false,
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "280c938a-7422-80b2-9227-c86cf9bbe478",
          "cachedResultUrl": "https://www.notion.so/280c938a742280b29227c86cf9bbe478",
          "cachedResultName": "Incidences"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Content|rich_text",
              "textContent": "={{ $fromAI('content', ``, 'string') }}"
            }
          ]
        }
      },
      "credentials": {
        "notionApi": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": false,
      "typeVersion": 2.2
    },
    {
      "id": "789f5961-b752-478d-b812-eae4f2519238",
      "name": "Action agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "onError": "continueRegularOutput",
      "position": [
        1600,
        16
      ],
      "parameters": {
        "text": "=Prompt:\nYou will receive a list of feedback clusters, each with a label, count, and examples.\nFirst you will send the processed input to \"{{ $('Set  CSM email').item.json['CSM email'] }}\" with the subject \"Weekly digest\"\nYour task: decide the correct destination action for each cluster based on the label and the count if it is superior to 1. Each message will have the examples in it.\n\n## Routing Rules:\n### Performance / Feature gaps \u2192 Product\n    - Create a zendesk ticket with the label as the \"subject\" and the examples as the \"description\".\n\n### Billing / Contract issues \u2192 Finance or Sales Ops\n  - Post message to Slack channel #billing-feedback with the examples as the text preceded by \"Billing / Contract Issues\"\n\n### Sales and Deal Negotiations\n  - Create Notion task with the label as the title and the examples as the content\n\n### High-risk sentiment / VIP account \u2192 CS Manager\n  - Send direct email to cs Manager \"{{ $('Set  CSM email').item.json['CSM email'] }}\" with the **Subject** \"Problem with the software\" and the examples as the **Message**\n\n### Sales and customer engagement\n  -  Send direct email to cs Manager \"{{ $('Set  CSM email').item.json['CSM email'] }}\" with the **Subject** \"Customer engagement\" and the examples as the **Message**\n\n### Client Management and Proposals\n    -  Send direct email to cs Manager \"{{ $('Set  CSM email').item.json['CSM email'] }}\" with the **Subject** \"Client Management and Proposals\" with the examples as the **Message**\n  \nIf the cluster doesn\u2019t fit above, mark as \"unassigned\" and remove it from the output.\nThe input:\n {{ JSON.stringify($json.output) }}",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "79db4542-4698-4642-8752-ead3bd7daf83",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -384,
        128
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "04d17e22-0722-47e7-992d-2f52e5ff6c89",
      "name": "Send a message in Slack",
      "type": "n8n-nodes-base.slackTool",
      "position": [
        1968,
        336
      ],
      "parameters": {
        "text": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('Message_Text', ``, 'string') }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "billing-feedback"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "4de48589-db29-449f-afe3-110afaf6e17a",
      "name": "LLM",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        864,
        432
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {
          "temperature": 0
        }
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b8e08d87-c51a-4272-889e-851a5107a89a",
      "name": "Set  CSM email",
      "type": "n8n-nodes-base.set",
      "position": [
        -80,
        16
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "d69bdbe2-f51a-4956-9d5d-bfe3a82ec82d",
              "name": "CSM email",
              "type": "string",
              "value": "user@example.com"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "49f74165-a46d-439f-b110-cbd94e072d54",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -208,
        -80
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 256,
        "content": "## Variables\nset your CSM Or reponsible email here"
      },
      "typeVersion": 1
    },
    {
      "id": "d9b0caac-8195-4e5f-8593-f72e7a118053",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        -224
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 512,
        "content": "## Scheduling\n\nYou can set the frequency of the executions in the Schedulle trigger node.\nOr you can click on Testing to do a test run. "
      },
      "typeVersion": 1
    },
    {
      "id": "65fcee6b-1f95-4855-9cdf-9ddad6e7e783",
      "name": "Testing",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -384,
        -80
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "dbc3e267-f134-4ba3-9f7f-7b5ad8d9d5f6",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 352,
        "content": "## Data agent\nIs n charge of collecting data from varous sources. I put here those three as examples. But that can be modified and adapted to your specific needs. \nDon't forget to modify the prompt accordingly.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e8faa814-be17-4265-9ef8-227abf33b4e3",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 352,
        "content": "## Signal agent\nGenerates \"signals\" from user input. Modify this prompt if you have changed the sources of the Data Agent.\nUses a structured Output parser to Define the signals for each message\n"
      },
      "typeVersion": 1
    },
    {
      "id": "00f71f2d-b6bc-43c1-9d76-16f9d739e06b",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 352,
        "content": "## Clustering agent\n\nGroup the signal by topic, number them and outputs examples from it"
      },
      "typeVersion": 1
    },
    {
      "id": "33bcd3b6-e2d3-4f2e-988f-3ba72dd86067",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -944,
        -224
      ],
      "parameters": {
        "width": 368,
        "height": 1008,
        "content": "# Overview \n## **How it works / What it does**\nThe workflow runs on a schedule or manual trigger and first sets the CSM\u2019s email address. It then uses an AI \u201cData agent\u201d to pull recent customer signals from multiple sources: Gmail messages, Slack messages, Pipedrive notes and Zendesk tickets.\nA \u201cSignals agent\u201d compresses each piece of feedback into a concise, neutral summary, which is then grouped by topic via a \u201cClustering agent\u201d. Each cluster gets a label, count and examples.\nFinally, an \u201cAction agent\u201d routes clusters based on their label:\n- Create Zendesk tickets for product/performance issues\n- Post to a dedicated Slack channel for billing / contract topics\n- Create Notion tasks for sales-related feedback\n- Send targeted Gmail messages to the CSM for high-risk or engagement-related items\n## **How to set up**\n1. Import the workflow into n8n.\n2. Connect credentials for Gmail, Slack, Pipedrive, Zendesk, Notion and OpenAI.\n3. Adjust the sources of the Data Agent\n3. Update the CSM email in the \u201cSet CSM email\u201d node.\n4. Adjust the prompts as needed.\n5. Enable the schedule trigger for weekly or daily digests.\n\n## **How to customize the workflow**\n- Change the time window or filters (sender, channel, query) for each data source.\n- Edit the clustering and routing prompts to match your own categories and teams.\n- Add new destinations (e.g. Jira, HubSpot) by connecting more tools to the Action agent.\n- Modify thresholds (e.g. minimum count) before a cluster triggers an action.\n- Localize labels and email copy to your team\u2019s language and tone."
      },
      "typeVersion": 1
    },
    {
      "id": "8f809f61-9bde-403e-a54e-6767eb34a5c6",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 336,
        "height": 352,
        "content": "## Action agent\n\nTake action from th input. This is highly customizable"
      },
      "typeVersion": 1
    },
    {
      "id": "4198da79-2ec6-40a0-9742-e49e423b9e51",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        208
      ],
      "parameters": {
        "color": 5,
        "width": 464,
        "height": 352,
        "content": "## Data agent sources"
      },
      "typeVersion": 1
    },
    {
      "id": "b5ac42ad-abdb-461a-8556-b3bcb8782ee5",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        192
      ],
      "parameters": {
        "color": 5,
        "width": 464,
        "height": 352,
        "content": "## Output messages"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "LLM": {
      "ai_languageModel": [
        [
          {
            "node": "Signals agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Clustering agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Action agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Data agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Testing": {
      "main": [
        [
          {
            "node": "Set  CSM email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Data agent": {
      "main": [
        [
          {
            "node": "Signals agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Signals agent": {
      "main": [
        [
          {
            "node": "Clustering agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "Data agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Set  CSM email": {
      "main": [
        [
          {
            "node": "Data agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clustering agent": {
      "main": [
        [
          {
            "node": "Action agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set  CSM email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message in Gmail": {
      "ai_tool": [
        [
          {
            "node": "Action agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Send a message in Slack": {
      "ai_tool": [
        [
          {
            "node": "Action agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser1": {
      "ai_outputParser": [
        [
          {
            "node": "Signals agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser2": {
      "ai_outputParser": [
        [
          {
            "node": "Clustering agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Create a ticket in Zendesk": {
      "ai_tool": [
        [
          {
            "node": "Action agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get many messages in Gmail": {
      "ai_tool": [
        [
          {
            "node": "Data agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get many notes in Pipedrive": {
      "ai_tool": [
        [
          {
            "node": "Data agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Search for messages in Slack": {
      "ai_tool": [
        [
          {
            "node": "Data agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Create a database page in Notion": {
      "ai_tool": [
        [
          {
            "node": "Action agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    }
  }
}