Scheduler de publication MCP pour Twitter

Avancé

Ceci est unMiscellaneous, AI RAG, Multimodal AIworkflow d'automatisation du domainecontenant 16 nœuds.Utilise principalement des nœuds comme Code, Wait, MySql, Slack, Twitter. Analyse des tendances et publication automatisée de contenu Twitter avec OpenAI GPT et MCP

Prérequis
  • Informations de connexion à la base de données MySQL
  • Token Bot Slack ou URL Webhook
  • Informations d'identification Twitter API
  • Clé API OpenAI
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "8BcTtr8AdLgBa23S",
  "meta": {
    "instanceId": "9c51453afbec31d8209fd304a1a3e6af1fb4621ca939ac8364a6b6d4aeed48c1",
    "templateCredsSetupCompleted": true
  },
  "name": "twitter_mcp_post_scheduler",
  "tags": [],
  "nodes": [
    {
      "id": "dd350044-eff4-40b7-bbe8-aaf95d17e019",
      "name": "Formater les résultats 1",
      "type": "n8n-nodes-base.function",
      "position": [
        720,
        -128
      ],
      "parameters": {
        "functionCode": "// Get the raw array of names from the AI Agent\nlet arr = items[0].json.output;\n\n// If it's a stringified array, parse it\nif (typeof arr === 'string') {\n  arr = JSON.parse(arr);\n}\n\n// Ensure it's an array\nif (!Array.isArray(arr)) {\n  return [];\n}\n\n// Return one item per trend name\nreturn arr.map(name => ({ json: { name } }));\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b60238c7-03b5-4a5b-84ca-c01e2cd3af93",
      "name": "Boucler sur les éléments",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        896,
        144
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "deb12dad-4c08-4310-8dd2-46c1615eaaed",
      "name": "Agent IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1184,
        -112
      ],
      "parameters": {
        "text": "=You are an AI agent with access to ONE MCP server:\n- Twitter Search → aigeon-ai-twitter154.search_tweets\n\nINPUT (from workflow)\nTrend name: {{ $json.name }}\n\nGoal\nSearch recent tweets for the given trend name and produce a concise, brand-safe “why it’s trending” summary. Do not generate or request any images.\n\nRules\n- Make at most ONE tool call.\n- Use the INPUT trend name verbatim as the query (no expansions).\n- Focus on “why now” (current event, game, release, announcement, controversy, etc.).\n- Keep it readable for a general audience; no hashtags, emojis, or @usernames.\n- Include concrete details if available; do NOT fabricate.\n- If the input is empty after trimming, skip the tool call and return the JSON with a brief “unknown reason” summary.\n\nSteps\n1) CALL `aigeon-ai-twitter154.search_tweets` with the trend name as the query (recent timeframe).\n2) Synthesize a 1–2 sentence summary (≈30–60 words) explaining why it’s trending.\n\nOutput (STRICT)\nReturn ONLY this JSON object (no prose, no extra keys, no markdown fences):\n\n{\n  \"trend\": \"{{ $json.name }}\",\n  \"summary\": \"<your concise explanation in 30–60 words>\",\n  \"search_url\": \"https://x.com/search?q={{ encodeURIComponent($json.name) }}\",\n  \"image_url\": null,\n  \"image_prompt\": null,\n  \"aspect_ratio\": \"16:9\"\n}\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "2dff454b-a58a-4303-9e5b-dafd635250a7",
      "name": "Client MCP",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1328,
        304
      ],
      "parameters": {
        "endpointUrl": "https://amber.mcpreview.com/slug/aigeon-ai-twitter154",
        "authentication": "headerAuth",
        "serverTransport": "httpStreamable"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "DNAG7Ji5OdnS7oBi",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "862a8930-0f27-4e51-b662-c28b9240c5f7",
      "name": "Envoyer un message",
      "type": "n8n-nodes-base.slack",
      "position": [
        1680,
        -112
      ],
      "webhookId": "ae669a44-f283-42b3-9cea-6f0b0febe4da",
      "parameters": {
        "text": "={{ $json.output }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#mcp-hub-test"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "id": "CbAz3Qd1iNJhMuNj",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "427bb5ba-2ba0-4444-89ab-4488b3e874ce",
      "name": "Attendre",
      "type": "n8n-nodes-base.wait",
      "position": [
        2640,
        304
      ],
      "webhookId": "adf20b2f-acdc-49b1-96c5-7c57a18ea1cd",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "baa30922-1058-41d7-a394-cd1f1a9fb48a",
      "name": "OpenAI Modèle de chat",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1184,
        288
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5-mini",
          "cachedResultName": "gpt-5-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "Kca9177CPSlzNiHg",
          "name": "Cooper Openai"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bf43e456-b478-4038-a1b4-f2b05dddc5c6",
      "name": "Prétraitement d'agent IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        208,
        -128
      ],
      "parameters": {
        "text": "=You are an AI agent with access to ONE MCP server:\n- Twitter trends → get-trends-near-location\n\nINPUT from workflow\nEXCLUDE (JSON array of normalized forms): {{ JSON.stringify($json.exclude || []) }}\n\nPrimary goal\nReturn the most conversation-worthy U.S. trend. Cross-run suppression is handled in MySQL, but you must also avoid any trend whose normalized form appears in EXCLUDE.\n\nTask\n1) CALL `get-trends-near-location` with WOEID 23424977 (United States). The tool may return an array of items like:\n   { name, url, query, tweet_volume|null, ... }. Handle missing fields gracefully.\n\n2) Internally normalize names for comparison ONLY:\n   • lowercase  • strip leading “#”  • trim  • collapse spaces  • remove surrounding punctuation/symbols\n\n3) Filter out any item whose normalized form is present in EXCLUDE.\n\n4) Score remaining items by ENGAGEMENT POTENTIAL (not just tweet volume). Treat tweet_volume=null as UNKNOWN (do NOT treat as 0). Prefer:\n   • clear moments happening now (games, finals, premieres, elections, announcements, releases, controversies, breaking news)\n   • specific & recognizable entities over generic tags\n   • conversation-friendly, broad-interest communities\n   • distinct items (avoid near-duplicates)\n   • brand-safe topics (skip NSFW/harassment)\n\n   Heuristics (guidance, not rules):\n   • +3 specific event/entity signals (e.g., “Team A vs Team B”, “Finale”, “Kickoff”, “Trailer”, “Album”, “Box Office”)\n   • +2 strong recognizability (proper-noun phrases, league/team/celebrity names)\n   • +1 recency cues in top tweets (today/tonight/just announced) if visible via the search URL/metadata\n   • TIE-BREAKERS ONLY: when two candidates are otherwise close, prefer the one with a non-null tweet_volume; if both have volume, prefer the higher.\n\n   Exclude/penalize:\n   • overly generic tags (#news, #breaking), single emojis, day-of-week only, spammy promos.\n\n5) Select exactly ONE trend name with the highest overall score.\n   • If no viable item remains, return an empty list. Do NOT fabricate.\n\nOutput (STRICT)\nReturn ONLY a JSON array of strings with the final human-friendly name(s). No prose, counts, or extra fields.\nExample: [\"Cracker Barrel\"]\n",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 2.2
    },
    {
      "id": "45a35c06-c201-40a4-a058-c864afc3e8fb",
      "name": "OpenAI Modèle de chat 1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        176,
        128
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "id": "Kca9177CPSlzNiHg",
          "name": "Cooper Openai"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5715d5af-7b63-4e92-99a8-b0a87a2b3dcf",
      "name": "Client MCP 1",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        352,
        144
      ],
      "parameters": {
        "endpointUrl": "https://amber.mcpreview.com/slug/aigeon-ai-twitter154",
        "authentication": "headerAuth",
        "serverTransport": "httpStreamable"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "DNAG7Ji5OdnS7oBi",
          "name": "Header Auth account"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "c40a0864-3376-43db-bc02-46e3069e33a2",
      "name": "Exécuter une requête SQL",
      "type": "n8n-nodes-base.mySql",
      "position": [
        2144,
        -272
      ],
      "parameters": {
        "query": "INSERT INTO keyword_registry\n  (platform, locale, raw_keyword, canon, status, published_at, publish_payload, next_eligible_at)\nVALUES (\n  $1,                    -- platform\n  $2,                    -- locale\n  $3,                    -- raw_keyword (trend)\n  $4,                    -- canon\n  'published',\n  NOW(),\n  JSON_OBJECT(\n    'trend',        $3,\n    'summary',      $5,\n    'search_url',   $6,\n    'image_url',    NULL,\n    'image_prompt', NULL,\n    'aspect_ratio', COALESCE($7, '16:9'),\n    'slack', JSON_OBJECT(\n      'channel',            $8,\n      'ts',                 $9,\n      'message_timestamp',  $10\n    )\n  ),\n  DATE_ADD(NOW(), INTERVAL 3 DAY)\n)\nON DUPLICATE KEY UPDATE\n  last_seen        = CURRENT_TIMESTAMP,\n  status           = 'published',\n  published_at     = NOW(),\n  publish_payload  = VALUES(publish_payload),\n  next_eligible_at = DATE_ADD(NOW(), INTERVAL 3 DAY);\n",
        "options": {
          "queryReplacement": "={{ [\n  $json.platform || 'twitter',                 // $1\n  $json.locale   || 'US',                      // $2\n  $json.trend,\n  ($json.canon ??\n    String($json.trend || '')\n      .normalize('NFKC')\n      .toLowerCase()\n      .replace(/^#+/, '')\n      .replace(/\\s+/g, ' ')\n      .trim()\n  ),                                           // $4 (canon)\n  $json.summary,                               // $5\n  $json.search_url,                            // $6\n  $json.aspect_ratio || '16:9',                // $7\n  ($json.channel ?? $json.message?.channel),   // $8\n  ($json.message?.ts ?? $json.ts ?? null),     // $9\n  ($json.message_timestamp ?? null)            // $10\n] }}\n"
        },
        "operation": "executeQuery"
      },
      "credentials": {
        "mySql": {
          "id": "kqvrRLnX254pfQhm",
          "name": "MySQL account"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "9209ade7-5c70-452d-a832-9770a0691038",
      "name": "Exécuter une requête SQL 1",
      "type": "n8n-nodes-base.mySql",
      "position": [
        -48,
        -112
      ],
      "parameters": {
        "query": "SELECT\n  CAST(CONCAT(\n        '[',\n        IFNULL(GROUP_CONCAT(JSON_QUOTE(canon)\n                ORDER BY published_at DESC\n                SEPARATOR ','), ''),\n        ']'\n      ) AS JSON) AS exclude\nFROM (\n  SELECT canon, published_at\n  FROM keyword_registry\n  WHERE platform = $1\n    AND locale   = $2\n    AND status   = 'published'\n    AND next_eligible_at > NOW()   -- still in the 3-day window\n  ORDER BY published_at DESC\n  LIMIT 30\n) AS t;\n",
        "options": {
          "queryReplacement": "={{ [ 'twitter', 'US' ] }}"
        },
        "operation": "executeQuery"
      },
      "credentials": {
        "mySql": {
          "id": "kqvrRLnX254pfQhm",
          "name": "MySQL account"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "b891d9e0-1501-46b2-8a5f-17997b65eae6",
      "name": "Déclencheur planifié",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -352,
        -128
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 2,
              "triggerAtMinute": 12
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "bd1341ee-dcd6-45cb-9b43-f986be70634f",
      "name": "Attendre 1",
      "type": "n8n-nodes-base.wait",
      "position": [
        2080,
        -736
      ],
      "webhookId": "0c0a6cd3-b2cd-4ea7-85ba-3b38f901c572",
      "parameters": {},
      "typeVersion": 1.1
    },
    {
      "id": "903b774d-3b3a-4a24-b3fb-ae1e5a668f13",
      "name": "Créer un Tweet",
      "type": "n8n-nodes-base.twitter",
      "position": [
        2864,
        -192
      ],
      "parameters": {
        "text": "={{ $json.trend }}: {{ $json.summary }}",
        "additionalFields": {}
      },
      "credentials": {
        "twitterOAuth2Api": {
          "id": "X7FXukmqV03ghtzN",
          "name": "X account Ella.m@newsbreak.com"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "d8411ea5-95c6-4c76-8af8-f35d279c84cb",
      "name": "Formateur de mots-clés",
      "type": "n8n-nodes-base.code",
      "position": [
        1504,
        -480
      ],
      "parameters": {
        "jsCode": "let o = $json.output;\nif (typeof o === 'string') {\n  try { o = JSON.parse(o); } catch { o = {}; }\n}\nconst trend = o.trend ?? '';\nconst canon = trend\n  .normalize('NFKC')\n  .toLowerCase()\n  .replace(/^#+/,'')\n  .replace(/\\s+/g,' ')\n  .trim();\n\nreturn [{\n  json: {\n    platform: 'twitter',\n    locale: 'US',\n    ...o,            // trend, summary, search_url, etc.\n    canon\n  }\n}];\n"
      },
      "typeVersion": 2
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f87d8268-70b1-4e5b-9111-c280b354b3b8",
  "connections": {
    "427bb5ba-2ba0-4444-89ab-4488b3e874ce": {
      "main": [
        []
      ]
    },
    "bd1341ee-dcd6-45cb-9b43-f986be70634f": {
      "main": [
        [
          {
            "node": "903b774d-3b3a-4a24-b3fb-ae1e5a668f13",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "deb12dad-4c08-4310-8dd2-46c1615eaaed": {
      "main": [
        [
          {
            "node": "862a8930-0f27-4e51-b662-c28b9240c5f7",
            "type": "main",
            "index": 0
          },
          {
            "node": "d8411ea5-95c6-4c76-8af8-f35d279c84cb",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2dff454b-a58a-4303-9e5b-dafd635250a7": {
      "ai_tool": [
        [
          {
            "node": "deb12dad-4c08-4310-8dd2-46c1615eaaed",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "5715d5af-7b63-4e92-99a8-b0a87a2b3dcf": {
      "ai_tool": [
        [
          {
            "node": "bf43e456-b478-4038-a1b4-f2b05dddc5c6",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "903b774d-3b3a-4a24-b3fb-ae1e5a668f13": {
      "main": [
        [
          {
            "node": "427bb5ba-2ba0-4444-89ab-4488b3e874ce",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "862a8930-0f27-4e51-b662-c28b9240c5f7": {
      "main": [
        [
          {
            "node": "427bb5ba-2ba0-4444-89ab-4488b3e874ce",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dd350044-eff4-40b7-bbe8-aaf95d17e019": {
      "main": [
        [
          {
            "node": "b60238c7-03b5-4a5b-84ca-c01e2cd3af93",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b60238c7-03b5-4a5b-84ca-c01e2cd3af93": {
      "main": [
        [],
        [
          {
            "node": "deb12dad-4c08-4310-8dd2-46c1615eaaed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b891d9e0-1501-46b2-8a5f-17997b65eae6": {
      "main": [
        [
          {
            "node": "9209ade7-5c70-452d-a832-9770a0691038",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "baa30922-1058-41d7-a394-cd1f1a9fb48a": {
      "ai_languageModel": [
        [
          {
            "node": "deb12dad-4c08-4310-8dd2-46c1615eaaed",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "d8411ea5-95c6-4c76-8af8-f35d279c84cb": {
      "main": [
        [
          {
            "node": "bd1341ee-dcd6-45cb-9b43-f986be70634f",
            "type": "main",
            "index": 0
          },
          {
            "node": "c40a0864-3376-43db-bc02-46e3069e33a2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "45a35c06-c201-40a4-a058-c864afc3e8fb": {
      "ai_languageModel": [
        [
          {
            "node": "bf43e456-b478-4038-a1b4-f2b05dddc5c6",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "bf43e456-b478-4038-a1b4-f2b05dddc5c6": {
      "main": [
        [
          {
            "node": "dd350044-eff4-40b7-bbe8-aaf95d17e019",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c40a0864-3376-43db-bc02-46e3069e33a2": {
      "main": [
        [
          {
            "node": "427bb5ba-2ba0-4444-89ab-4488b3e874ce",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9209ade7-5c70-452d-a832-9770a0691038": {
      "main": [
        [
          {
            "node": "bf43e456-b478-4038-a1b4-f2b05dddc5c6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - Divers, RAG IA, IA Multimodale

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds16
Catégorie3
Types de nœuds11
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
Dayong Huang

Dayong Huang

@dayonghuang

Developer of mcphub.com. Use mcp to automate LLM tool call!

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34