{"workflow":{"id":13819,"name":"Monitor ecommerce reviews with MrScraper, GPT-4o-mini, Slack and Notion","views":38,"recentViews":0,"totalViews":38,"createdAt":"2026-03-03T02:43:08.378Z","description":"## Description\n\nThis n8n template gives ecommerce brands a fully automated review intelligence system — running every morning to scrape, analyze, and report on what customers are actually saying across every platform. It uses MrScraper to collect reviews from Tokopedia, Shopee, Lazada, Bukalapak, Amazon, and more, then GPT-4o-mini to extract 15 brand intelligence signals per review including sentiment, emotion, viral risk, competitor mentions, and CS response suggestions.\n\nThe result is a daily Brand Awareness Score (BAS) delivered to Slack, every review archived in Notion, and urgent alerts fired the moment a critical review is detected — before it goes viral.\n\n---\n\n## How It Works\n\n* **Phase 1 – Trigger & Config:** A Schedule Trigger fires daily at 6AM. The workflow reads your product list from Google Sheets — each row is one product SKU across any platform — and loops through them one by one.\n* **Phase 2 – Review URL Discovery:** For each product, the Map Agent crawls the product page and discovers review section URLs or paginated review pages. A smart fallback ensures reviews embedded directly on the product page (common on Tokopedia and Shopee) are still captured even when no separate review URL exists.\n* **Phase 3 – Review Extraction & Filtering:** Each review URL is processed by the General Agent, which extracts the full review text, star rating, reviewer name, date, photo count, helpful votes, verified purchase status, and any existing seller reply. Short reviews under 10 words are skipped — unless the rating is 1 or 2 stars, where even brief negative feedback is treated as a valuable signal. A deduplication hash is generated per review to prevent double-processing on re-runs.\n* **Phase 4 – AI Brand Sentiment Analysis:** Every valid review is sent to GPT-4o-mini with a structured prompt that returns 15 brand intelligence fields: sentiment label and score, emotion tags (frustration, delight, anger, loyalty, etc.), the most impacted product dimension (quality, delivery, packaging, pricing, authenticity), a CX score out of 10, competitor brand mentions, viral risk assessment, urgency level, and a ready-to-use customer service response suggestion.\n* **Phase 5 – Storage, Alerts & Daily Digest:** Reviews flagged as action-required trigger an immediate Slack alert to your `#brand-alerts` channel. Every review is saved to Notion with all 27 metadata fields. At the end of each run, a Daily Brand Health Digest is compiled — including the Brand Awareness Score (BAS) out of 100, sentiment breakdown, top praises and complaints, emotion trends, competitor mentions, viral risk list, and action items — then posted to your `#brand-monitoring` Slack channel.\n\n---\n\n## How to Set Up\n\n1. **Prepare your Google Sheet** with these columns: `Platform`, `Product_URL`, `Brand_Name`, `SKU_Code`, `Category`, `Active` (Y/N). Add one row per product SKU you want to monitor.\n\n2. **Create 2 scrapers in your MrScraper account:**\n   * Review List Scraper (Map Agent) — crawls product pages and discovers review URLs\n   * Review Detail Scraper (General Agent) — extracts review_text, rating, reviewer_name, review_date, photo_count, helpful_votes, verified_purchase, seller_reply\n   * Copy the `scraperId` for each and paste into the corresponding n8n nodes.\n\n3. **Enable AI Scraper API access** in your MrScraper account settings.\n\n4. **Add your credentials in n8n:**\n   * MrScraper API key\n   * OpenAI API key\n   * Slack OAuth\n   * Notion OAuth\n   * Google Sheets OAuth2\n\n5. **Configure your Notion database** with all 27 properties listed in the setup note inside the workflow (Title, SKU Code, Platform, Sentiment, Sentiment Score, Emotion Tags, CX Score, Viral Risk, Action Required, and more).\n\n6. **Update config values** inside the `Filter & Enrich Review Data` node:\n   * `slackChannel` (e.g. `#brand-monitoring`)\n   * `slackAlertChannel` (e.g. `#brand-alerts`)\n   * `notionDatabaseId` (from your Notion database URL)\n   * `competitorKeywords` (comma-separated competitor brand names to detect)\n   * `alertThreshold` (default: 2.5 stars)\n\n7. **Adjust the Map Agent node** include/exclude patterns for your target platform (e.g. `/review`, `/ulasan` for Indonesian platforms, paginated review paths for Amazon).\n\n8. **Set your trigger time** in the Schedule node to match your timezone (default: every 24 hours).\n\n---\n\n## Requirements\n\n* **MrScraper** account with API access enabled\n* **OpenAI** account (GPT-4o-mini used by default)\n* **Slack** workspace with OAuth connected (two channels recommended: one for digest, one for urgent alerts)\n* **Notion** workspace with a database configured and OAuth connected\n* **Google Sheets** (OAuth2 connected) for your product SKU list\n\n---\n\n## Good to Know\n\n* The **Brand Awareness Score (BAS)** is calculated using a weighted formula combining average star rating (30%), positive review rate (25%), sentiment score (20%), brand loyalty signals (10%), and a viral risk penalty (up to -10 points). It gives you a single number to track brand health over time.\n* GPT-4o-mini processes each review for approximately $0.0001 — making it extremely cost-effective even for catalogs with hundreds of SKUs.\n* Short 1–2 star reviews are never skipped, even if they contain only a few words — a single-word complaint like \"rusak\" (broken) or \"fake\" carries strong signal and is always analyzed.\n* The workflow has two independent Slack outputs: an instant urgent alert fires the moment a critical review is detected, while the Daily Digest posts a full brand health report after all reviews for the day have been processed.\n* Reviews from platforms where feedback is embedded on the product page (no separate review URL) are handled automatically via the smart URL fallback in the Extract Review URLs node.\n\n---\n\n## Customising This Workflow\n\n* **Multi-brand monitoring:** Duplicate the workflow and point it at a different Google Sheet to run separate brand intelligence pipelines for different product lines or client brands.\n* **Auto CS ticket creation:** Add a Jira, Asana, or Trello node after the Notion save step to automatically create customer service tickets for every critical or high-urgency review.\n* **Email reporting:** Insert a Gmail node after the Slack Daily Digest to also deliver the Brand Health Report as a formatted email to your marketing or brand team each morning.\n* **Visual dashboards:** Connect your Notion database to Google Looker Studio or Metabase to build BAS trend charts, sentiment heatmaps by platform, and weekly brand health dashboards.\n* **Competitor switch alerts:** Extend the competitor keyword list and add a dedicated Slack message branch specifically for reviews where a competitor switch is mentioned — a high-priority signal for retention teams.","workflow":{"id":"XwxAhfsVlx68TL5A","meta":{"instanceId":"ff80ff7708e50014ab81fa837934b47761ca37bb76e027238bca430a67bf5090"},"name":"BrandPulse 360° — Ecommerce Review Intelligence","tags":[],"nodes":[{"id":"afa13857-44a7-48ba-9ffa-b45edfd45899","name":"Schedule Trigger (Daily 6AM)","type":"n8n-nodes-base.scheduleTrigger","position":[848,208],"parameters":{"rule":{"interval":[{"field":"hours","hoursInterval":24}]}},"typeVersion":1.2},{"id":"1a85bcd1-b359-4147-a183-72d218b78a01","name":"Loop Each Product SKU","type":"n8n-nodes-base.splitInBatches","position":[1296,208],"parameters":{"options":{"reset":false}},"typeVersion":3},{"id":"83cb9fda-7141-41f4-8835-d842b2c801db","name":"MrScraper - Discover Review URLs","type":"n8n-nodes-mrscraper.mrscraper","position":[1520,80],"parameters":{"url":"={{ $json.Product_URL }}","operation":"mapAgent","scraperId":"=// Input Your Review List Scraper ID from MrScraper (required)","requestOptions":{},"excludePatterns":"// e.g. /seller, /similar, /ads","includePatterns":"// e.g. /review, /ulasan, #review-section"},"credentials":{"mrscraperApi":{"id":"l5klfCQPVgZ8liKu","name":"Walmart Kiss"}},"retryOnFail":true,"typeVersion":1,"waitBetweenTries":3000},{"id":"508a804b-9095-40a7-89cd-e30ff6fc62a3","name":"Loop Each Review","type":"n8n-nodes-base.splitInBatches","position":[1968,192],"parameters":{"options":{"reset":false}},"typeVersion":3},{"id":"92a44af9-d943-4f5f-a546-f8a6cb190dde","name":"MrScraper - Extract Review Content","type":"n8n-nodes-mrscraper.mrscraper","position":[2224,80],"parameters":{"url":"={{ $json.url }}","operation":"generalAgent","scraperId":"=// Input Your Review Detail Scraper ID from MrScraper (required)","requestOptions":{}},"credentials":{"mrscraperApi":{"id":"l5klfCQPVgZ8liKu","name":"Walmart Kiss"}},"retryOnFail":true,"typeVersion":1,"continueOnFail":true},{"id":"97628393-3576-4214-9428-d79886c034e3","name":"Filter & Enrich Review Data","type":"n8n-nodes-base.code","position":[2448,80],"parameters":{"jsCode":"// ─────────────────────────────────────────────────────────────\n// FILTER & ENRICH ECOMMERCE REVIEW DATA\n// Handles Tokopedia, Shopee, Lazada, Bukalapak, Amazon\n// ─────────────────────────────────────────────────────────────\nconst item = $input.item.json;\n\n// --- 1. Resolve nested data from MrScraper response ---\nlet rootData =\n  item?.data?.data?.data ||\n  item?.data?.data ||\n  item?.data ||\n  {};\n\n// --- 2. Extract review fields (map common field names across platforms) ---\nconst reviewText =\n  rootData.review_text ||\n  rootData.review ||\n  rootData.content ||\n  rootData.ulasan ||\n  rootData.text ||\n  rootData.body ||\n  '';\n\nconst rating =\n  parseFloat(rootData.rating ||\n  rootData.star ||\n  rootData.stars ||\n  rootData.score || 0);\n\nconst reviewerName =\n  rootData.reviewer ||\n  rootData.reviewer_name ||\n  rootData.user ||\n  rootData.username ||\n  'Anonymous';\n\nconst reviewDate =\n  rootData.review_date ||\n  rootData.date ||\n  rootData.created_at ||\n  rootData.published_at ||\n  new Date().toISOString();\n\nconst photoCount =\n  parseInt(rootData.photo_count ||\n  rootData.images_count ||\n  rootData.photos || 0);\n\nconst helpfulVotes =\n  parseInt(rootData.helpful ||\n  rootData.helpful_votes ||\n  rootData.likes || 0);\n\nconst isVerified =\n  rootData.verified_purchase ||\n  rootData.verified ||\n  false;\n\nconst sellerReply =\n  rootData.seller_reply ||\n  rootData.shop_reply ||\n  rootData.response ||\n  '';\n\n// --- 3. Word count filter ---\nconst wordCount =\n  reviewText.split(/\\s+/).filter(w => w.length > 0).length || 0;\n\n// Skip reviews under 10 words UNLESS rating is very low (1-2 stars = still valuable signal)\nif (wordCount < 10 && rating > 2) {\n  return [{\n    json: {\n      skip: true,\n      reason: 'Review too short and not a critical rating',\n      rating,\n      wordCount\n    }\n  }];\n}\n\n// --- 4. Deduplication hash (reviewer + date + first 50 chars) ---\nconst hashBase = `${reviewerName}|${reviewDate}|${reviewText.slice(0, 50)}`;\nconst reviewHash = hashBase.split('').reduce((acc, char) => {\n  return ((acc << 5) - acc + char.charCodeAt(0)) | 0;\n}, 0).toString(36);\n\n// --- 5. Pre-flag viral risk (before AI — fast check) ---\nconst viralRiskPreflag =\n  photoCount >= 3 ||\n  helpfulVotes >= 10 ||\n  rating === 1 ||\n  reviewText.length > 500;\n\n// --- 6. Infer sentiment from rating alone for text-less reviews ---\nlet ratingOnlySentiment = null;\nif (wordCount < 10) {\n  if (rating <= 2) ratingOnlySentiment = 'negative';\n  else if (rating === 3) ratingOnlySentiment = 'neutral';\n  else ratingOnlySentiment = 'positive';\n}\n\n// --- 7. Return enriched review ---\nreturn [{\n  json: {\n    skip: false,\n    // Review core data\n    reviewText: reviewText.slice(0, 4000), // Trim to max 4000 chars for AI\n    rating,\n    reviewerName,\n    reviewDate,\n    photoCount,\n    helpfulVotes,\n    isVerified,\n    sellerReply,\n    wordCount,\n    reviewHash,\n    viralRiskPreflag,\n    ratingOnlySentiment,\n    // Product context (passed from Google Sheets)\n    productName: $('Get Target Product List').item.json.Product_Name || rootData.product_name || '',\n    skuCode: $('Get Target Product List').item.json.SKU_Code || '',\n    platform: $('Get Target Product List').item.json.Platform || rootData.platform || '',\n    category: $('Get Target Product List').item.json.Category || '',\n    productUrl: $('Get Target Product List').item.json.Product_URL || '',\n    brandName: $('Get Target Product List').item.json.Brand_Name || 'YourBrand',\n    // Workflow config\n    slackChannel: '// Input your Slack channel name e.g. #brand-monitoring',\n    slackAlertChannel: '// Input your Slack alert channel name e.g. #brand-alerts',\n    notionDatabaseId: '// Input your Notion Database ID',\n    competitorKeywords: 'competitor1, competitor2, competitor3',\n    alertThreshold: 2.5,\n    runDate: new Date().toISOString()\n  }\n}];"},"typeVersion":2},{"id":"ecb54aac-43ae-4f40-896d-f6de93f19d45","name":"Keep Only Valid Reviews","type":"n8n-nodes-base.if","position":[2640,80],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"filter-001","operator":{"type":"boolean","operation":"false","singleValue":true},"leftValue":"={{ $json.skip }}","rightValue":"100"}]}},"typeVersion":2.3},{"id":"57e08124-c7f1-4c3f-9d82-1a53ecd9fc74","name":"OpenAI Chat Model","type":"@n8n/n8n-nodes-langchain.lmChatOpenAi","position":[2880,224],"parameters":{"model":{"__rl":true,"mode":"list","value":"gpt-4o-mini","cachedResultName":"gpt-4o-mini"},"options":{},"builtInTools":{}},"credentials":{"openAiApi":{"id":"zIW6DcoL8jhB82nz","name":"OpenAi account 2"}},"typeVersion":1.3},{"id":"b269bc7f-f1cb-4c34-8b12-ff5a011b994d","name":"Brand Sentiment AI Agent","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[2864,64],"parameters":{"text":"=Analyze the following ecommerce product review for the brand \"{{ $json.brandName }}\".\n\nProduct: {{ $json.productName }}\nSKU: {{ $json.skuCode }}\nPlatform: {{ $json.platform }}\nCategory: {{ $json.category }}\nStar Rating: {{ $json.rating }} / 5\nReviewer: {{ $json.reviewerName }}\nReview Date: {{ $json.reviewDate }}\nVerified Purchase: {{ $json.isVerified }}\nPhoto Count: {{ $json.photoCount }}\nHelpful Votes: {{ $json.helpfulVotes }}\nSeller Reply Exists: {{ $json.sellerReply ? 'Yes' : 'No' }}\n\nReview Text:\n{{ $json.reviewText }}\n\nKnown Competitors to detect: {{ $json.competitorKeywords }}\n\nReturn ONLY this exact JSON structure, no markdown, no explanation:\n\n{\n  \"sentiment_label\": \"positive | neutral | negative\",\n  \"sentiment_score\": number between -1.0 and 1.0,\n  \"emotion_tags\": [\"array of emotions: frustration | delight | anger | loyalty | confusion | disappointment | trust | excitement | skepticism\"],\n  \"product_dimension\": \"quality | delivery | packaging | pricing | authenticity | customer_service | after_sales | overall\",\n  \"key_phrase\": \"most impactful sentence from the review (max 20 words)\",\n  \"summary\": \"2 sentence summary of the review in English\",\n  \"competitor_mentions\": [\"array of competitor brand names mentioned, or empty array []\"],\n  \"urgency_level\": \"low | medium | high | critical\",\n  \"response_suggestion\": \"suggested CS reply to this review (max 40 words)\",\n  \"viral_risk\": true or false,\n  \"viral_reason\": \"why this review could go viral, or empty string\",\n  \"brand_loyalty_signal\": true or false,\n  \"awareness_source\": \"first_time | repeat | referral_mention | unknown\",\n  \"action_required\": true or false,\n  \"action_reason\": \"why action is needed, or empty string\",\n  \"cx_score\": number between 1 and 10\n}","messages":{"messageValues":[{"message":"You are an expert brand intelligence engine specializing in ecommerce review analysis.\n\nYou MUST return ONLY valid JSON. No markdown. No explanations. No backticks. No extra text.\nAlways return all fields. Never return null.\n\nSentiment rules:\n- positive → praise, satisfaction, recommendation, repeat purchase intent, product quality compliment\n- negative → complaint, defect, scam accusation, damaged product, bad service, misleading description\n- neutral → factual description, mixed feedback, neither clearly positive nor negative\n\nSentiment score rules:\n- Range: -1.0 (strongly negative) to +1.0 (strongly positive)\n- 1 star → typically -0.7 to -1.0\n- 2 stars → typically -0.3 to -0.7\n- 3 stars → typically -0.1 to +0.1\n- 4 stars → typically +0.3 to +0.6\n- 5 stars → typically +0.6 to +1.0\n\nUrgency rules:\n- critical → rating 1-2 stars + scam/fake/tipu claim, OR viral risk true, OR competitor switch mentioned\n- high → rating 1-2 stars OR strong complaint about safety/defect/health\n- medium → rating 3 stars with complaints OR delivery issue\n- low → positive or neutral reviews\n\nViral risk = true if:\n- photo count >= 3 in the metadata\n- review text length > 300 characters with strong emotion\n- contains words like 'viral', 'share', 'warning', 'jangan beli', 'scam', 'tipu', 'boycott'\n- helpful votes >= 10\n\nBrand loyalty signal = true if:\n- reviewer mentions repeat purchase, been using for years, always buys this brand, or recommends to others"}]},"promptType":"define"},"typeVersion":1.5},{"id":"09945704-cfd1-458f-90b0-904e00fbe30a","name":"Parse AI Response & Format Output","type":"n8n-nodes-base.code","position":[3216,64],"parameters":{"jsCode":"// ─────────────────────────────────────────────────────────────\n// PARSE AI RESPONSE & FORMAT ALL OUTPUT FIELDS\n// ─────────────────────────────────────────────────────────────\nconst item = $input.item.json;\nconst reviewMeta = $('Keep Only Valid Reviews').item.json;\n\nlet analysis = {};\ntry {\n  const raw = item.text || item.response || item.output || '';\n  const cleaned = raw.replace(/```json|```/g, '').trim();\n  analysis = JSON.parse(cleaned);\n} catch (e) {\n  // Fallback: infer from star rating if AI parse fails\n  const r = reviewMeta.rating || 3;\n  analysis = {\n    sentiment_label: r >= 4 ? 'positive' : r === 3 ? 'neutral' : 'negative',\n    sentiment_score: r >= 4 ? 0.6 : r === 3 ? 0.0 : -0.6,\n    emotion_tags: [],\n    product_dimension: 'overall',\n    key_phrase: reviewMeta.reviewText?.slice(0, 80) || '',\n    summary: 'AI parse failed — sentiment inferred from star rating.',\n    competitor_mentions: [],\n    urgency_level: r <= 2 ? 'high' : 'low',\n    response_suggestion: 'Thank you for your feedback. We will look into this.',\n    viral_risk: false,\n    viral_reason: '',\n    brand_loyalty_signal: false,\n    awareness_source: 'unknown',\n    action_required: r <= 2,\n    action_reason: r <= 2 ? 'Low star rating requires CS follow-up' : '',\n    cx_score: r * 2\n  };\n}\n\n// Sanitize types\nconst sentimentLabel = String(analysis.sentiment_label || 'neutral').toLowerCase();\nconst sentimentScore = parseFloat(analysis.sentiment_score) || 0;\nconst actionRequired = analysis.action_required === true || analysis.action_required === 'true';\nconst viralRisk = analysis.viral_risk === true || analysis.viral_risk === 'true' || reviewMeta.viralRiskPreflag;\nconst urgencyLevel = String(analysis.urgency_level || 'low').toLowerCase();\n\n// Emoji maps\nconst sentimentEmoji = { positive: '🟢', neutral: '🟡', negative: '🔴' }[sentimentLabel] || '⚪';\nconst urgencyEmoji = { critical: '🚨', high: '⚠️', medium: '🔔', low: 'ℹ️' }[urgencyLevel] || 'ℹ️';\nconst platformEmoji = {\n  tokopedia: '🛍️', shopee: '🟠', lazada: '🔵', bukalapak: '🔴', amazon: '📦'\n}[String(reviewMeta.platform || '').toLowerCase()] || '🛒';\n\n// Star display\nconst starDisplay = '⭐'.repeat(Math.round(reviewMeta.rating || 0));\n\n// Competitor mentions as string\nconst competitorStr = Array.isArray(analysis.competitor_mentions) && analysis.competitor_mentions.length > 0\n  ? analysis.competitor_mentions.join(', ')\n  : 'None';\n\n// Emotion tags as string\nconst emotionStr = Array.isArray(analysis.emotion_tags)\n  ? analysis.emotion_tags.join(', ')\n  : String(analysis.emotion_tags || '');\n\n// Slack urgent message\nconst slackUrgentMessage =\n`${urgencyEmoji} *URGENT BRAND ALERT* — Action Required\n\n${platformEmoji} *Platform:* ${reviewMeta.platform} | ${sentimentEmoji} *Sentiment:* ${sentimentLabel.toUpperCase()} (Score: ${sentimentScore.toFixed(2)})\n*Product:* ${reviewMeta.productName} (${reviewMeta.skuCode})\n*Star Rating:* ${starDisplay} ${reviewMeta.rating}/5\n*Emotion:* ${emotionStr}\n*Product Dimension:* ${analysis.product_dimension || 'overall'}\n\n*Review Excerpt:*\n_\"${reviewMeta.reviewText?.slice(0, 200)}...\"_\n\n*Key Phrase:* \"${analysis.key_phrase || ''}\"\n*Urgency:* ${urgencyLevel.toUpperCase()}\n${viralRisk ? `🔥 *Viral Risk Detected:* ${analysis.viral_reason || 'High engagement signals'}` : ''}\n${competitorStr !== 'None' ? `⚔️ *Competitor Mentioned:* ${competitorStr}` : ''}\n\n*Suggested CS Response:*\n_${analysis.response_suggestion || 'Thank you for your feedback.'}_\n\n*Why action is needed:*\n${analysis.action_reason || ''}\n\n🔗 <${reviewMeta.productUrl}|View Product on ${reviewMeta.platform}>\n_Reviewed: ${reviewMeta.reviewDate} | Processed: ${reviewMeta.runDate}_`;\n\nreturn [{\n  json: {\n    // Review metadata\n    productName: reviewMeta.productName,\n    skuCode: reviewMeta.skuCode,\n    platform: reviewMeta.platform,\n    category: reviewMeta.category,\n    productUrl: reviewMeta.productUrl,\n    brandName: reviewMeta.brandName,\n    reviewerName: reviewMeta.reviewerName,\n    reviewDate: reviewMeta.reviewDate,\n    rating: reviewMeta.rating,\n    starDisplay,\n    photoCount: reviewMeta.photoCount,\n    helpfulVotes: reviewMeta.helpfulVotes,\n    isVerified: reviewMeta.isVerified,\n    sellerReply: reviewMeta.sellerReply,\n    wordCount: reviewMeta.wordCount,\n    reviewHash: reviewMeta.reviewHash,\n    reviewExcerpt: reviewMeta.reviewText?.slice(0, 300) || '',\n    runDate: reviewMeta.runDate,\n    // AI analysis fields\n    sentiment_label: sentimentLabel,\n    sentiment_score: sentimentScore,\n    sentimentEmoji,\n    emotion_tags: emotionStr,\n    product_dimension: analysis.product_dimension || 'overall',\n    key_phrase: analysis.key_phrase || '',\n    summary: analysis.summary || '',\n    competitor_mentions: competitorStr,\n    urgency_level: urgencyLevel,\n    urgencyEmoji,\n    response_suggestion: analysis.response_suggestion || '',\n    viral_risk: viralRisk,\n    viral_reason: analysis.viral_reason || '',\n    brand_loyalty_signal: analysis.brand_loyalty_signal === true,\n    awareness_source: analysis.awareness_source || 'unknown',\n    action_required: actionRequired,\n    action_reason: analysis.action_reason || '',\n    cx_score: parseFloat(analysis.cx_score) || (reviewMeta.rating * 2),\n    // Routing\n    slackChannel: reviewMeta.slackChannel,\n    slackAlertChannel: reviewMeta.slackAlertChannel,\n    notionDatabaseId: reviewMeta.notionDatabaseId,\n    // Formatted messages\n    slackUrgentMessage,\n    platformEmoji\n  }\n}];"},"typeVersion":2},{"id":"7af404e6-441a-4f58-a359-f0450977919d","name":"Needs Urgent Alert?","type":"n8n-nodes-base.if","position":[3440,96],"parameters":{"options":{},"conditions":{"options":{"version":3,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"urgent-001","operator":{"type":"boolean","operation":"true","singleValue":true},"leftValue":"={{ $json.action_required }}"}]}},"typeVersion":2.3},{"id":"5322273d-f6e8-4b30-b298-69d869d8c30a","name":"Slack - Urgent Brand Alert","type":"n8n-nodes-base.slack","position":[3888,48],"webhookId":"ab6451a2-9c25-4c68-a40d-788f3a958de2","parameters":{"text":"={{ $json.slackUrgentMessage }}","select":"channel","channelId":{"__rl":true,"mode":"name","value":"={{ $json.slackAlertChannel }}"},"otherOptions":{"mrkdwn":true}},"typeVersion":2.3},{"id":"8c515320-9a48-4831-807b-b7e135d097e4","name":"Notion - Save Review Analysis","type":"n8n-nodes-base.notion","position":[4048,160],"parameters":{"title":"={{ $json.productName }} — {{ $json.platform }} — {{ $json.rating }}⭐ — {{ $json.reviewDate }}","options":{},"resource":"databasePage","databaseId":{"__rl":true,"mode":"id","value":"={{ $json.notionDatabaseId }}"},"propertiesUi":{"propertyValues":[{"key":"SKU Code"},{"key":"Platform","selectValue":"={{ $json.platform }}"},{"key":"Category"},{"key":"Product URL","urlValue":"={{ $json.productUrl }}"},{"key":"Star Rating","numberValue":"={{ $json.rating }}"},{"key":"Sentiment","selectValue":"={{ $json.sentiment_label }}"},{"key":"Sentiment Score","numberValue":"={{ $json.sentiment_score }}"},{"key":"Emotion Tags"},{"key":"Product Dimension","selectValue":"={{ $json.product_dimension }}"},{"key":"Key Phrase"},{"key":"Summary"},{"key":"CX Score","numberValue":"={{ $json.cx_score }}"},{"key":"Competitor Mentions"},{"key":"Urgency Level","selectValue":"={{ $json.urgency_level }}"},{"key":"Response Suggestion"},{"key":"Viral Risk","checkboxValue":"={{ $json.viral_risk }}"},{"key":"Viral Reason"},{"key":"Brand Loyalty Signal","checkboxValue":"={{ $json.brand_loyalty_signal }}"},{"key":"Awareness Source","selectValue":"={{ $json.awareness_source }}"},{"key":"Action Required","checkboxValue":"={{ $json.action_required }}"},{"key":"Action Reason"},{"key":"Reviewer Name"},{"key":"Verified Purchase","checkboxValue":"={{ $json.isVerified }}"},{"key":"Photo Count","numberValue":"={{ $json.photoCount }}"},{"key":"Helpful Votes","numberValue":"={{ $json.helpfulVotes }}"},{"key":"Review Excerpt"},{"key":"Review Date"},{"key":"Processed At"}]}},"typeVersion":2.2,"continueOnFail":true},{"id":"84eb269e-b442-4944-9313-3c7e6a3e1451","name":"Build Daily Brand Health Digest","type":"n8n-nodes-base.code","position":[3584,192],"parameters":{"jsCode":"// ─────────────────────────────────────────────────────────────\n// BUILD DAILY BRAND HEALTH DIGEST\n// Aggregates all processed reviews into a structured report\n// ─────────────────────────────────────────────────────────────\nconst allItems = $input.all();\n\nif (!allItems || allItems.length === 0) {\n  return [{\n    json: {\n      digestMessage: `📊 *BrandPulse 360° — Daily Brand Health Report*\\n\\nNo reviews were processed today. Check your scraper configuration or product URLs.`,\n      total: 0\n    }\n  }];\n}\n\nconst reviews = allItems.map(i => i.json);\nconst runDate = new Date().toISOString().slice(0, 10);\n\n// ── Sentiment breakdown ──\nconst sentimentCounts = { positive: 0, neutral: 0, negative: 0 };\nfor (const r of reviews) {\n  const s = (r.sentiment_label || 'neutral').toLowerCase();\n  if (sentimentCounts[s] !== undefined) sentimentCounts[s]++;\n}\n\n// ── Average rating & sentiment score ──\nconst avgRating = (reviews.reduce((sum, r) => sum + (parseFloat(r.rating) || 0), 0) / reviews.length).toFixed(2);\nconst avgSentimentScore = (reviews.reduce((sum, r) => sum + (parseFloat(r.sentiment_score) || 0), 0) / reviews.length).toFixed(2);\nconst avgCxScore = (reviews.reduce((sum, r) => sum + (parseFloat(r.cx_score) || 0), 0) / reviews.length).toFixed(1);\n\n// ── Brand Awareness Score (BAS) calculation ──\nconst positiveRate = sentimentCounts.positive / reviews.length;\nconst viralCount = reviews.filter(r => r.viral_risk).length;\nconst loyaltyCount = reviews.filter(r => r.brand_loyalty_signal).length;\nconst actionCount = reviews.filter(r => r.action_required).length;\nconst viralPenalty = Math.min(viralCount * 5, 10); // max -10 pts\nconst BAS = Math.min(100, Math.max(0, Math.round(\n  (parseFloat(avgRating) / 5) * 30 +           // avg rating → max 30pts\n  positiveRate * 25 +                           // % positive → max 25pts\n  parseFloat(avgSentimentScore) * 10 + 10 +    // sentiment score → max 20pts\n  (loyaltyCount / reviews.length) * 10 +       // loyalty signals → max 10pts\n  (5) -                                         // base 5pts for competitor benchmark (placeholder)\n  viralPenalty                                  // viral risk penalty → max -10pts\n)));\n\nconst basEmoji = BAS >= 75 ? '🟢' : BAS >= 50 ? '🟡' : '🔴';\nconst basLabel = BAS >= 75 ? 'Healthy' : BAS >= 50 ? 'Needs Attention' : 'At Risk';\n\n// ── Product dimension breakdown ──\nconst dimensionCounts = {};\nfor (const r of reviews) {\n  const d = r.product_dimension || 'overall';\n  dimensionCounts[d] = (dimensionCounts[d] || 0) + 1;\n}\nconst topDimension = Object.entries(dimensionCounts).sort((a, b) => b[1] - a[1])[0]?.[0] || 'N/A';\n\n// ── Emotion tag frequency ──\nconst emotionFreq = {};\nfor (const r of reviews) {\n  for (const e of (r.emotion_tags || '').split(',').map(t => t.trim()).filter(Boolean)) {\n    emotionFreq[e] = (emotionFreq[e] || 0) + 1;\n  }\n}\nconst topEmotions = Object.entries(emotionFreq).sort((a, b) => b[1] - a[1]).slice(0, 3).map(([e, c]) => `${e} (${c})`).join(', ');\n\n// ── Competitor mentions ──\nconst competitorMap = {};\nfor (const r of reviews) {\n  if (r.competitor_mentions && r.competitor_mentions !== 'None') {\n    for (const c of r.competitor_mentions.split(',').map(s => s.trim())) {\n      if (c) competitorMap[c] = (competitorMap[c] || 0) + 1;\n    }\n  }\n}\nconst topCompetitors = Object.entries(competitorMap).sort((a, b) => b[1] - a[1]).slice(0, 3);\nconst competitorSummary = topCompetitors.length > 0\n  ? topCompetitors.map(([brand, count]) => `${brand} (${count}x)`).join(', ')\n  : 'None detected';\n\n// ── Platform breakdown ──\nconst platformCounts = {};\nfor (const r of reviews) {\n  const p = r.platform || 'Unknown';\n  platformCounts[p] = (platformCounts[p] || 0) + 1;\n}\nconst platformBreakdown = Object.entries(platformCounts).map(([p, c]) => `${p}: ${c}`).join(' | ');\n\n// ── Top 3 praises ──\nconst topPraises = reviews\n  .filter(r => r.sentiment_label === 'positive')\n  .sort((a, b) => b.sentiment_score - a.sentiment_score)\n  .slice(0, 3)\n  .map(r => `• ${r.key_phrase || r.summary?.slice(0, 80) || ''} [${r.platform}, ${r.rating}⭐]`);\n\n// ── Top 3 complaints ──\nconst topComplaints = reviews\n  .filter(r => r.sentiment_label === 'negative')\n  .sort((a, b) => a.sentiment_score - b.sentiment_score)\n  .slice(0, 3)\n  .map(r => `• ${r.key_phrase || r.summary?.slice(0, 80) || ''} [${r.platform}, ${r.rating}⭐]`);\n\n// ── Viral risk reviews ──\nconst viralReviews = reviews.filter(r => r.viral_risk).slice(0, 3);\n\n// ── Action items ──\nconst actionItems = reviews.filter(r => r.action_required).slice(0, 5);\n\n// ── Build Slack digest message ──\nlet digest = `📊 *BrandPulse 360° — Daily Brand Health Report*\\n`;\ndigest += `📅 ${runDate} | 🛒 Ecommerce Review Intelligence\\n`;\ndigest += `─────────────────────────────────\\n\\n`;\n\ndigest += `${basEmoji} *Brand Awareness Score (BAS): ${BAS}/100 — ${basLabel}*\\n`;\ndigest += `⭐ Avg Rating: ${avgRating}/5 | 📊 Avg Sentiment: ${avgSentimentScore} | 🎯 CX Score: ${avgCxScore}/10\\n`;\ndigest += `📦 Total Reviews Processed: ${reviews.length}\\n`;\ndigest += `🟢 Positive: ${sentimentCounts.positive} | 🟡 Neutral: ${sentimentCounts.neutral} | 🔴 Negative: ${sentimentCounts.negative}\\n\\n`;\n\ndigest += `*📍 Platform Breakdown:* ${platformBreakdown}\\n`;\ndigest += `*🎭 Top Emotions Detected:* ${topEmotions || 'N/A'}\\n`;\ndigest += `*🔧 Most Discussed Dimension:* ${topDimension}\\n`;\ndigest += `*⚔️ Competitor Mentions:* ${competitorSummary}\\n\\n`;\n\nif (topPraises.length > 0) {\n  digest += `*✅ Top Praise Signals:*\\n${topPraises.join('\\n')}\\n\\n`;\n}\n\nif (topComplaints.length > 0) {\n  digest += `*❌ Top Complaint Signals:*\\n${topComplaints.join('\\n')}\\n\\n`;\n}\n\nif (viralReviews.length > 0) {\n  digest += `*🔥 Viral Risk Reviews (${viralCount}):*\\n`;\n  for (const v of viralReviews) {\n    digest += `• ${v.productName} [${v.platform}, ${v.rating}⭐] — ${v.viral_reason || 'High engagement'}\\n`;\n  }\n  digest += '\\n';\n}\n\nif (actionItems.length > 0) {\n  digest += `*⚠️ ${actionItems.length} Review(s) Requiring Action:*\\n`;\n  for (const a of actionItems) {\n    digest += `• ${a.productName} [${a.platform}, ${a.rating}⭐] — ${a.action_reason}\\n`;\n  }\n  digest += '\\n';\n}\n\ndigest += `_BrandPulse 360° | Powered by MrScraper + GPT-4o-mini + n8n_`;\n\nreturn [{\n  json: {\n    digestMessage: digest,\n    total: reviews.length,\n    sentimentCounts,\n    avgRating,\n    avgSentimentScore,\n    avgCxScore,\n    BAS,\n    basLabel,\n    viralCount,\n    actionCount,\n    competitorSummary,\n    runDate,\n    slackChannel: reviews[0]?.slackChannel || '#brand-monitoring'\n  }\n}];"},"typeVersion":2},{"id":"67db960a-b79f-4e79-bf94-93f08877404d","name":"Slack - Daily Brand Digest","type":"n8n-nodes-base.slack","position":[3808,192],"webhookId":"cf622ee2-42be-4450-9949-59331c9f8a51","parameters":{"text":"={{ $json.digestMessage }}","select":"channel","channelId":{"__rl":true,"mode":"name","value":"={{ $json.slackChannel }}"},"otherOptions":{"mrkdwn":true}},"typeVersion":2.3},{"id":"faf60391-e42a-4b7f-92e8-47c06feb72e0","name":"Get Target Product List","type":"n8n-nodes-base.googleSheets","position":[1072,208],"parameters":{"options":{},"sheetName":{"__rl":true,"mode":"list","value":"gid=0","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit#gid=0","cachedResultName":"Sheet1"},"documentId":{"__rl":true,"mode":"list","value":"// Input your Google Sheet ID here","cachedResultUrl":"https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID","cachedResultName":"Target Product List"}},"credentials":{"googleSheetsOAuth2Api":{"id":"HofjgH0Hk3EpOn57","name":"Google Sheets account - Riandra"}},"typeVersion":4.7},{"id":"7e73c8d7-a504-4f6d-8458-59c6ae795efc","name":"Extract Review URLs","type":"n8n-nodes-base.code","position":[1744,80],"parameters":{"jsCode":"// Extract review URLs from MrScraper map agent response\nconst inputData = $input.all();\nlet urls = [];\n\nif (\n  inputData.length > 0 &&\n  inputData[0].json?.data?.data?.urls &&\n  Array.isArray(inputData[0].json.data.data.urls)\n) {\n  urls = inputData[0].json.data.data.urls;\n}\n\n// Filter to only include review-related URLs\nconst reviewPatterns = [/review/i, /ulasan/i, /rating/i, /comment/i, /feedback/i];\nconst filteredUrls = urls.filter(url =>\n  reviewPatterns.some(p => p.test(url))\n);\n\n// Use filtered if available, otherwise use all (some platforms keep reviews on product page)\nconst finalUrls = filteredUrls.length > 0 ? filteredUrls : urls;\n\nreturn finalUrls.map((url, index) => ({\n  json: {\n    url,\n    index: index + 1\n  }\n}));"},"typeVersion":2},{"id":"ba8c747d-377d-4812-b381-6c268504e4df","name":"Sticky Note - Setup","type":"n8n-nodes-base.stickyNote","position":[0,0],"parameters":{"color":7,"width":720,"height":1200,"content":"## 🛒 BrandPulse 360° — Setup & Configuration\n\n### Before Running This Workflow\n\n**A) Google Sheets Setup (required)**\nCreate a sheet with these columns (exact names):\n- `Platform` → e.g. Tokopedia, Shopee, Lazada, Bukalapak\n- `Product_URL` → full product page URL\n- `Brand_Name` → your brand name (e.g. YourBrand)\n- `SKU_Code` → product identifier (e.g. SKU-001)\n- `Category` → e.g. Electronics, Fashion, Beauty\n- `Active` → Y or N (only Y rows are processed)\n\nAdd one row per product you want to monitor.\n\n**B) MrScraper Setup (required)**\nCreate TWO scrapers in your MrScraper dashboard:\n\n1. **Review List Scraper** (Map Agent)\n   - Crawls product page and discovers review URLs or review sections\n   - Copy its `scraperId` → paste into the Map Agent node\n\n2. **Review Detail Scraper** (General Agent)\n   - Extracts: review_text, rating, reviewer_name, review_date, photo_count, helpful_votes, verified_purchase, seller_reply\n   - Copy its `scraperId` → paste into the General Agent node\n\n3. **Enable AI Scraper API access** in MrScraper account settings.\n\n**C) Credentials Needed in n8n**\n- `MrScraper` API key → both MrScraper nodes\n- `OpenAI` API key → OpenAI Chat Model node\n- `Slack` OAuth → both Slack nodes\n- `Notion` OAuth → Notion node\n- `Google Sheets` OAuth2 → Google Sheets node\n\n**D) Config Values to Update (inside Filter & Enrich node)**\n- `slackChannel`: e.g. #brand-monitoring\n- `slackAlertChannel`: e.g. #brand-alerts\n- `notionDatabaseId`: from your Notion DB URL\n- `competitorKeywords`: comma-separated competitor names\n- `alertThreshold`: default 2.5 stars\n\n**E) Notion Database Properties**\nCreate a Notion DB with these properties:\n- Title (title)\n- SKU Code (text) | Platform (select) | Category (text)\n- Product URL (URL) | Star Rating (number)\n- Sentiment (select: positive/neutral/negative)\n- Sentiment Score (number) | Emotion Tags (text)\n- Product Dimension (select) | Key Phrase (text)\n- Summary (text) | CX Score (number)\n- Competitor Mentions (text) | Urgency Level (select)\n- Response Suggestion (text)\n- Viral Risk (checkbox) | Viral Reason (text)\n- Brand Loyalty Signal (checkbox) | Awareness Source (select)\n- Action Required (checkbox) | Action Reason (text)\n- Reviewer Name (text) | Verified Purchase (checkbox)\n- Photo Count (number) | Helpful Votes (number)\n- Review Excerpt (text) | Review Date (text) | Processed At (text)"},"typeVersion":1},{"id":"c9fe4e5f-0585-4bc3-96b3-8e0c8c9c25e4","name":"Sticky Note Phase Header 1","type":"n8n-nodes-base.stickyNote","position":[800,112],"parameters":{"color":4,"width":432,"height":256,"content":"## Phase 1 — Trigger & Config"},"typeVersion":1},{"id":"5649c41b-cdd1-42e3-bf7e-585713f56a72","name":"Sticky Note Phase 1 Notes","type":"n8n-nodes-base.stickyNote","position":[800,384],"parameters":{"color":4,"width":432,"height":336,"content":"### Phase 1 — What To Do\n* Trigger fires daily at **6:00 AM** — adjust to your timezone.\n* Google Sheets provides the product list.\n  Each row = one product SKU to monitor.\n* Loop processes each SKU independently.\n\n### Key Settings\n* **Trigger time** → edit the Schedule node\n* **Product list** → update Google Sheet ID\n* **Brand config** → edit slackChannel, notionDatabaseId, competitorKeywords inside the _Filter & Enrich Review Data_ node\n* Mark rows `Active = N` in Sheets to pause monitoring for a product without deleting it."},"typeVersion":1},{"id":"63da5a7a-da6b-45be-9e3f-b6a6cc9d6ce9","name":"Sticky Note Phase Header 2","type":"n8n-nodes-base.stickyNote","position":[1248,16],"parameters":{"color":2,"width":880,"height":336,"content":"##  Phase 2 — Review URL Discovery"},"typeVersion":1},{"id":"64ae885b-00d4-4aa5-ac99-9c03d112347c","name":"Sticky Note Phase 2 Notes","type":"n8n-nodes-base.stickyNote","position":[1248,368],"parameters":{"color":2,"width":880,"height":400,"content":"###  Phase 2 — What To Do\n1. **Map Agent** crawls the product page URL and discovers review section URLs or pagination links.\n2. **Extract Review URLs** node filters to only review-pattern URLs (e.g. /review, /ulasan).\n   If no review-specific URLs found, falls back to the product page itself (handles platforms where reviews are embedded).\n3. Each URL is passed individually into the review extraction loop.\n\n### Tips\n* For Tokopedia/Shopee, reviews are often on the same product page (no separate URL needed).\n* For Amazon, the review section has its own paginated URL — Map Agent handles this well.\n* Set `limit` on the Map Agent node to control max review pages per product.\n* Adjust `includePatterns` in the Map Agent to target review-specific page sections."},"typeVersion":1},{"id":"e8a96139-1c5f-4e71-b023-ec48c8379d3a","name":"Sticky Note Phase Header 3","type":"n8n-nodes-base.stickyNote","position":[2160,16],"parameters":{"color":5,"width":640,"height":336,"content":"## Phase 3 — Review Extraction & Filtering"},"typeVersion":1},{"id":"6a52db12-cb3d-4ea2-bf2d-2b9d19e48536","name":"Sticky Note Phase 3 Notes","type":"n8n-nodes-base.stickyNote","position":[2160,368],"parameters":{"color":5,"width":640,"height":560,"content":"### Phase 3 — What To Do\n1. **General Agent** extracts full review data from each URL.\n   Target fields in your MrScraper setup:\n   - `review_text` (or review / ulasan / content)\n   - `rating` (or star / stars / score)\n   - `reviewer_name` (or user / username)\n   - `review_date` (or date / created_at)\n   - `photo_count` (or images_count)\n   - `helpful_votes` (or likes)\n   - `verified_purchase` (boolean)\n   - `seller_reply` (or shop_reply / response)\n2. **Filter & Enrich** node:\n   - Skips reviews under 10 words (unless rating ≤ 2 stars — short bad reviews are still valuable signals)\n   - Generates a deduplication hash to prevent processing the same review twice\n   - Pre-flags viral risk based on photo count, helpful votes, and review length\n   - Passes product metadata (SKU, platform, brand) from Google Sheets into each review item\n3. **Keep Only Valid Reviews** passes only items where `skip = false`.\n\n### Expected Output Per Review\n- review_text, rating, reviewerName, reviewDate\n- photoCount, helpfulVotes, isVerified, sellerReply\n- productName, skuCode, platform, category, brandName\n- viralRiskPreflag, reviewHash"},"typeVersion":1},{"id":"70162d1b-7fe4-4064-9db0-0b7afd740b20","name":"Sticky Note Phase Header 4","type":"n8n-nodes-base.stickyNote","position":[2816,16],"parameters":{"color":6,"width":580,"height":336,"content":"## Phase 4 — AI Brand Sentiment Analysis"},"typeVersion":1},{"id":"03704708-7416-4b2a-898b-b15856d0c551","name":"Sticky Note Phase 4 Notes","type":"n8n-nodes-base.stickyNote","position":[2816,368],"parameters":{"color":6,"width":580,"height":720,"content":"### Phase 4 — What To Do\n1. **GPT-4o-mini** analyzes each review with a structured prompt.\n   Returns a JSON with all 15 brand intelligence fields:\n\n   **Sentiment & Emotion:**\n   - `sentiment_label` → positive / neutral / negative\n   - `sentiment_score` → -1.0 to +1.0\n   - `emotion_tags` → frustration / delight / anger / loyalty / confusion / trust...\n\n   **Product Quality Signals:**\n   - `product_dimension` → quality / delivery / packaging / pricing / authenticity / customer_service / after_sales\n\n   **Brand Reputation:**\n   - `key_phrase` → most impactful sentence from review\n   - `summary` → 2-sentence plain-English summary\n   - `cx_score` → Customer Experience score 1–10\n\n   **Competitive Intelligence:**\n   - `competitor_mentions` → array of competitor names detected\n\n   **Viral Risk Detection:**\n   - `viral_risk` → true/false\n   - `viral_reason` → explanation\n\n   **Action & Routing:**\n   - `urgency_level` → low / medium / high / critical\n   - `action_required` → true/false\n   - `action_reason` → why CS needs to respond\n   - `response_suggestion` → ready-to-use CS reply\n   - `brand_loyalty_signal` → repeat buyer praise detection\n   - `awareness_source` → first_time / repeat / referral_mention\n\n2. **Parse AI Response** node sanitizes output, builds display formats, and prepares Slack alert message.\n\n### Cost Tip\n* gpt-4o-mini ≈ $0.0001 per review (very low cost)\n* Switch to gpt-4o only for high-value product lines requiring deeper analysis"},"typeVersion":1},{"id":"849ecd84-987a-40d0-8d3d-ab30d3a4a84a","name":"Sticky Note Phase Header 5","type":"n8n-nodes-base.stickyNote","position":[3408,16],"parameters":{"color":3,"width":804,"height":336,"content":"## Phase 5 — Storage, Alerts & Daily Digest"},"typeVersion":1},{"id":"8311b054-8516-42f7-9cb5-8effb8bf1942","name":"Sticky Note Phase 5 Notes","type":"n8n-nodes-base.stickyNote","position":[3408,368],"parameters":{"color":3,"width":804,"height":720,"content":"### Phase 5 — What To Do\n1. **Needs Urgent Alert?** routes reviews where `action_required = true` to an immediate Slack alert.\n   Urgent conditions: urgency = critical or high, viral risk detected, competitor switch mentioned.\n\n2. **Slack - Urgent Brand Alert** fires instantly to your #brand-alerts channel.\n   Message includes: platform, product, rating, emotion, dimension, key phrase, viral reason, competitor mention, and AI-suggested CS response.\n\n3. **Notion - Save Review Analysis** stores every processed review with all 27 metadata fields.\n   Enables: filtering by SKU/platform/sentiment, trend tracking, quarterly brand audits, CS ticket creation.\n\n4. **Build Daily Brand Health Digest** aggregates the full run and calculates:\n   - **Brand Awareness Score (BAS)** out of 100 (weighted formula combining rating, sentiment trend, loyalty signals, viral penalty)\n   - Sentiment breakdown (positive/neutral/negative counts)\n   - Avg rating, avg sentiment score, avg CX score\n   - Platform breakdown\n   - Top 3 praises + top 3 complaints (with platform & rating)\n   - Top emotion tags detected\n   - Most discussed product dimension\n   - Competitor mention summary\n   - Viral risk review list\n   - Action items needing CS follow-up\n\n5. **Slack - Daily Brand Digest** posts the full report to #brand-monitoring every morning.\n\n### Slack Alert Types\n* 🚨 **Urgent Alert** → fires immediately when action_required = true\n* 📊 **Daily Digest** → posted once at end of run with full brand health summary\n\n### Optional Extensions\n* Add Gmail node after Slack Digest to email the report to brand team\n* Connect Notion DB to Google Looker Studio for visual BAS trend charts\n* Add Jira/Asana node to auto-create CS tickets for critical reviews"},"typeVersion":1}],"active":false,"pinData":{},"settings":{"binaryMode":"separate","availableInMCP":false,"executionOrder":"v1"},"versionId":"7c5fc293-34c5-4f36-9eb2-bfb686836a25","connections":{"Loop Each Review":{"main":[[{"node":"Loop Each Product SKU","type":"main","index":0}],[{"node":"MrScraper - Extract Review Content","type":"main","index":0}]]},"OpenAI Chat Model":{"ai_languageModel":[[{"node":"Brand Sentiment AI Agent","type":"ai_languageModel","index":0}]]},"Extract Review URLs":{"main":[[{"node":"Loop Each Review","type":"main","index":0}]]},"Needs Urgent Alert?":{"main":[[{"node":"Slack - Urgent Brand Alert","type":"main","index":0}],[{"node":"Notion - Save Review Analysis","type":"main","index":0}]]},"Loop Each Product SKU":{"main":[[{"node":"Build Daily Brand Health Digest","type":"main","index":0}],[{"node":"MrScraper - Discover Review URLs","type":"main","index":0}]]},"Get Target Product List":{"main":[[{"node":"Loop Each Product SKU","type":"main","index":0}]]},"Keep Only Valid Reviews":{"main":[[{"node":"Brand Sentiment AI Agent","type":"main","index":0}]]},"Brand Sentiment AI Agent":{"main":[[{"node":"Parse AI Response & Format Output","type":"main","index":0}]]},"Slack - Urgent Brand Alert":{"main":[[{"node":"Notion - Save Review Analysis","type":"main","index":0}]]},"Filter & Enrich Review Data":{"main":[[{"node":"Keep Only Valid Reviews","type":"main","index":0}]]},"Schedule Trigger (Daily 6AM)":{"main":[[{"node":"Get Target Product List","type":"main","index":0}]]},"Notion - Save Review Analysis":{"main":[[{"node":"Loop Each Review","type":"main","index":0}]]},"Build Daily Brand Health Digest":{"main":[[{"node":"Slack - Daily Brand Digest","type":"main","index":0}]]},"MrScraper - Discover Review URLs":{"main":[[{"node":"Extract Review URLs","type":"main","index":0}]]},"Parse AI Response & Format Output":{"main":[[{"node":"Needs Urgent Alert?","type":"main","index":0}]]},"MrScraper - Extract Review Content":{"main":[[{"node":"Filter & Enrich Review Data","type":"main","index":0}]]}}},"lastUpdatedBy":1,"workflowInfo":{"nodeCount":28,"nodeTypes":{"n8n-nodes-base.if":{"count":2},"n8n-nodes-base.code":{"count":4},"n8n-nodes-base.slack":{"count":2},"n8n-nodes-base.notion":{"count":1},"n8n-nodes-base.stickyNote":{"count":11},"n8n-nodes-base.googleSheets":{"count":1},"n8n-nodes-base.splitInBatches":{"count":2},"n8n-nodes-mrscraper.mrscraper":{"count":2},"n8n-nodes-base.scheduleTrigger":{"count":1},"@n8n/n8n-nodes-langchain.chainLlm":{"count":1},"@n8n/n8n-nodes-langchain.lmChatOpenAi":{"count":1}}},"status":"published","readyToDemo":null,"user":{"name":"riandra","username":"riandradiva","bio":"","verified":true,"links":[""],"avatar":"https://gravatar.com/avatar/c085ff3e99cfe2328699b49cb9802f5762a12c94cb8f21692548a0dc0cc6e2e4?r=pg&d=retro&size=200"},"nodes":[{"id":18,"icon":"file:googleSheets.svg","name":"n8n-nodes-base.googleSheets","codex":{"data":{"alias":["CSV","Sheet","Spreadsheet","GS"],"resources":{"generic":[{"url":"https://n8n.io/blog/love-at-first-sight-ricardos-n8n-journey/","icon":"❤️","label":"Love at first sight: Ricardo’s n8n journey"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/automatically-adding-expense-receipts-to-google-sheets-with-telegram-mindee-twilio-and-n8n/","icon":"🧾","label":"Automatically Adding Expense Receipts to Google Sheets with Telegram, Mindee, Twilio, and n8n"},{"url":"https://n8n.io/blog/supercharging-your-conference-registration-process-with-n8n/","icon":"🎫","label":"Supercharging your conference registration process with n8n"},{"url":"https://n8n.io/blog/creating-triggers-for-n8n-workflows-using-polling/","icon":"⏲","label":"Creating triggers for n8n workflows using polling"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/migrating-community-metrics-to-orbit-using-n8n/","icon":"📈","label":"Migrating Community Metrics to Orbit using n8n"},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/your-business-doesnt-need-you-to-operate/","icon":" 🖥️","label":"Hey founders! Your business doesn't need you to operate"},{"url":"https://n8n.io/blog/how-honest-burgers-use-automation-to-save-100k-per-year/","icon":"🍔","label":"How Honest Burgers Use Automation to Save $100k per year"},{"url":"https://n8n.io/blog/how-a-digital-strategist-uses-n8n-for-online-marketing/","icon":"💻","label":"How a digital strategist uses n8n for online marketing"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-a-membership-development-manager-automates-his-work-and-investments/","icon":"📈","label":"How a Membership Development Manager automates his work and investments"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.googlesheets/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/google/oauth-single-service/"}]},"categories":["Data & Storage","Productivity"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"input\",\"output\"]","defaults":{"name":"Google Sheets"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI2MCIgaGVpZ2h0PSI2MCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNS42OSAxIDUyIDE3LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0OC4yOTMgNjBIMTIuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDkgNTYuMzEyVjQuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTIuNzA3IDF6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM1LjY5IDEgNTIgMTcuMjI1SDM5LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzkuMjExIDE3LjIyNSA1MiAyMi40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTIwLjEyIDMxLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMS42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzEuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjxwYXRoIGZpbGw9IiMyOEI0NDYiIGQ9Ik0zNC42OSAwIDUxIDE2LjIyNXYzOS4wODdhMy42NyAzLjY3IDAgMCAxLTEuMDg0IDIuNjFBMy43IDMuNyAwIDAgMSA0Ny4yOTMgNTlIMTEuNzA3YTMuNyAzLjcgMCAwIDEtMi42MjMtMS4wNzhBMy42NyAzLjY3IDAgMCAxIDggNTUuMzEyVjMuNjg4YTMuNjcgMy42NyAwIDAgMSAxLjA4NC0yLjYxQTMuNyAzLjcgMCAwIDEgMTEuNzA3IDB6Ii8+PHBhdGggZmlsbD0iIzZBQ0U3QyIgZD0iTTM0LjY5IDAgNTEgMTYuMjI1SDM4LjM5N2MtMi4wNTQgMC0zLjcwNy0xLjgyOS0zLjcwNy0zLjg3MnoiLz48cGF0aCBmaWxsPSIjMjE5QjM4IiBkPSJNMzguMjExIDE2LjIyNSA1MSAyMS40OHYtNS4yNTV6Ii8+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTE5LjEyIDMwLjk3NWMwLS44MTcuNjYyLTEuNDc1IDEuNDgzLTEuNDc1aDE3Ljc5NGMuODIxIDAgMS40ODIuNjU4IDEuNDgyIDEuNDc1djE1LjQ4N2MwIC44MTgtLjY2MSAxLjQ3NS0xLjQ4MiAxLjQ3NUgyMC42MDNhMS40NzYgMS40NzYgMCAwIDEtMS40ODItMS40NzRWMzAuOTc0em0yLjIyNSAxLjQ3NWg2LjY3MnYyLjIxMmgtNi42NzJ6bTAgNS4xNjJoNi42NzJ2Mi4yMTNoLTYuNjcyem0wIDUuMTYzaDYuNjcydjIuMjEyaC02LjY3MnptOS42MzgtMTAuMzI1aDYuNjcydjIuMjEyaC02LjY3MnptMCA1LjE2Mmg2LjY3MnYyLjIxM2gtNi42NzJ6bTAgNS4xNjNoNi42NzJ2Mi4yMTJoLTYuNjcyeiIvPjwvZz48L3N2Zz4="},"displayName":"Google Sheets","typeVersion":5,"nodeCategories":[{"id":3,"name":"Data & Storage"},{"id":4,"name":"Productivity"}]},{"id":20,"icon":"fa:map-signs","name":"n8n-nodes-base.if","codex":{"data":{"alias":["Router","Filter","Condition","Logic","Boolean","Branch"],"details":"The IF node can be used to implement binary conditional logic in your workflow. You can set up one-to-many conditions to evaluate each item of data being inputted into the node. That data will either evaluate to TRUE or FALSE and route out of the node accordingly.\n\nThis node has multiple types of conditions: Bool, String, Number, and Date & Time.","resources":{"generic":[{"url":"https://n8n.io/blog/learn-to-automate-your-factorys-incident-reporting-a-step-by-step-guide/","icon":"🏭","label":"Learn to Automate Your Factory's Incident Reporting: A Step by Step Guide"},{"url":"https://n8n.io/blog/2021-the-year-to-automate-the-new-you-with-n8n/","icon":"☀️","label":"2021: The Year to Automate the New You with n8n"},{"url":"https://n8n.io/blog/why-business-process-automation-with-n8n-can-change-your-daily-life/","icon":"🧬","label":"Why business process automation with n8n can change your daily life"},{"url":"https://n8n.io/blog/create-a-toxic-language-detector-for-telegram/","icon":"🤬","label":"Create a toxic language detector for Telegram in 4 step"},{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/how-to-build-a-low-code-self-hosted-url-shortener/","icon":"🔗","label":"How to build a low-code, self-hosted URL shortener in 3 steps"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/automate-google-apps-for-productivity/","icon":"💡","label":"15 Google apps you can combine and automate to increase productivity"},{"url":"https://n8n.io/blog/automation-for-maintainers-of-open-source-projects/","icon":"🏷️","label":"How to automatically manage contributions to open-source projects"},{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/5-workflow-automations-for-mattermost-that-we-love-at-n8n/","icon":"🤖","label":"5 workflow automations for Mattermost that we love at n8n"},{"url":"https://n8n.io/blog/why-this-product-manager-loves-workflow-automation-with-n8n/","icon":"🧠","label":"Why this Product Manager loves workflow automation with n8n"},{"url":"https://n8n.io/blog/sending-automated-congratulations-with-google-sheets-twilio-and-n8n/","icon":"🙌","label":"Sending Automated Congratulations with Google Sheets, Twilio, and n8n "},{"url":"https://n8n.io/blog/how-to-set-up-a-ci-cd-pipeline-with-no-code/","icon":"🎡","label":"How to set up a no-code CI/CD pipeline with GitHub and TravisCI"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"},{"url":"https://n8n.io/blog/aws-workflow-automation/","label":"7 no-code workflow automations for Amazon Web Services"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.if/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"transform\"]","defaults":{"name":"If","color":"#408000"},"iconData":{"icon":"map-signs","type":"icon"},"displayName":"If","typeVersion":2,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":39,"icon":"fa:sync","name":"n8n-nodes-base.splitInBatches","codex":{"data":{"alias":["Loop","Concatenate","Batch","Split","Split In Batches"],"resources":{"generic":[{"url":"https://n8n.io/blog/how-uproc-scraped-a-multi-page-website-with-a-low-code-workflow/","icon":" 🕸️","label":"How uProc scraped a multi-page website with a low-code workflow"},{"url":"https://n8n.io/blog/benefits-of-automation-and-n8n-an-interview-with-hubspots-hugh-durkin/","icon":"🎖","label":"Benefits of automation and n8n: An interview with HubSpot's Hugh Durkin"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitinbatches/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Flow"]}}},"group":"[\"organization\"]","defaults":{"name":"Loop Over Items","color":"#007755"},"iconData":{"icon":"sync","type":"icon"},"displayName":"Loop Over Items (Split in Batches)","typeVersion":3,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":40,"icon":"file:slack.svg","name":"n8n-nodes-base.slack","codex":{"data":{"alias":["human","form","wait","hitl","approval"],"resources":{"generic":[{"url":"https://n8n.io/blog/no-code-ecommerce-workflow-automations/","icon":"store","label":"6 e-commerce workflows to power up your Shopify s"},{"url":"https://n8n.io/blog/automate-your-data-processing-pipeline-in-9-steps-with-n8n/","icon":"⚙️","label":"Automate your data processing pipeline in 9 steps"},{"url":"https://n8n.io/blog/how-to-get-started-with-crm-automation-and-no-code-workflow-ideas/","icon":"👥","label":"How to get started with CRM automation (with 3 no-code workflow ideas"},{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "},{"url":"https://n8n.io/blog/build-your-own-virtual-assistant-with-n8n-a-step-by-step-guide/","icon":"👦","label":"Build your own virtual assistant with n8n: A step by step guide"},{"url":"https://n8n.io/blog/how-to-automatically-give-kudos-to-contributors-with-github-slack-and-n8n/","icon":"👏","label":"How to automatically give kudos to contributors with GitHub, Slack, and n8n"},{"url":"https://n8n.io/blog/automations-for-activists/","icon":"✨","label":"How Common Knowledge use workflow automation for activism"}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.slack/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/slack/"}]},"categories":["Communication","HITL"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"HITL":["Human in the Loop"]}}},"group":"[\"output\"]","defaults":{"name":"Slack"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiB2aWV3Qm94PSIwIDAgMTUwLjg1MiAxNTAuODUyIj48dXNlIHhsaW5rOmhyZWY9IiNhIiB4PSIuOTI2IiB5PSIuOTI2Ii8+PHN5bWJvbCBpZD0iYSIgb3ZlcmZsb3c9InZpc2libGUiPjxnIHN0cm9rZS13aWR0aD0iMS44NTIiPjxwYXRoIGZpbGw9IiNlMDFlNWEiIHN0cm9rZT0iI2UwMWU1YSIgZD0iTTQwLjc0MSA5My41NWMwLTguNzM1IDYuNjA3LTE1Ljc3MiAxNC44MTUtMTUuNzcyczE0LjgxNSA3LjAzNyAxNC44MTUgMTUuNzcydjM4LjgyNGMwIDguNzM3LTYuNjA3IDE1Ljc3NC0xNC44MTUgMTUuNzc0cy0xNC44MTUtNy4wMzctMTQuODE1LTE1Ljc3MnoiLz48cGF0aCBmaWxsPSIjZWNiMjJkIiBzdHJva2U9IiNlY2IyMmQiIGQ9Ik05My41NSAxMDcuNDA4Yy04LjczNSAwLTE1Ljc3Mi02LjYwNy0xNS43NzItMTQuODE1czcuMDM3LTE0LjgxNSAxNS43NzItMTQuODE1aDM4LjgyNmM4LjczNSAwIDE1Ljc3MiA2LjYwNyAxNS43NzIgMTQuODE1cy03LjAzNyAxNC44MTUtMTUuNzcyIDE0LjgxNXoiLz48cGF0aCBmaWxsPSIjMmZiNjdjIiBzdHJva2U9IiMyZmI2N2MiIGQ9Ik03Ny43NzggMTUuNzcyQzc3Ljc3OCA3LjAzNyA4NC4zODUgMCA5Mi41OTMgMHMxNC44MTUgNy4wMzcgMTQuODE1IDE1Ljc3MnYzOC44MjZjMCA4LjczNS02LjYwNyAxNS43NzItMTQuODE1IDE1Ljc3MnMtMTQuODE1LTcuMDM3LTE0LjgxNS0xNS43NzJ6Ii8+PHBhdGggZmlsbD0iIzM2YzVmMSIgc3Ryb2tlPSIjMzZjNWYxIiBkPSJNMTUuNzcyIDcwLjM3MUM3LjAzNyA3MC4zNzEgMCA2My43NjMgMCA1NS41NTZzNy4wMzctMTQuODE1IDE1Ljc3Mi0xNC44MTVoMzguODI2YzguNzM1IDAgMTUuNzcyIDYuNjA3IDE1Ljc3MiAxNC44MTVzLTcuMDM3IDE0LjgxNS0xNS43NzIgMTQuODE1eiIvPjxnIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiPjxwYXRoIGZpbGw9IiNlY2IyMmQiIHN0cm9rZT0iI2VjYjIyZCIgZD0iTTc3Ljc3OCAxMzMuMzMzYzAgOC4yMDggNi42MDcgMTQuODE1IDE0LjgxNSAxNC44MTVzMTQuODE1LTYuNjA3IDE0LjgxNS0xNC44MTUtNi42MDctMTQuODE1LTE0LjgxNS0xNC44MTVINzcuNzc4eiIvPjxwYXRoIGZpbGw9IiMyZmI2N2MiIHN0cm9rZT0iIzJmYjY3YyIgZD0iTTEzMy4zMzQgNzAuMzcxaC0xNC44MTVWNTUuNTU2YzAtOC4yMDcgNi42MDctMTQuODE1IDE0LjgxNS0xNC44MTVzMTQuODE1IDYuNjA3IDE0LjgxNSAxNC44MTUtNi42MDcgMTQuODE1LTE0LjgxNSAxNC44MTV6Ii8+PHBhdGggZmlsbD0iI2UwMWU1YSIgc3Ryb2tlPSIjZTAxZTVhIiBkPSJNMTQuODE1IDc3Ljc3OEgyOS42M3YxNC44MTVjMCA4LjIwNy02LjYwNyAxNC44MTUtMTQuODE1IDE0LjgxNVMwIDEwMC44IDAgOTIuNTkzczYuNjA3LTE0LjgxNSAxNC44MTUtMTQuODE1eiIvPjxwYXRoIGZpbGw9IiMzNmM1ZjEiIHN0cm9rZT0iIzM2YzVmMSIgZD0iTTcwLjM3MSAxNC44MTVWMjkuNjNINTUuNTU2Yy04LjIwNyAwLTE0LjgxNS02LjYwNy0xNC44MTUtMTQuODE1UzQ3LjM0OCAwIDU1LjU1NiAwczE0LjgxNSA2LjYwNyAxNC44MTUgMTQuODE1eiIvPjwvZz48L2c+PC9zeW1ib2w+PC9zdmc+"},"displayName":"Slack","typeVersion":2,"nodeCategories":[{"id":6,"name":"Communication"},{"id":28,"name":"HITL"}]},{"id":487,"icon":"file:notion.svg","name":"n8n-nodes-base.notion","codex":{"data":{"resources":{"generic":[{"url":"https://n8n.io/blog/5-tasks-you-can-automate-with-notion-api/","icon":"⚡️","label":"5 tasks you can automate with the new Notion API "}],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/app-nodes/n8n-nodes-base.notion/"}],"credentialDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/credentials/notion/"}]},"categories":["Productivity"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"output\"]","defaults":{"name":"Notion"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03LjU4Mjc2IDYuOTc2NzlDOC44MjA0NyA3Ljk4MjM4IDkuMjg0NzkgNy45MDU2NiAxMS42MDkxIDcuNzUwNTdMMzMuNTIwNiA2LjQzNDg4QzMzLjk4NTMgNi40MzQ4OCAzMy41OTg5IDUuOTcxMjcgMzMuNDQzOSA1Ljg5NDIzTDI5LjgwNDkgMy4yNjM0OEMyOS4xMDc2IDIuNzIyMTMgMjguMTc4NiAyLjEwMjE3IDI2LjM5ODIgMi4yNTcyNkw1LjE4MTE1IDMuODA0NzZDNC40MDczNiAzLjg4MTQ4IDQuMjUyODIgNC4yNjgzNyA0LjU2MDk2IDQuNTc4NDdMNy41ODI3NiA2Ljk3Njc5Wk04Ljg5ODI5IDEyLjA4MzNWMzUuMTM4MUM4Ljg5ODI5IDM2LjM3NzEgOS41MTc0NiAzNi44NDA3IDEwLjkxMSAzNi43NjRMMzQuOTkxOSAzNS4zNzA2QzM2LjM4NjIgMzUuMjkzOSAzNi41NDE1IDM0LjQ0MTcgMzYuNTQxNSAzMy40MzUyVjEwLjUzNTFDMzYuNTQxNSA5LjUzMDE5IDM2LjE1NDkgOC45ODgyOSAzNS4zMDE0IDkuMDY1NjRMMTAuMTM2NyAxMC41MzUxQzkuMjA3OTkgMTAuNjEzMSA4Ljg5ODIxIDExLjA3NzcgOC44OTgyMSAxMi4wODMzSDguODk4MjlaTTMyLjY3MDggMTMuMzJDMzIuODI1MiAxNC4wMTcgMzIuNjcwOCAxNC43MTMzIDMxLjk3MjUgMTQuNzkxN0wzMC44MTIzIDE1LjAyMjlWMzIuMDQzNEMyOS44MDQ5IDMyLjU4NDggMjguODc1OSAzMi44OTQ0IDI4LjEwMTggMzIuODk0NEMyNi44NjI1IDMyLjg5NDQgMjYuNTUyMSAzMi41MDcyIDI1LjYyMzcgMzEuMzQ3NEwxOC4wMzQzIDE5LjQzMjlWMzAuOTYwNUwyMC40MzU5IDMxLjUwMjRDMjAuNDM1OSAzMS41MDI0IDIwLjQzNTkgMzIuODk0NCAxOC40OTgzIDMyLjg5NDRMMTMuMTU2OCAzMy4yMDQyQzEzLjAwMTYgMzIuODk0NCAxMy4xNTY4IDMyLjEyMTQgMTMuNjk4NiAzMS45NjY1TDE1LjA5MjUgMzEuNTgwMlYxNi4zMzg1TDEzLjE1NzIgMTYuMTgzNEMxMy4wMDE5IDE1LjQ4NjQgMTMuMzg4NSAxNC40ODE0IDE0LjQ3MzMgMTQuNDAzNUwyMC4yMDM1IDE0LjAxNzJMMjguMTAxOCAyNi4wODY4VjE1LjQwOTdMMjYuMDg4MSAxNS4xNzg2QzI1LjkzMzUgMTQuMzI2NSAyNi41NTIxIDEzLjcwNzggMjcuMzI2NSAxMy42MzExTDMyLjY3MDggMTMuMzJaTTMuMzk5NzMgMS43MTU5OEwyNS40Njg4IDAuMDkwNzQ1N0MyOC4xNzkgLTAuMTQxNjg4IDI4Ljg3NjMgMC4wMTQwMjQ1IDMwLjU3OTYgMS4yNTEzNUwzNy42MjQzIDYuMjAyNzZDMzguNzg2NyA3LjA1NDIxIDM5LjE3NDIgNy4yODYwMiAzOS4xNzQyIDguMjE0MTlWMzUuMzcwNkMzOS4xNzQyIDM3LjA3MjYgMzguNTU0MiAzOC4wNzkxIDM2LjM4NjUgMzguMjMzMUwxMC43NTc3IDM5Ljc4MDdDOS4xMzA0OSAzOS44NTgzIDguMzU2MDcgMzkuNjI2NCA3LjUwMzkyIDM4LjU0MjZMMi4zMTYwOCAzMS44MTE3QzEuMzg2NTggMzAuNTcyNiAxIDI5LjY0NTcgMSAyOC41NjEzVjQuNDIyODNDMSAzLjAzMTA1IDEuNjIwMTkgMS44NzAwNSAzLjM5OTczIDEuNzE1OThWMS43MTU5OFoiIGZpbGw9ImJsYWNrIi8+Cjwvc3ZnPgo="},"displayName":"Notion","typeVersion":2,"nodeCategories":[{"id":4,"name":"Productivity"}]},{"id":565,"icon":"fa:sticky-note","name":"n8n-nodes-base.stickyNote","codex":{"data":{"alias":["Comments","Notes","Sticky"],"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers"]}}},"group":"[\"input\"]","defaults":{"name":"Sticky Note","color":"#FFD233"},"iconData":{"icon":"sticky-note","type":"icon"},"displayName":"Sticky Note","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":834,"icon":"file:code.svg","name":"n8n-nodes-base.code","codex":{"data":{"alias":["cpde","Javascript","JS","Python","Script","Custom Code","Function"],"details":"The Code node allows you to execute JavaScript in your workflow.","resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.code/"}]},"categories":["Development","Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0","subcategories":{"Core Nodes":["Helpers","Data Transformation"]}}},"group":"[\"transform\"]","defaults":{"name":"Code"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8xMTcxXzQ0MSkiPgo8cGF0aCBkPSJNMTcwLjI4MyA0OEgxOTYuNUMyMDMuMTI3IDQ4IDIwOC41IDQyLjYyNzQgMjA4LjUgMzZWMTJDMjA4LjUgNS4zNzI1OCAyMDMuMTI3IDAgMTk2LjUgMEgxNzAuMjgzQzEyNi4xIDAgOTAuMjgzIDM1LjgxNzIgOTAuMjgzIDgwVjE3NkM5MC4yODMgMjA2LjkyOCA2NS4yMTA5IDIzMiAzNC4yODMgMjMySDIzQzE2LjM3MjYgMjMyIDExIDIzNy4zNzIgMTEgMjQ0VjI2OEMxMSAyNzQuNjI3IDE2LjM3MjQgMjgwIDIyLjk5OTYgMjgwTDM0LjI4MyAyODBDNjUuMjEwOSAyODAgOTAuMjgzIDMwNS4wNzIgOTAuMjgzIDMzNlY0NDBDOTAuMjgzIDQ3OS43NjQgMTIyLjUxOCA1MTIgMTYyLjI4MyA1MTJIMTk2LjVDMjAzLjEyNyA1MTIgMjA4LjUgNTA2LjYyNyAyMDguNSA1MDBWNDc2QzIwOC41IDQ2OS4zNzMgMjAzLjEyNyA0NjQgMTk2LjUgNDY0SDE2Mi4yODNDMTQ5LjAyOCA0NjQgMTM4LjI4MyA0NTMuMjU1IDEzOC4yODMgNDQwVjMzNkMxMzguMjgzIDMwOS4wMjIgMTI4LjAxMSAyODQuNDQzIDExMS4xNjQgMjY1Ljk2MUMxMDYuMTA5IDI2MC40MTYgMTA2LjEwOSAyNTEuNTg0IDExMS4xNjQgMjQ2LjAzOUMxMjguMDExIDIyNy41NTcgMTM4LjI4MyAyMDIuOTc4IDEzOC4yODMgMTc2VjgwQzEzOC4yODMgNjIuMzI2OSAxNTIuNjEgNDggMTcwLjI4MyA0OFoiIGZpbGw9IiNGRjk5MjIiLz4KPHBhdGggZD0iTTMwNSAzNkMzMDUgNDIuNjI3NCAzMTAuMzczIDQ4IDMxNyA0OEgzNDIuOTc5QzM2MC42NTIgNDggMzc0Ljk3OCA2Mi4zMjY5IDM3NC45NzggODBWMTc2QzM3NC45NzggMjAyLjk3OCAzODUuMjUxIDIyNy41NTcgNDAyLjA5OCAyNDYuMDM5QzQwNy4xNTMgMjUxLjU4NCA0MDcuMTUzIDI2MC40MTYgNDAyLjA5OCAyNjUuOTYxQzM4NS4yNTEgMjg0LjQ0MyAzNzQuOTc4IDMwOS4wMjIgMzc0Ljk3OCAzMzZWNDMyQzM3NC45NzggNDQ5LjY3MyAzNjAuNjUyIDQ2NCAzNDIuOTc5IDQ2NEgzMTdDMzEwLjM3MyA0NjQgMzA1IDQ2OS4zNzMgMzA1IDQ3NlY1MDBDMzA1IDUwNi42MjcgMzEwLjM3MyA1MTIgMzE3IDUxMkgzNDIuOTc5QzM4Ny4xNjEgNTEyIDQyMi45NzggNDc2LjE4MyA0MjIuOTc4IDQzMlYzMzZDNDIyLjk3OCAzMDUuMDcyIDQ0OC4wNTEgMjgwIDQ3OC45NzkgMjgwSDQ5MEM0OTYuNjI3IDI4MCA1MDIgMjc0LjYyOCA1MDIgMjY4VjI0NEM1MDIgMjM3LjM3MyA0OTYuNjI4IDIzMiA0OTAgMjMyTDQ3OC45NzkgMjMyQzQ0OC4wNTEgMjMyIDQyMi45NzggMjA2LjkyOCA0MjIuOTc4IDE3NlY4MEM0MjIuOTc4IDM1LjgxNzIgMzg3LjE2MSAwIDM0Mi45NzkgMEgzMTdDMzEwLjM3MyAwIDMwNSA1LjM3MjU4IDMwNSAxMlYzNloiIGZpbGw9IiNGRjk5MjIiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8xMTcxXzQ0MSI+CjxyZWN0IHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8L2RlZnM+Cjwvc3ZnPgo="},"displayName":"Code","typeVersion":2,"nodeCategories":[{"id":5,"name":"Development"},{"id":9,"name":"Core Nodes"}]},{"id":839,"icon":"fa:clock","name":"n8n-nodes-base.scheduleTrigger","codex":{"data":{"alias":["Time","Scheduler","Polling","Cron","Interval"],"resources":{"generic":[],"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.scheduletrigger/"}]},"categories":["Core Nodes"],"nodeVersion":"1.0","codexVersion":"1.0"}},"group":"[\"trigger\",\"schedule\"]","defaults":{"name":"Schedule Trigger","color":"#31C49F"},"iconData":{"icon":"clock","type":"icon"},"displayName":"Schedule Trigger","typeVersion":1,"nodeCategories":[{"id":9,"name":"Core Nodes"}]},{"id":1123,"icon":"fa:link","name":"@n8n/n8n-nodes-langchain.chainLlm","codex":{"data":{"alias":["LangChain"],"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Chains","Root Nodes"]}}},"group":"[\"transform\"]","defaults":{"name":"Basic LLM Chain","color":"#909298"},"iconData":{"icon":"link","type":"icon"},"displayName":"Basic LLM Chain","typeVersion":2,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]},{"id":1153,"icon":"file:openAiLight.svg","name":"@n8n/n8n-nodes-langchain.lmChatOpenAi","codex":{"data":{"resources":{"primaryDocumentation":[{"url":"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatopenai/"}]},"categories":["AI","Langchain"],"subcategories":{"AI":["Language Models","Root Nodes"],"Language Models":["Chat Models (Recommended)"]}}},"group":"[\"transform\"]","defaults":{"name":"OpenAI Chat Model"},"iconData":{"type":"file","fileBuffer":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTM2Ljg2NzEgMTYuMzcxOEMzNy43NzQ2IDEzLjY0OCAzNy40NjIxIDEwLjY2NDIgMzYuMDEwOCA4LjE4NjYxQzMzLjgyODIgNC4zODY1MyAyOS40NDA3IDIuNDMxNDkgMjUuMTU1NiAzLjM1MTUxQzIzLjI0OTMgMS4yMDM5NiAyMC41MTA1IC0wLjAxNzMxNDggMTcuNjM5MiAwLjAwMDE4NTUzM0MxMy4yNTkxIC0wLjAwOTgxNDY4IDkuMzcyNzMgMi44MTAyNSA4LjAyNTIgNi45Nzc4M0M1LjIxMTM5IDcuNTU0MSAyLjc4MjU4IDkuMzE1MzggMS4zNjEzIDExLjgxMTdDLTAuODM3NDkzIDE1LjYwMTggLTAuMzM2MjMyIDIwLjM3OTQgMi42MDEzMyAyMy42Mjk0QzEuNjkzODEgMjYuMzUzMiAyLjAwNjMyIDI5LjMzNzEgMy40NTc2IDMxLjgxNDZDNS42NDAxNSAzNS42MTQ3IDEwLjAyNzcgMzcuNTY5NyAxNC4zMTI4IDM2LjY0OTdDMTYuMjE3OSAzOC43OTczIDE4Ljk1NzkgNDAuMDE4NSAyMS44MjkyIDM5Ljk5OThDMjYuMjExOCA0MC4wMTEgMzAuMDk5NCAzNy4xODg1IDMxLjQ0NjkgMzMuMDE3MUMzNC4yNjA4IDMyLjQ0MDkgMzYuNjg5NiAzMC42Nzk2IDM4LjExMDggMjguMTgzM0M0MC4zMDcxIDI0LjM5MzIgMzkuODA0NiAxOS42MTk0IDM2Ljg2ODMgMTYuMzY5M0wzNi44NjcxIDE2LjM3MThaTTIxLjgzMTcgMzcuMzg2QzIwLjA3OCAzNy4zODg1IDE4LjM3OTIgMzYuNzc0NyAxNy4wMzI5IDM1LjY1MDlDMTcuMDk0MSAzNS42MTg0IDE3LjIwMDQgMzUuNTU5NyAxNy4yNjkxIDM1LjUxNzJMMjUuMjM0MyAzMC45MTcxQzI1LjY0MTggMzAuNjg1OCAyNS44OTE4IDMwLjI1MjEgMjUuODg5MyAyOS43ODMzVjE4LjU1NDNMMjkuMjU1NyAyMC40OTgxQzI5LjI5MTkgMjAuNTE1NiAyOS4zMTU3IDIwLjU1MDYgMjkuMzIwNyAyMC41OTA2VjI5Ljg4OTZDMjkuMzE1NyAzNC4wMjQ3IDI1Ljk2NjggMzcuMzc3MiAyMS44MzE3IDM3LjM4NlpNNS43MjY0IDMwLjUwNzFDNC44NDc2MyAyOC45ODk2IDQuNTMxMzcgMjcuMjEwOCA0LjgzMjYzIDI1LjQ4NDVDNC44OTEzOCAyNS41MTk1IDQuOTk1MTMgMjUuNTgzMiA1LjA2ODg4IDI1LjYyNTdMMTMuMDM0MSAzMC4yMjU4QzEzLjQzNzggMzAuNDYyMSAxMy45Mzc4IDMwLjQ2MjEgMTQuMzQyOCAzMC4yMjU4TDI0LjA2NjggMjQuNjEwN1YyOC40OTgzQzI0LjA2OTMgMjguNTM4MyAyNC4wNTA1IDI4LjU3NyAyNC4wMTkzIDI4LjYwMkwxNS45Njc5IDMzLjI1MDlDMTIuMzgxNSAzNS4zMTU5IDcuODAxNDQgMzQuMDg4NCA1LjcyNzY1IDMwLjUwNzFINS43MjY0Wk0zLjYzMDEgMTMuMTIwNUM0LjUwNTEyIDExLjYwMDQgNS44ODY0IDEwLjQzNzkgNy41MzE0NCA5LjgzNDE1QzcuNTMxNDQgOS45MDI5IDcuNTI3NjkgMTAuMDI0MiA3LjUyNzY5IDEwLjEwOTJWMTkuMzEwNkM3LjUyNTE5IDE5Ljc3ODEgNy43NzUxOSAyMC4yMTE5IDguMTgxNDUgMjAuNDQzMUwxNy45MDU0IDI2LjA1N0wxNC41MzkxIDI4LjAwMDhDMTQuNTA1MyAyOC4wMjMzIDE0LjQ2MjggMjguMDI3IDE0LjQyNTMgMjguMDEwOEw2LjM3MjY2IDIzLjM1ODJDMi43OTM4MyAyMS4yODU2IDEuNTY2MzEgMTYuNzA2OCAzLjYyODg1IDEzLjEyMTdMMy42MzAxIDEzLjEyMDVaTTMxLjI4ODIgMTkuNTU2OUwyMS41NjQyIDEzLjk0MTdMMjQuOTMwNiAxMS45OTkyQzI0Ljk2NDMgMTEuOTc2NyAyNS4wMDY4IDExLjk3MjkgMjUuMDQ0MyAxMS45ODkyTDMzLjA5NyAxNi42MzhDMzYuNjgyMSAxOC43MDkzIDM3LjkxMDggMjMuMjk1NyAzNS44Mzk1IDI2Ljg4MDhDMzQuOTYzMyAyOC4zOTgzIDMzLjU4MzIgMjkuNTYwOCAzMS45Mzk1IDMwLjE2NThWMjAuNjg5NEMzMS45NDMyIDIwLjIyMTkgMzEuNjk0NSAxOS43ODk0IDMxLjI4OTQgMTkuNTU2OUgzMS4yODgyWk0zNC42MzgzIDE0LjUxNDJDMzQuNTc5NSAxNC40NzggMzQuNDc1OCAxNC40MTU1IDM0LjQwMiAxNC4zNzNMMjYuNDM2OCA5Ljc3Mjg5QzI2LjAzMzEgOS41MzY2NCAyNS41MzMxIDkuNTM2NjQgMjUuMTI4MSA5Ljc3Mjg5TDE1LjQwNDEgMTUuMzg4VjExLjUwMDRDMTUuNDAxNiAxMS40NjA0IDE1LjQyMDQgMTEuNDIxNyAxNS40NTE2IDExLjM5NjdMMjMuNTAzIDYuNzUxNThDMjcuMDg5NCA0LjY4Mjc5IDMxLjY3NDUgNS45MTQwNiAzMy43NDIgOS41MDE2NEMzNC42MTU4IDExLjAxNjcgMzQuOTMyIDEyLjc5MDUgMzQuNjM1OCAxNC41MTQySDM0LjYzODNaTTEzLjU3NDEgMjEuNDQzMUwxMC4yMDY1IDE5LjQ5OTRDMTAuMTcwMiAxOS40ODE5IDEwLjE0NjUgMTkuNDQ2OCAxMC4xNDE1IDE5LjQwNjhWMTAuMTA3OUMxMC4xNDQgNS45Njc4MSAxMy41MDI4IDIuNjEyNzQgMTcuNjQyOSAyLjYxNTI0QzE5LjM5NDIgMi42MTUyNCAyMS4wODkyIDMuMjMwMjUgMjIuNDM1NSA0LjM1MDI4QzIyLjM3NDMgNC4zODI3OCAyMi4yNjkzIDQuNDQxNTMgMjIuMTk5MiA0LjQ4NDAzTDE0LjIzNDEgOS4wODQxM0MxMy44MjY2IDkuMzE1MzggMTMuNTc2NiA5Ljc0Nzg5IDEzLjU3OTEgMTAuMjE2N0wxMy41NzQxIDIxLjQ0MDZWMjEuNDQzMVpNMTUuNDAyOSAxNy41MDA2TDE5LjczNDIgMTQuOTk5M0wyNC4wNjU1IDE3LjQ5OTNWMjIuNTAwN0wxOS43MzQyIDI1LjAwMDdMMTUuNDAyOSAyMi41MDA3VjE3LjUwMDZaIiBmaWxsPSIjN0Q3RDg3Ii8+Cjwvc3ZnPgo="},"displayName":"OpenAI Chat Model","typeVersion":1,"nodeCategories":[{"id":25,"name":"AI"},{"id":26,"name":"Langchain"}]}],"categories":[{"id":32,"name":"Market Research"},{"id":49,"name":"AI Summarization"}],"image":[]}}