{
  "nodes": [
    {
      "id": "55b32b5a-3320-4e6e-acae-9a960b30eae0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        224
      ],
      "parameters": {
        "color": 7,
        "width": 1024,
        "height": 240,
        "content": "## Need more advanced automation solutions? Contact us for custom enterprise workflows!\n\n# Growth-AI.fr\n\n## https://www.linkedin.com/in/allanvaccarizi/\n## https://www.linkedin.com/in/hugo-marinier-%F0%9F%A7%B2-6537b633/"
      },
      "typeVersion": 1
    },
    {
      "id": "4871a388-e7ea-46ee-a366-97b4d7b4bce3",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1568,
        -224
      ],
      "parameters": {
        "width": 1024,
        "height": 400,
        "content": "![Logo Growth AI](https://cdn.prod.website-files.com/6825df5b20329ba581df4914/68d413c43f8729fa336568a6_Logo_horizontal.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "46ac9a16-dfbb-4583-9b62-44d79eccba4f",
      "name": "Sticky Note21",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1008,
        448
      ],
      "parameters": {
        "color": 2,
        "width": 480,
        "height": 176,
        "content": "![Query Table](https://cdn.prod.website-files.com/6825df5b20329ba581df4914/69c26981fe656b39959e5ace_Capture%20d%27%C3%A9cran%202026-03-24%20113742.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "4913d4bc-5db1-453f-9825-04625f26ed0a",
      "name": "When Schedule Triggers",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1072,
        848
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "94097653-0e95-47d5-ad66-3a2920249458",
      "name": "Send TikTok Report by Email",
      "type": "n8n-nodes-base.gmail",
      "notes": "Send dahsboard with top 10 of the most engaging post ",
      "position": [
        2400,
        848
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Trends Social Media - {{ $('Loop Over TikTok Queries').first().json.Query }}</title>\n    <style>\n        * {\n            margin: 0;\n            padding: 0;\n            box-sizing: border-box;\n        }\n\n        body {\n            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n            line-height: 1.6;\n            color: #333;\n            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n            min-height: 100vh;\n            padding: 20px;\n        }\n\n        .newsletter-container {\n            max-width: 1200px;\n            margin: 0 auto;\n            background: white;\n            border-radius: 20px;\n            overflow: hidden;\n            box-shadow: 0 20px 40px rgba(0,0,0,0.1);\n        }\n\n        .header {\n            background: linear-gradient(135deg, #ff6b6b, #ee5a24);\n            color: white;\n            padding: 40px 30px;\n            text-align: center;\n        }\n\n        .header h1 {\n            font-size: 2.8em;\n            margin-bottom: 10px;\n            font-weight: 700;\n        }\n\n        .header p {\n            font-size: 1.2em;\n            opacity: 0.9;\n            margin-bottom: 15px;\n        }\n\n        .keyword-badge {\n            display: inline-block;\n            background: rgba(255,255,255,0.2);\n            color: white;\n            padding: 8px 20px;\n            border-radius: 20px;\n            font-size: 1em;\n            font-weight: 600;\n            backdrop-filter: blur(10px);\n        }\n\n        .stats-overview {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n            gap: 20px;\n            padding: 30px;\n            background: #f8f9fa;\n        }\n\n        .stat-card {\n            background: white;\n            padding: 20px;\n            border-radius: 15px;\n            text-align: center;\n            box-shadow: 0 5px 15px rgba(0,0,0,0.08);\n            border-left: 4px solid;\n        }\n\n        .stat-card.high { border-left-color: #ff4757; }\n        .stat-card.medium { border-left-color: #ffa502; }\n        .stat-card.low { border-left-color: #70a1ff; }\n\n        .stat-number {\n            font-size: 2.5em;\n            font-weight: bold;\n            margin-bottom: 5px;\n        }\n\n        .stat-label {\n            color: #666;\n            font-size: 0.9em;\n            text-transform: uppercase;\n            letter-spacing: 1px;\n        }\n\n        .table-container {\n            margin: 30px;\n            background: white;\n            border-radius: 15px;\n            overflow: hidden;\n            box-shadow: 0 10px 25px rgba(0,0,0,0.1);\n        }\n\n        .table-header {\n            background: linear-gradient(135deg, #2c3e50, #34495e);\n            color: white;\n            padding: 25px 30px;\n            text-align: center;\n        }\n\n        .table-title {\n            font-size: 1.8em;\n            font-weight: 600;\n            margin-bottom: 5px;\n        }\n\n        .table-subtitle {\n            opacity: 0.8;\n            font-size: 1em;\n        }\n\n        .trends-table {\n            width: 100%;\n            border-collapse: collapse;\n            font-size: 0.95em;\n        }\n\n        .trends-table th {\n            background: #f8f9fa;\n            padding: 15px 12px;\n            text-align: left;\n            font-weight: 600;\n            color: #555;\n            border-bottom: 2px solid #dee2e6;\n            text-transform: uppercase;\n            font-size: 0.8em;\n            letter-spacing: 0.5px;\n        }\n\n        .trends-table td {\n            padding: 15px 12px;\n            border-bottom: 1px solid #eee;\n            vertical-align: middle;\n            text-align: center;\n        }\n\n        .trends-table td:nth-child(3),\n        .trends-table td:nth-child(4) {\n            text-align: left;\n        }\n\n        .trends-table tr:nth-child(even) {\n            background-color: #f8f9fa;\n        }\n\n        .trends-table tr:hover {\n            background-color: #e3f2fd;\n            transform: scale(1.01);\n            transition: all 0.2s ease;\n        }\n\n        .rank-number {\n            font-weight: bold;\n            font-size: 1.2em;\n            color: #2c3e50;\n        }\n\n        .rank-number.top3 {\n            color: #ff6b6b;\n            font-size: 1.4em;\n        }\n\n        .source-badge {\n            padding: 6px 12px;\n            border-radius: 20px;\n            font-size: 0.8em;\n            font-weight: 600;\n            text-transform: uppercase;\n            letter-spacing: 0.5px;\n        }\n\n        .source-badge.tiktok {\n            background: #ff0050;\n            color: white;\n        }\n\n        .source-badge.reddit {\n            background: #ff4500;\n            color: white;\n        }\n\n        .source-badge.instagram {\n            background: #e4405f;\n            color: white;\n        }\n\n        .level-badge {\n            padding: 4px 10px;\n            border-radius: 15px;\n            font-size: 0.75em;\n            font-weight: 600;\n            text-transform: uppercase;\n        }\n\n        .level-badge.high {\n            background: #ff4757;\n            color: white;\n        }\n\n        .level-badge.medium {\n            background: #ffa502;\n            color: white;\n        }\n\n        .level-badge.low {\n            background: #70a1ff;\n            color: white;\n        }\n\n        .content-text {\n            max-width: 250px;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            white-space: nowrap;\n            color: #555;\n            line-height: 1.4;\n        }\n\n        .author-link {\n            color: #667eea;\n            text-decoration: none;\n            font-weight: 600;\n        }\n\n        .author-link:hover {\n            text-decoration: underline;\n        }\n\n        .score-number {\n            font-weight: bold;\n            color: #2c3e50;\n            font-size: 1.1em;\n        }\n\n        .footer {\n            text-align: center;\n            padding: 30px;\n            background: #f8f9fa;\n            color: #666;\n            border-top: 1px solid #eee;\n        }\n\n        .footer p {\n            margin-bottom: 10px;\n        }\n\n        .date-info {\n            font-size: 0.9em;\n            color: #888;\n        }\n\n        @media (max-width: 768px) {\n            .newsletter-container {\n                margin: 10px;\n                border-radius: 15px;\n            }\n            \n            .header {\n                padding: 30px 20px;\n            }\n            \n            .header h1 {\n                font-size: 2.2em;\n            }\n            \n            .table-container {\n                margin: 20px;\n                overflow-x: auto;\n            }\n            \n            .trends-table {\n                min-width: 800px;\n            }\n            \n            .stats-overview {\n                padding: 20px;\n                grid-template-columns: 1fr;\n            }\n        }\n    </style>\n</head>\n<body>\n    <div class=\"newsletter-container\">\n        <!-- Header -->\n        <header class=\"header\">\n            <h1>\ud83d\udcca R\u00e9capitulatif par Hashtag</h1>\n            <p>Scores totaux par r\u00e9seau social</p>\n        </header>\n\n        <!-- Hashtag Summary Table -->\n        <section class=\"table-container\" style=\"margin: 30px 30px 0 30px;\">\n            <table class=\"trends-table\">\n                <thead>\n                    <tr>\n                        <th>Hashtag</th>\n                        <th>TikTok</th>\n                        <th>Reddit</th>\n                        <th>Instagram</th>\n                        <th>Score Total</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    <tr>\n                        <td>\n                            <span style=\"font-weight: bold; color: #ff6b6b; font-size: 1.1em;\">#{{ $('Loop Over TikTok Queries').first().json.Query }}</span>\n                        </td>\n                        <td>\n                            <span class=\"score-number\">{{ $('Rank TikTok Posts1').all().filter(item => item.json.source === 'TikTok').reduce((sum, item) => sum + item.json.score, 0).toLocaleString('fr-FR') }}</span>\n                        </td>\n                        <td>\n                            <span class=\"score-number\">{{ $('Rank TikTok Posts1').all().filter(item => item.json.source === 'Reddit').reduce((sum, item) => sum + item.json.score, 0).toLocaleString('fr-FR') }}</span>\n                        </td>\n                        <td>\n                            <span class=\"score-number\">{{ $('Rank TikTok Posts1').all().filter(item => item.json.source === 'Instagram').reduce((sum, item) => sum + item.json.score, 0).toLocaleString('fr-FR') }}</span>\n                        </td>\n                        <td>\n                            <span class=\"score-number\" style=\"color: #ff6b6b; font-size: 1.2em;\">{{ $('Rank TikTok Posts1').all().reduce((sum, item) => sum + item.json.score, 0).toLocaleString('fr-FR') }}</span>\n                        </td>\n                    </tr>\n                </tbody>\n            </table>\n        </section>\n\n        <!-- Main Table -->\n        <section class=\"table-container\">\n            <div class=\"table-header\">\n                <div class=\"table-title\">#{{ $('Loop Over TikTok Queries').first().json.Query }}</div>\n                <div class=\"table-subtitle\"></div>\n            </div>\n            \n            <table class=\"trends-table\">\n                <thead>\n                    <tr>\n                        <th>Rang</th>\n                        <th>Source</th>\n                        <th>Auteur</th>\n                        <th>Contenu</th>\n                        <th>Score</th>\n                        <th>Level</th>\n                    </tr>\n                </thead>\n                <tbody>\n                    {{ $('Rank TikTok Posts1').all().map(item => `\n                        <tr onclick=\"window.open('${item.json.url}', '_blank')\" style=\"cursor: pointer;\">\n                            <td>\n                                <span class=\"rank-number ${item.json.rank <= 3 ? 'top3' : ''}\">${item.json.rank}</span>\n                            </td>\n                            <td>\n                                <span class=\"source-badge ${item.json.source.toLowerCase()}\">${item.json.source}</span>\n                            </td>\n                            <td>\n                                <a href=\"${item.json.url}\" target=\"_blank\" class=\"author-link\">${item.json.author}</a>\n                            </td>\n                            <td>\n                                <div class=\"content-text\" title=\"${item.json.content}\">${item.json.content}</div>\n                            </td>\n                            <td>\n                                <span class=\"score-number\">${item.json.score.toLocaleString('fr-FR')}</span>\n                            </td>\n                            <td>\n                                <span class=\"level-badge ${item.json.level.toLowerCase()}\">${item.json.level}</span>\n                            </td>\n                        </tr>\n                    `).join('') }}\n                </tbody>\n            </table>\n        </section>\n\n        <!-- Footer -->\n        <footer class=\"footer\">\n            <p><strong>Social Media Trends Dashboard</strong></p>\n            <p>Analyse automatis\u00e9e des contenus par mot-cl\u00e9</p>\n            <div class=\"date-info\">\n                <p>G\u00e9n\u00e9r\u00e9 le {{ new Date().toLocaleDateString('fr-FR', { \n                    year: 'numeric', \n                    month: 'long', \n                    day: 'numeric', \n                    hour: '2-digit', \n                    minute: '2-digit' \n                }) }}</p>\n            </div>\n        </footer>\n    </div>\n</body>\n</html>",
        "options": {},
        "subject": "Social media monitoring"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "executeOnce": true,
      "notesInFlow": true,
      "typeVersion": 2.1
    },
    {
      "id": "9efb06ca-39fa-48e1-b9b1-5744b6a67e5c",
      "name": "Scrape TikTok via Apify",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "Post the request on apify",
      "position": [
        1744,
        848
      ],
      "parameters": {
        "url": "https://api.apify.com/v2/acts/clockworks~tiktok-scraper/run-sync-get-dataset-items",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"hashtags\": [\"{{ $json.Query.replace(/\\s+/g, '') }}\"],\n  \"resultsPerPage\": 50,\n  \"oldestPostDateUnified\": \"7 days\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "apifyApi"
      },
      "credentials": {
        "apifyApi": {
          "name": "<your credential>"
        },
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "executeOnce": false,
      "notesInFlow": true,
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "ef644544-31a8-48de-a8b6-72f91b36a77a",
      "name": "Score and Sort TikTok Posts",
      "type": "n8n-nodes-base.code",
      "notes": "Sorts posts",
      "position": [
        1984,
        848
      ],
      "parameters": {
        "jsCode": "// Code pour n\u0153ud Code n8n - Classement TikTok avec score personnalis\u00e9\n// R\u00e9cup\u00e9rer les donn\u00e9es d'entr\u00e9e\nconst items = $input.all();\n\n// V\u00e9rifier si on a des donn\u00e9es\nif (!items || items.length === 0) {\n  console.log(\"\u274c Aucune donn\u00e9e d'entr\u00e9e trouv\u00e9e\");\n  return [];\n}\n\n// Extraire les posts TikTok du JSON\nlet posts = [];\n\n// Si les donn\u00e9es sont dans un tableau \u00e0 l'int\u00e9rieur du premier item\nif (items[0] && items[0].json && Array.isArray(items[0].json)) {\n  posts = items[0].json;\n} \n// Si les donn\u00e9es sont directement dans les items\nelse if (Array.isArray(items)) {\n  posts = items.map(item => item.json);\n}\n\nconsole.log(`\ud83d\udce5 ${posts.length} posts TikTok trouv\u00e9s`);\n\n// Calculer le score pour chaque post TikTok\nconst postsWithScore = posts.map((post, index) => {\n  // M\u00e9triques TikTok\n  const likes = post.diggCount || 0;\n  const comments = post.commentCount || 0;\n  const shares = post.shareCount || 0;\n  const views = post.playCount || 0;\n  \n  // Calcul du score : (likes * 1) + (comments * 2) + (shares * 3) + (views / 1000)\n  const likesScore = likes * 1;\n  const commentsScore = comments * 2;\n  const sharesScore = shares * 3;\n  const viewsScore = Math.floor(views / 1000);\n  const totalScore = likesScore + commentsScore + sharesScore + viewsScore;\n  \n  return {\n    json: {\n      url: post.webVideoUrl || `https://www.tiktok.com/@${post.authorMeta?.name}/video/${post.id}`,\n      caption: post.text || \"Pas de caption\",\n      score: totalScore,\n      // Donn\u00e9es d\u00e9taill\u00e9es pour debug (optionnel)\n      details: {\n        likes: likes,\n        comments: comments,\n        shares: shares,\n        views: views,\n        author: post.authorMeta?.name || \"Inconnu\",\n        id: post.id\n      }\n    }\n  };\n}).filter(post => post.json.url); // Filtrer les posts sans URL\n\nconsole.log(`\u2705 ${postsWithScore.length} posts trait\u00e9s avec succ\u00e8s`);\n\n// Trier par score d\u00e9croissant\nconst sortedPosts = postsWithScore.sort((a, b) => b.json.score - a.json.score);\n\n// Prendre les 10 meilleurs\nconst topPosts = sortedPosts.slice(0, 10);\n\n// Ajouter un rang \u00e0 chaque post\nconst rankedPosts = topPosts.map((post, index) => ({\n  json: {\n    rank: index + 1,\n    url: post.json.url,\n    caption: post.json.caption,\n    score: post.json.score\n  }\n}));\n\n// Retourner les r\u00e9sultats avec le format demand\u00e9 : url, caption, score\nreturn rankedPosts;"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "f57ac21e-eaf9-455c-812e-c34572957f7f",
      "name": "Loop Over TikTok Queries",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1520,
        848
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "731ab30b-110f-424a-a071-c5ad15023cd2",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        512
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Trend monitoring TikTok\n\n### How it works\n\n1. A schedule trigger fires the workflow at regular intervals and retrieves a list of search queries from a data table.\n2. Each query is looped over in batches, and for each one, a POST request is sent to the Apify TikTok scraper API to fetch recent posts.\n3. The raw API results are sorted and scored using a custom ranking algorithm, then a final classification step is applied.\n4. The ranked results are saved back to a data table for storage and simultaneously sent out via Gmail as a message.\n5. After the email is sent, the loop continues to the next batch of queries until all are processed.\n\n### Setup steps\n\n- - [ ] Configure the **Reddit Schedule Trigger1** node with the desired run frequency (e.g., daily, hourly).\n- - [ ] Set up the **Reddit Get row(s)1** data table node with the correct table/sheet containing the list of queries to process.\n- - [ ] Add your Apify API key to the **Tiktok get posts solo1** HTTP Request node (POST to `https://api.apify.com/v2/acts/clockworks...`).\n- - [ ] Connect a Gmail account to the **Reddit Send a message1** node and configure the recipient, subject, and message body.\n- - [ ] Configure the **Reddot Push to data table1** node to point to the correct destination table where ranked results should be stored.\n- - [ ] Review and adjust the scoring logic in **Sort TikTok solo1** and **Classement Instagram** code nodes to match your ranking criteria.\n\n### Customization\n\nThe custom scoring formula in the `Sort TikTok solo1` and `Classement Instagram` code nodes can be adjusted to weight engagement metrics (likes, views, comments) differently. The batch size in `TikTok Loop Over Query1` can be tuned to control API request rate."
      },
      "typeVersion": 1
    },
    {
      "id": "38bf052a-7107-4293-bc86-b41d12948e83",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1024,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 320,
        "content": "## Schedule trigger and query fetch\n\nA schedule trigger initiates the workflow and retrieves the list of queries to process from a data table."
      },
      "typeVersion": 1
    },
    {
      "id": "bd69a5b9-7359-43a1-a2be-b42b85905e96",
      "name": "Sticky Note19",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1472,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 320,
        "content": "## Loop and fetch TikTok posts\n\nIterates over each query in batches and calls the Apify TikTok scraper API to retrieve recent posts for each query."
      },
      "typeVersion": 1
    },
    {
      "id": "871a466f-a25e-48b9-bbf3-2fdaf839a7d1",
      "name": "Sticky Note20",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1936,
        688
      ],
      "parameters": {
        "color": 7,
        "width": 384,
        "height": 320,
        "content": "## Sort and rank posts\n\nApplies a custom scoring algorithm to sort TikTok posts, then performs a final classification/ranking step on the results."
      },
      "typeVersion": 1
    },
    {
      "id": "1524197f-3624-42df-af14-de36d5f6d10d",
      "name": "Sticky Note23",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2352,
        512
      ],
      "parameters": {
        "color": 7,
        "height": 496,
        "content": "## Save results and notify\n\nStores the ranked results in a data table for persistence and sends the results via Gmail as a notification message."
      },
      "typeVersion": 1
    },
    {
      "id": "67f547d3-234b-48c4-a0e4-f22c68cddf50",
      "name": "Rank TikTok Posts1",
      "type": "n8n-nodes-base.code",
      "notes": "Sorts all posts + give them points depending on their likes + comments",
      "position": [
        2176,
        848
      ],
      "parameters": {
        "jsCode": "// Code pour n\u0153ud Code n8n - Classement TikTok\n// R\u00e9cup\u00e9rer le keyword dynamiquement\nconst keyword = $('Loop Over TikTok Queries').first().json.Query;\n\n// R\u00e9cup\u00e9rer les donn\u00e9es du n\u0153ud pr\u00e9c\u00e9dent\nconst tiktokData = $('Score and Sort TikTok Posts').all();\n\n// Fonction pour d\u00e9terminer le level bas\u00e9 sur le score\nfunction getLevel(score) {\n  if (score >= 10000) return 'High';\n  if (score >= 1000) return 'Medium';\n  return 'Low';\n}\n\n// Fonction pour extraire l'auteur TikTok\nfunction getAuthor(item) {\n  const tiktokMatch = item.url.match(/tiktok\\.com\\/@([^\\/]+)/);\n  return tiktokMatch ? `@${tiktokMatch[1]}` : '@inconnu';\n}\n\n// Transformer les donn\u00e9es TikTok\nconst tiktokPosts = tiktokData.map(item => ({\n  json: {\n    source: 'TikTok',\n    keyword: keyword,\n    author: getAuthor(item.json),\n    content: (item.json.caption || 'Pas de caption').substring(0, 50) + '...',\n    score: item.json.score,\n    level: getLevel(item.json.score),\n    url: item.json.url,\n    originalRank: item.json.rank\n  }\n}));\n\n// Trier par score d\u00e9croissant\nconst sortedPosts = tiktokPosts.sort((a, b) => b.json.score - a.json.score);\n\n// Ajouter le rang\nconst rankedPosts = sortedPosts.map((post, index) => ({\n  json: {\n    ...post.json,\n    rank: index + 1,\n    date: new Date().toISOString().split('T')[0]\n  }\n}));\n\n// Prendre le top 15\nconst topPosts = rankedPosts.slice(0, 15);\n\nreturn topPosts;"
      },
      "notesInFlow": true,
      "typeVersion": 2
    },
    {
      "id": "7ff09b4e-f990-4d7c-8496-40b6e0674642",
      "name": "Get Queries from Table1",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1264,
        848
      ],
      "parameters": {
        "operation": "get",
        "returnAll": true,
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "BYMzHVIbNU0mmvAZ",
          "cachedResultUrl": "/projects/oTpNUA7ZOCuhiQA0/datatables/BYMzHVIbNU0mmvAZ",
          "cachedResultName": "Query social media"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ab6b8fd2-5171-4273-8a0e-898a8558f009",
      "name": "Save Rankings to Table1",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        2400,
        720
      ],
      "parameters": {
        "columns": {
          "value": {
            "url": "={{ $json.url }}",
            "Date": "={{ $now.toISO() }}",
            "rank": "={{ $json.rank }}",
            "level": "={{ $json.level }}",
            "score": "={{ $json.score }}",
            "author": "={{ $json.author }}",
            "source": "={{ $json.source }}",
            "content": "={{ $json.content }}",
            "keyword": "={{ $json.keyword }}"
          },
          "schema": [
            {
              "id": "rank",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "rank",
              "defaultMatch": false
            },
            {
              "id": "keyword",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "keyword",
              "defaultMatch": false
            },
            {
              "id": "source",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "source",
              "defaultMatch": false
            },
            {
              "id": "author",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "author",
              "defaultMatch": false
            },
            {
              "id": "content",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "content",
              "defaultMatch": false
            },
            {
              "id": "score",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "score",
              "defaultMatch": false
            },
            {
              "id": "level",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "level",
              "defaultMatch": false
            },
            {
              "id": "url",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "url",
              "defaultMatch": false
            },
            {
              "id": "Date",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "75Jvx9ALCoEGcdwY",
          "cachedResultUrl": "/projects/oTpNUA7ZOCuhiQA0/datatables/75Jvx9ALCoEGcdwY",
          "cachedResultName": "Trend Social media"
        }
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Rank TikTok Posts1": {
      "main": [
        [
          {
            "node": "Send TikTok Report by Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Save Rankings to Table1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Schedule Triggers": {
      "main": [
        [
          {
            "node": "Get Queries from Table1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Queries from Table1": {
      "main": [
        [
          {
            "node": "Loop Over TikTok Queries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Scrape TikTok via Apify": {
      "main": [
        [
          {
            "node": "Score and Sort TikTok Posts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over TikTok Queries": {
      "main": [
        [],
        [
          {
            "node": "Scrape TikTok via Apify",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Score and Sort TikTok Posts": {
      "main": [
        [
          {
            "node": "Rank TikTok Posts1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send TikTok Report by Email": {
      "main": [
        [
          {
            "node": "Loop Over TikTok Queries",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}