8
n8n 中文网amn8n.com

使用 Gemini AI 进行 X (Twitter) 品牌情感分析及 Slack 提醒

高级

这是一个自动化工作流,包含 42 个节点。主要使用 If, Set, Code, Wait, Limit 等节点。 使用 Gemini AI 进行 X (Twitter) 品牌情感分析及 Slack 提醒

前置要求
  • Slack Bot Token 或 Webhook URL
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
  • Google Gemini API Key

分类

-
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "12b5738dbe70639f3b7d069a122c5f581ca4347fcd62ddef39ad5c33b40e7e5e",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "59dc116b-2c89-4dd0-a65d-707c9c19a7d0",
      "name": "代码",
      "type": "n8n-nodes-base.code",
      "position": [
        656,
        -1104
      ],
      "parameters": {
        "jsCode": "// Get the input data from the first item\nconst inputData = items[0].json;\n\n// This will hold our final list of individual items\nconst outputItems = [];\n\nconst nextCursor = inputData.next_cursor;\n\n// Loop through each tweet in the 'tweets' array from the input\nfor (const tweet of inputData.tweets) {\n  // 1. Create the clean object for a single tweet\n  const cleanTweet = {\n    id:tweet.id,\n    text: tweet.text,\n    url: tweet.url,\n    authorUsername: tweet.author.userName,\n    authorName: tweet.author.name,\n    createdAt: tweet.createdAt,\n    likeCount: tweet.likeCount,\n    retweetCount: tweet.retweetCount,\n    replyCount: tweet.replyCount,\n    quoteCount: tweet.quoteCount,\n    viewCount: tweet.viewCount,\n    isReply: tweet.isReply,\n    nextCursor: nextCursor \n  };\n\n  if (tweet.isReply) {\n    cleanTweet.inReplyToUsername = tweet.inReplyToUsername;\n    cleanTweet.inReplyToId = tweet.inReplyToId;\n  }\n\n  // 2. Wrap this single tweet object in the required N8N item structure\n  const n8nItem = {\n    json: cleanTweet\n  };\n\n  // 3. Add this new item to our output list\n  outputItems.push(n8nItem);\n}\n\n// Return the array of individual items\nreturn outputItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "4a4011b2-34e4-460d-aeaa-16f7d268387e",
      "name": "在表格中追加行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        880,
        -1104
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $json.url }}",
            "Date": "={{ $json.createdAt }}",
            "Likes": "={{ $json.likeCount }}",
            "Views": "={{ $json.viewCount }}",
            "Quotes": "={{ $json.quoteCount }}",
            "Content": "={{ $json.text }}",
            "Replies": "={{ $json.replyCount }}",
            "isreply": "={{ $json.isReply }}",
            "Retweets": "={{ $json.retweetCount }}",
            "Tweet_ID": "={{ $json.id }}",
            "Author_Name": "={{ $json.authorName }}",
            "next_cursor": "={{ $json.nextCursor }}",
            "Author_Username": "={{ $json.authorUsername }}"
          },
          "schema": [
            {
              "id": "Tweet_ID",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Tweet_ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Content",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Content",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Author_Username",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Author_Username",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Author_Name",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Author_Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Likes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Likes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Views",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Views",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Retweets",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Retweets",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "next_cursor",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "next_cursor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Replies",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Replies",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Quotes",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Quotes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "isreply",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "isreply",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {
          "useAppend": true
        },
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit?usp=drivesdk",
          "cachedResultName": "Tweet Data"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "6q55WdTedKPZERoF",
          "name": "Google Sheets account 3"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "86afb72d-92d7-460c-b9c0-5d96674c7931",
      "name": "计数",
      "type": "n8n-nodes-base.set",
      "position": [
        -240,
        -1040
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "75e9cf42-928f-4dc2-a354-7b1edd7dfebb",
              "name": "count",
              "type": "number",
              "value": 1
            },
            {
              "id": "866e2004-3995-4431-b373-ac8b3b93c147",
              "name": "query",
              "type": "string",
              "value": "emergentlabs"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "ae1ff19a-ff35-4cba-9269-1eeff32763ca",
      "name": "计数器",
      "type": "n8n-nodes-base.set",
      "position": [
        -16,
        -1040
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f8c5768f-f465-42ca-b990-0f687ccc7805",
              "name": "counter",
              "type": "number",
              "value": "={{ $json.count }}"
            },
            {
              "id": "2290eb4e-938c-4b66-aefd-1b88a37f5f00",
              "name": "cursor",
              "type": "string",
              "value": "={{ $json['next cursor'] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f0abc5af-dddc-48df-b916-0b7d79835171",
      "name": "条件判断",
      "type": "n8n-nodes-base.if",
      "position": [
        1360,
        -1120
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e80112e6-c902-4185-af64-8d706550886c",
              "operator": {
                "type": "number",
                "operation": "equals"
              },
              "leftValue": "={{ $('counter').item.json.counter }}",
              "rightValue": 1
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "38daa357-3e8f-46a5-8256-37717205b53d",
      "name": "限制",
      "type": "n8n-nodes-base.limit",
      "position": [
        256,
        -896
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "91a1fc06-52d9-4aef-af97-151199bded57",
      "name": "设置递增",
      "type": "n8n-nodes-base.set",
      "position": [
        480,
        -896
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "f2a3a921-640f-42b7-b455-4110cfc76f6e",
              "name": "counter",
              "type": "string",
              "value": "={{ $('counter').item.json.counter }}"
            },
            {
              "id": "8cad4530-b5b8-4a6f-b901-926f432b0ff3",
              "name": "cursor",
              "type": "string",
              "value": "={{ $('Tweet Scraper').item.json.next_cursor }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "306f0c25-2e3a-4d2a-8d6a-4c50f3873ecf",
      "name": "代码1",
      "type": "n8n-nodes-base.code",
      "position": [
        704,
        -896
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nreturn items.map(item => {\n  // Default to 1 if no counter exists\n  let newCount = 1;\n\n  // 1. Correctly check if the counter EXISTS\n  if (item.json && item.json.counter != null) {\n    // 2. Convert the counter text to a number before adding\n    newCount = parseInt(item.json.counter) + 1;\n  }\n\n  // Make sure the json object exists\n  if (!item.json) {\n    item.json = {};\n  }\n\n  // Add the new, calculated count to the item\n  item.json.count = newCount;\n\n  // 3. Return the single MODIFIED item, not the whole list\n  return item;\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "639373f6-2282-49c6-bf3c-fe2fc14baf9b",
      "name": "设置计数和游标",
      "type": "n8n-nodes-base.set",
      "position": [
        1152,
        -848
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "42e55567-d8e4-4ee6-9649-a1299c09c2d3",
              "name": "count",
              "type": "string",
              "value": "={{ $json.count }}"
            },
            {
              "id": "c654e218-d1f6-49ef-b401-fb81ef428bbf",
              "name": "cursor",
              "type": "string",
              "value": "={{ $json.cursor }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "143ba536-5062-4f1f-8930-8a3c1b1d0ac7",
      "name": "等待",
      "type": "n8n-nodes-base.wait",
      "position": [
        208,
        -1104
      ],
      "webhookId": "792f7689-0419-41a5-9ccd-1bdd83002e48",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "bcb717ef-5bd5-444b-8aa3-4921774b109a",
      "name": "Google Calendar MCP",
      "type": "n8n-nodes-base.switch",
      "position": [
        -272,
        -448
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "4ed77836-9697-4a95-aa7a-ffbe4790f57b",
                    "operator": {
                      "type": "string",
                      "operation": "notExists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.Content }}",
                    "rightValue": ""
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "eda67442-2198-4692-bbdb-8db08dbf576f",
      "name": "Google Gemini 聊天模型",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        32,
        -304
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "sFPucaeaikoDAevM",
          "name": "Google Gemini(PaLM) Api account 3"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "e441a2b2-7abf-4c1f-a8d6-9a910474d85b",
      "name": "从数据库获取推文",
      "type": "n8n-nodes-base.googleSheetsTool",
      "position": [
        448,
        -320
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit?usp=drivesdk",
          "cachedResultName": "Tweet Data"
        },
        "descriptionType": "manual",
        "toolDescription": "Use this tool to get all recent tweets mentioning our brand from the Google Sheets database. It returns a complete list of tweets with details like content, author, likes, and retweets."
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "6q55WdTedKPZERoF",
          "name": "Google Sheets account 3"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3edca455-922f-4956-8f45-6a47fd8024d2",
      "name": "在 sheet1 中追加行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1136,
        -480
      ],
      "parameters": {
        "columns": {
          "value": {
            "summary": "={{ $json.summary }}",
            "tweetId": "={{ $json.tweetID }}",
            "urgency": "={{ $json.urgency }}",
            "keyTopic": "={{ $json.keyTopic }}",
            "sentiment": "={{ $json.sentiment }}",
            "action taken ": "Notmarked",
            "date_analyzed": "={{ $now }}"
          },
          "schema": [
            {
              "id": "tweetId",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "tweetId",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sentiment",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sentiment",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "keyTopic",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "keyTopic",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "urgency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "urgency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "summary",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "summary",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date_analyzed",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "date_analyzed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "action taken ",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "action taken ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 454621199,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit#gid=454621199",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit?usp=drivesdk",
          "cachedResultName": "Tweet Data"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "6q55WdTedKPZERoF",
          "name": "Google Sheets account 3"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "a9435786-bbe9-4f10-871c-97d1ccd314a0",
      "name": "聚合",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1728,
        -688
      ],
      "parameters": {
        "options": {},
        "fieldsToAggregate": {
          "fieldToAggregate": [
            {
              "renameField": true,
              "outputFieldName": "final",
              "fieldToAggregate": "Content"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cd92a7ce-d58d-4291-b128-d67373128b2b",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1184,
        -1120
      ],
      "parameters": {
        "width": 640,
        "height": 320,
        "content": "# 🎯 收集器与分析器工作流"
      },
      "typeVersion": 1
    },
    {
      "id": "b41a6ef6-be6b-49a7-acd8-d335d07796d1",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        -1296
      ],
      "parameters": {
        "width": 624,
        "height": 544,
        "content": "# 🚀 启动引擎"
      },
      "typeVersion": 1
    },
    {
      "id": "5aeb7918-f3cd-4796-956d-b390ba82bca5",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -1328
      ],
      "parameters": {
        "color": 5,
        "width": 1856,
        "height": 752,
        "content": "# 🐦 推文收集器(循环)"
      },
      "typeVersion": 1
    },
    {
      "id": "2fdc6db0-a947-42bf-ae04-f4869c7fd224",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -736,
        -688
      ],
      "parameters": {
        "color": 4,
        "width": 352,
        "height": 480,
        "content": "# 🤔 守门员"
      },
      "typeVersion": 1
    },
    {
      "id": "9277459d-8348-41a2-87fe-1c2fc3ca9bf8",
      "name": "便签说明4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -160
      ],
      "parameters": {
        "color": 4,
        "width": 800,
        "height": 352,
        "content": "# 🧠 AI 分析师"
      },
      "typeVersion": 1
    },
    {
      "id": "5a9c2c81-2b56-4f42-b606-0dff90cb5242",
      "name": "翻译器",
      "type": "n8n-nodes-base.code",
      "position": [
        752,
        -480
      ],
      "parameters": {
        "jsCode": "// Get the raw text output and remove any leading/trailing whitespace\nconst rawOutput = $input.first().json.output.trim();\nconst outputItems = [];\n\n// 1. Split the entire text into individual analysis blocks using \"---\"\nconst analyses = rawOutput.split('\\n---\\n');\n\n// 2. Loop through each text block\nfor (const chunk of analyses) {\n  // Skip any empty blocks that might result from the split\n  if (chunk.trim() === '') continue;\n\n  const lines = chunk.trim().split('\\n');\n  const cleanAnalysis = {};\n\n  // 3. Loop through each line (e.g., \"Sentiment:: Positive\")\n  for (const line of lines) {\n    const parts = line.split('::');\n    if (parts.length === 2) {\n      // This part cleans up the key, e.g., \"Key Topic\" becomes \"keyTopic\"\n      let key = parts[0].trim();\n      key = key.charAt(0).toLowerCase() + key.slice(1).replace(/\\s+(\\w)/g, (match, letter) => letter.toUpperCase());\n      \n      const value = parts[1].trim();\n      cleanAnalysis[key] = value;\n    }\n  }\n\n  // 4. If we successfully built an object, add it to the output\n  if (Object.keys(cleanAnalysis).length > 0) {\n    outputItems.push({ json: cleanAnalysis });\n  }\n}\n\nreturn outputItems;"
      },
      "typeVersion": 2
    },
    {
      "id": "4c9bf29e-084e-47d1-8e69-c22b3bc34876",
      "name": "推文抓取器",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        432,
        -1104
      ],
      "parameters": {
        "url": "https://api.twitterapi.io/twitter/tweet/advanced_search",
        "options": {
          "batching": {
            "batch": {
              "batchSize": 1,
              "batchInterval": 2000
            }
          },
          "pagination": {}
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "query",
              "value": "={{ $('Count').item.json.query }}"
            },
            {
              "name": " queryType",
              "value": "Latest"
            },
            {
              "name": "cursor",
              "value": "={{ $json.cursor }}"
            }
          ]
        }
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "wJgzPVfBYohOim1J",
          "name": "twitter api io"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "a2679e6f-eb6f-4e44-ac7f-a3f550a95976",
      "name": "便签说明5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        640,
        -320
      ],
      "parameters": {
        "width": 320,
        "height": 512,
        "content": "# 🧹 翻译器"
      },
      "typeVersion": 1
    },
    {
      "id": "5c4fe7a8-3747-4489-8829-0d91b15919ce",
      "name": "便签 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        -336
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 720,
        "content": "# 💾 系统内存"
      },
      "typeVersion": 1
    },
    {
      "id": "ec4bf437-8fdb-468f-abda-06f98fc6d37c",
      "name": "定时触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -432,
        -1008
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "331ce67e-1830-4cc6-82c0-7e5ea2ccad26",
      "name": "AI 分析师",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        192,
        -480
      ],
      "parameters": {
        "text": "=For each distinct post, identify the following: 1. **Sentiment:** Is it Positive, Negative, or Neutral/Question? 2. **Key Topic:** What is the main subject (e.g., \"Product Quality,\" \"Customer Service,\" \"App Bug,\" \"Sales Inquiry\")? 3. **Urgency:** Is this something that requires an immediate response (High), a normal response (Medium), or no response (Low)? 4. **Summary:** 5. **Tweet ID::** \n6.Briefly summarize the post in one sentence.\n\n**CRITICAL FORMATTING RULES:**\n1.  Your entire response must ONLY be the extracted data. Do not add any introductory or concluding text like \"Here's the summary...\".\n2.  Format each post's analysis using the exact `Key:: Value` structure shown in the example. Use a double colon `::` with no extra formatting.\n3.  Separate each distinct post analysis with a single line containing only three dashes `---`.\n\n**EXAMPLE OUTPUT:**\n\nTweet ID:: 1234567890\nSentiment:: Positive\nKey Topic:: Product Quality\nUrgency:: Low\nSummary:: The user is praising the new feature and says it works perfectly.\n---\nTweet ID:: 9876543210\nSentiment:: Negative\nKey Topic:: App Bug\nUrgency:: High\nSummary:: The user reports that the app crashes on startup after the latest update.",
        "options": {
          "systemMessage": "You are an expert Social Media Brand Analyst for \"EmergentLabs\". Your goal is to create a strategic summary of recent brand mentions. To do this, you must first use your available tools to fetch the latest tweets from the database."
        },
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "6ecb4d34-0fb5-4467-b298-09ddcc98bc65",
      "name": "Google Gemini聊天模型1",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        976,
        1264
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "id": "sFPucaeaikoDAevM",
          "name": "Google Gemini(PaLM) Api account 3"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3aff36f1-2d9d-4d7a-836c-8c622bc8d67c",
      "name": "获取表格中的行",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        304,
        1024
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "Notmarked",
              "lookupColumn": "action taken "
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 454621199,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit#gid=454621199",
          "cachedResultName": "Sheet2"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1SVkQU85XCFkr7KGvMxG61f9xuSD6qHf9CaSWo43LL3c/edit?usp=drivesdk",
          "cachedResultName": "Tweet Data"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "6q55WdTedKPZERoF",
          "name": "Google Sheets account 3"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "bc97d230-329b-46d0-ba78-525ac0b0f6dc",
      "name": "解析警报",
      "type": "n8n-nodes-base.code",
      "position": [
        1472,
        1104
      ],
      "parameters": {
        "jsCode": "// Get the full text output from the AI\nconst aiOutput = $input.first().json.text;\n\n// Regex to find the JSON code block\nconst jsonRegex = /```json\\n([\\s\\S]*?)```/;\nconst match = aiOutput.match(jsonRegex);\n\n// If we found a JSON block, parse it and return each object as a separate item\nif (match && match[1]) {\n  try {\n    const jsonString = match[1];\n    const actionableTweets = JSON.parse(jsonString);\n\n    if (Array.isArray(actionableTweets)) {\n      // This returns multiple items, one for each urgent tweet\n      return actionableTweets.map(tweet => ({ json: tweet }));\n    }\n  } catch (error) {\n    console.log(\"Failed to parse JSON:\", error);\n    return []; // Return nothing if JSON is broken\n  }\n}\n\n// Return nothing if no JSON block was found\nreturn [];"
      },
      "typeVersion": 2
    },
    {
      "id": "cc2e2d5e-1f82-4cac-a8d8-6b5229ebde78",
      "name": "发送消息",
      "type": "n8n-nodes-base.slack",
      "position": [
        1696,
        912
      ],
      "webhookId": "fd363969-823b-440f-8f1d-429edcb9702f",
      "parameters": {
        "text": "=📈 *Brand Sentry: Daily Strategic Briefing* 📈 *Generated on: {{ new Date().toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' }) }}*  {{ $json.summaryReport }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09GMSQAHUP",
          "cachedResultName": "brand-alerts"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "aTFdliaAoi5NenQp",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "ede3bb3e-34b6-4a8f-b708-068cb54c5a87",
      "name": "发送消息1",
      "type": "n8n-nodes-base.slack",
      "position": [
        1920,
        1104
      ],
      "webhookId": "a50a8bd5-4016-4cb4-9920-3b51735ebc20",
      "parameters": {
        "text": "=🚨 *URGENT ACTION REQUIRED* 🚨  A social media mention has been flagged for immediate attention.  *Urgency:* `{{ $json.urgency }}` *Reason:* {{ $json.reason }}  *Tweet ID:* `{{ $json.tweetId }}` *Direct Link:* https://x.com/user/status/{{ $json.tweetId }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C09HWHG5L8K",
          "cachedResultName": "urgent"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "aTFdliaAoi5NenQp",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "888243e5-3d56-4d5d-9e7b-9135e21282a2",
      "name": "遍历项目",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1696,
        1104
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3
    },
    {
      "id": "0f91c2bf-c478-4c5b-8a7b-96e747347d87",
      "name": "策略师代理",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        944,
        1008
      ],
      "parameters": {
        "text": "=You are a Social Media Insights Expert. Your task is to analyze the provided social media data and generate a two-part report.\n\n**Part 1: The Summary Report**\nBased on all the posts, generate a summary report with these sections:\n1. Overall Sentiment\n2. Key Themes\n3. Positive Testimonials\n4. Most Influential Post\n\n**Part 2: Actionable Items JSON**\nAfter the summary report, you MUST provide a section titled \"--- ACTIONABLE TWEETS JSON ---\" followed by a valid JSON array. This array should contain objects ONLY for the tweets that have an Urgency of \"High\" or \"Medium\".\n\nEach JSON object must have the following keys: \"tweetId\", \"urgency\", \"reason\".\n- \"tweetId\": The ID of the tweet.\n- \"urgency\": The assessed urgency (High or Medium).\n- \"reason\": A brief, one-sentence explanation of why this tweet is actionable (e.g., \"User reports a critical bug,\" \"User is very angry about billing,\" \"User is asking a direct question about documentation.\").\n\nHere is the data:\n{{ $json.preparedText }}\n\n\nExample of the final JSON output format:\n--- ACTIONABLE TWEETS JSON ---\n```json\n[\n  {\n    \"tweetId\": \"1969737770261438710\",\n    \"urgency\": \"High\",\n    \"reason\": \"User is strongly criticizing the product's core functionality, stating it 'SUCKS'.\"\n  },\n  {\n    \"tweetId\": \"1941086912703504401\",\n    \"urgency\": \"Medium\",\n    \"reason\": \"User is asking for more detailed product documentation, which could be a sales opportunity.\"\n  }\n]\n\n",
        "batching": {
          "batchSize": 1
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "4d2ec48f-415f-4fd4-824f-27506b8f0cb7",
      "name": "解析器",
      "type": "n8n-nodes-base.code",
      "position": [
        608,
        1072
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nlet combinedText = \"Here are the recent analyses to summarize:\\n\\n\";\nconst rowsToUpdate = [];\n\n// Loop through every row from the Google Sheet\nfor (const item of items) {\n  const data = item.json;\n  // Add the row number to our list for later\n  rowsToUpdate.push({ rowNumber: item.json.rowNumber });\n  \n  // Create a neat summary for each analysis\n  const entry = `\n---\nTweet ID: ${data.tweetId}\nSentiment: ${data.sentiment}\nKey Topic: ${data.keyTopic}\nUrgency: ${data.urgency}\nSummary: ${data.summary}\n---\n  `;\n  combinedText += entry;\n}\n\n// Return a SINGLE item with all the data we need\nreturn [{\n  json: {\n    preparedText: combinedText, // For the AI\n    rowsToUpdate: rowsToUpdate  // For the update step\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "55265036-18e2-44bb-8427-685219a56eea",
      "name": "摘要",
      "type": "n8n-nodes-base.code",
      "position": [
        1472,
        912
      ],
      "parameters": {
        "jsCode": "// Get the full text output from the AI\nconst aiOutput = $input.first().json.text;\n\n// Define the delimiter that separates the summary from the JSON\nconst summaryDelimiter = \"--- ACTIONABLE TWEETS JSON ---\";\n\n// Find where the summary text ends\nconst summaryEndIndex = aiOutput.indexOf(summaryDelimiter);\n\n// The summary is everything before the delimiter. If delimiter isn't found, use the whole text.\nconst summaryReport = summaryEndIndex !== -1 ? aiOutput.substring(0, summaryEndIndex).trim() : aiOutput.trim();\n\n// Return a single item with just the summary report\nreturn [{ json: { summaryReport: summaryReport } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "65f4b982-4196-4315-9b8f-caf5a2c03388",
      "name": "## 为什么选择 4o 模型?👆",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -512,
        896
      ],
      "parameters": {
        "width": 512,
        "height": 320,
        "content": "# 🎯 策略师工作流"
      },
      "typeVersion": 1
    },
    {
      "id": "15bd2e16-77cd-499a-9ca1-40b732a14a56",
      "name": "便签 9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        576
      ],
      "parameters": {
        "width": 480,
        "height": 880,
        "content": "# 📊 1. 读取\"待办\"列表"
      },
      "typeVersion": 1
    },
    {
      "id": "b2f0cd05-fe05-486a-a7a6-604369ab4091",
      "name": "便签10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        528,
        592
      ],
      "parameters": {
        "width": 288,
        "height": 864,
        "content": "# 📚 2. 汇编简报书"
      },
      "typeVersion": 1
    },
    {
      "id": "7b62b892-025c-4d71-9673-5a1ab509fb09",
      "name": "便签11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        560
      ],
      "parameters": {
        "color": 4,
        "width": 416,
        "height": 896,
        "content": "# 👑 3. 策略师 AI"
      },
      "typeVersion": 1
    },
    {
      "id": "71eb9e89-8314-4324-9b43-6441e9711b55",
      "name": "便签12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        560
      ],
      "parameters": {
        "color": 5,
        "width": 656,
        "height": 496,
        "content": "# 📜 4a. 摘要报告路径"
      },
      "typeVersion": 1
    },
    {
      "id": "153bf685-006e-416c-aaf9-40b89625b2c1",
      "name": "便签13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        1072
      ],
      "parameters": {
        "color": 3,
        "width": 816,
        "height": 496,
        "content": "# 🚨 4b. 紧急警报路径"
      },
      "typeVersion": 1
    },
    {
      "id": "a2d428b0-4ccd-4f74-a38e-35af8474022a",
      "name": "计划触发器1",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        48,
        1056
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 9
            }
          ]
        }
      },
      "typeVersion": 1.2
    }
  ],
  "pinData": {},
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Limit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Tweet Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code1": {
      "main": [
        [
          {
            "node": "set count and cursor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Count": {
      "main": [
        [
          {
            "node": "counter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit": {
      "main": [
        [
          {
            "node": "set increase",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "AI Analyst",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "parser": {
      "main": [
        [
          {
            "node": "Strategist Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "counter": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "summary": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Analyst": {
      "main": [
        [
          {
            "node": "Translator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Translator": {
      "main": [
        [
          {
            "node": "Append row in sheet1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "parseAlerts": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "set increase": {
      "main": [
        [
          {
            "node": "Code1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Tweet Scraper": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Send a message1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send a message1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Count",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Strategist Agent": {
      "main": [
        [
          {
            "node": "summary",
            "type": "main",
            "index": 0
          },
          {
            "node": "parseAlerts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger1": {
      "main": [
        [
          {
            "node": "Get row(s) in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row(s) in sheet": {
      "main": [
        [
          {
            "node": "parser",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet1": {
      "main": [
        []
      ]
    },
    "set count and cursor": {
      "main": [
        [
          {
            "node": "counter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "getTweetsFromDatabase": {
      "ai_tool": [
        [
          {
            "node": "AI Analyst",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Analyst",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Strategist Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量42
分类-
节点类型17
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

外部链接
在 n8n.io 查看

分享此工作流