Modèle GiggleGPTBot

Avancé

Ceci est unAI Chatbot, Multimodal AIworkflow d'automatisation du domainecontenant 27 nœuds.Utilise principalement des nœuds comme If, Code, Switch, Postgres, Telegram. Utiliser OpenRouter pour créer un robot Telegram spirituel avec humour, taquinerie et statistiques alimentées par l'IA

Prérequis
  • Informations de connexion à la base de données PostgreSQL
  • Token Bot Telegram
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": "TfKEOWRNsYI093kR",
  "meta": {
    "instanceId": "673dd365761c86615255caaaae908ad0f2b40ed6e6f64e1be5631254544e65ca"
  },
  "name": "GiggleGPTBot Template",
  "tags": [],
  "nodes": [
    {
      "id": "c4dbddca-9165-401f-9a96-995a958a425a",
      "name": "Webhook Telegram",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        -1136,
        64
      ],
      "webhookId": "3cb5a3b8-5bae-4708-be95-172a7d50cb48",
      "parameters": {
        "updates": [
          "*"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "id": "GNUE3W3kc9bGnXyL",
          "name": "GiggleGPTBot"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5369e144-45cd-4a99-9fa6-284ae24ec585",
      "name": "Commandes OpenRouter",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        -512,
        736
      ],
      "parameters": {
        "model": "openai/gpt-oss-120b",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "id": "ONSHmBroionT6JFr",
          "name": "OpenRouter account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5ee25a3f-a9c7-4994-a9a9-315b9eeec5af",
      "name": "Initialiser Base de Données",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -1248,
        -128
      ],
      "parameters": {
        "query": "CREATE TABLE IF NOT EXISTS user_messages (\n  id SERIAL PRIMARY KEY,\n  user_id BIGINT NOT NULL,\n  username VARCHAR(255),\n  first_name VARCHAR(255),\n  chat_id BIGINT NOT NULL,\n  message_text TEXT,\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE IF NOT EXISTS bot_responses (\n  id SERIAL PRIMARY KEY,\n  user_id BIGINT NOT NULL,\n  chat_id BIGINT NOT NULL,\n  user_message TEXT,\n  bot_response TEXT,\n  response_type VARCHAR(50),\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE IF NOT EXISTS bot_commands (\n  id SERIAL PRIMARY KEY,\n  user_id BIGINT NOT NULL,\n  chat_id BIGINT NOT NULL,\n  command VARCHAR(50) NOT NULL,\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE IF NOT EXISTS message_reactions (\n  id SERIAL PRIMARY KEY,\n  message_id BIGINT NOT NULL,\n  chat_id BIGINT NOT NULL,\n  user_id BIGINT NOT NULL,\n  emoji VARCHAR(10),\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE IF NOT EXISTS scheduled_posts (\n  id SERIAL PRIMARY KEY,\n  chat_id BIGINT NOT NULL,\n  message_text TEXT,\n  post_type VARCHAR(50),\n  scheduled_time TIME,\n  is_active BOOLEAN DEFAULT true,\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n\nCREATE TABLE user_stats (\n  user_id BIGINT NOT NULL,\n  chat_id BIGINT NOT NULL,\n  messages_count INT DEFAULT 0,\n  commands_count INT DEFAULT 0,\n  reactions_received INT DEFAULT 0,\n  last_activity TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (user_id, chat_id)\n);\n\nCREATE INDEX IF NOT EXISTS idx_user_messages_chat_user ON user_messages(chat_id, user_id);\nCREATE INDEX IF NOT EXISTS idx_bot_responses_chat_user ON bot_responses(chat_id, user_id);\nCREATE INDEX IF NOT EXISTS idx_commands_user ON bot_commands(user_id, command);\nCREATE INDEX IF NOT EXISTS idx_reactions_message ON message_reactions(message_id);\nCREATE INDEX idx_user_stats_activity ON user_stats(last_activity DESC);\nCREATE INDEX idx_user_stats_messages ON user_stats(messages_count DESC);\n",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "2f7789fd-645c-436f-91ef-04cb2143aa7d",
      "name": "Journaliser message + statistiques",
      "type": "n8n-nodes-base.postgres",
      "onError": "continueRegularOutput",
      "position": [
        -960,
        -192
      ],
      "parameters": {
        "query": "INSERT INTO user_messages (user_id, username, first_name, chat_id, message_text) \nVALUES ({{ $('Webhook Telegram').item.json.message.from.id }}, \n        '{{ ($('Webhook Telegram').item.json.message.from.username || '').replace(/'/g, \"''\") }}', \n        '{{ ($('Webhook Telegram').item.json.message.from.first_name || '').replace(/'/g, \"''\") }}', \n        {{ $('Webhook Telegram').item.json.message.chat.id }}, \n        '{{ ($('Webhook Telegram').item.json.message.text || '').replace(/'/g, \"''\") }}');\n\nINSERT INTO user_stats (user_id, chat_id, messages_count, last_activity)\nVALUES ({{ $('Webhook Telegram').item.json.message.from.id }}, \n        {{ $('Webhook Telegram').item.json.message.chat.id }}, \n        1, CURRENT_TIMESTAMP)\nON CONFLICT (user_id, chat_id) \nDO UPDATE SET \n  messages_count = user_stats.messages_count + 1,\n  last_activity = CURRENT_TIMESTAMP;",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "5676c8d7-a456-4f12-be6a-2cd5c2ec41e6",
      "name": "Ajouter une planification",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -1120,
        400
      ],
      "parameters": {
        "query": "INSERT INTO scheduled_posts (chat_id, post_type, scheduled_time) VALUES\n(-1002837353897, 'morning_joke', '06:00:00'),\n(-1002837353897, 'random_wisdom', '17:00:00'),\n(-1002837353897, 'daily_motivation', '09:00:00');",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "5b7c3300-fa5a-43f5-881f-db48314be81c",
      "name": "Planification",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -992,
        544
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 * * * *"
            }
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "756e467d-835a-4166-8972-4edf50b0007f",
      "name": "Obtenir publications planifiées",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -800,
        544
      ],
      "parameters": {
        "query": "SELECT chat_id, post_type \nFROM scheduled_posts \nWHERE is_active = true \nAND EXTRACT(HOUR FROM scheduled_time) = EXTRACT(HOUR FROM CURRENT_TIME);",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "84247455-9eed-424d-8ee4-84ece8f10d54",
      "name": "Historique de chat",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -768,
        -96
      ],
      "parameters": {
        "query": "SELECT \n  message_text,\n  username,\n  first_name,\n  created_at,\n  'user' as message_type\nFROM user_messages \nWHERE chat_id = {{ $('Webhook Telegram').item.json.message.chat.id }}\n\nUNION ALL\n\nSELECT \n  bot_response as message_text,\n  'GiggleGPTBot' as username,\n  'GiggleGPTBot' as first_name,\n  created_at,\n  'bot' as message_type\nFROM bot_responses \nWHERE chat_id = {{ $('Webhook Telegram').item.json.message.chat.id }}\n\nORDER BY created_at DESC \nLIMIT 15;",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "86872198-4d19-4c3e-b5dd-14dda87a9139",
      "name": "Analyse de Mention",
      "type": "n8n-nodes-base.code",
      "position": [
        -592,
        -96
      ],
      "parameters": {
        "jsCode": "const telegramData = $('Webhook Telegram').first().json;\nconst chatHistory = $('Chat history').all();\n\nconst userId = telegramData.message.from.id;\nconst userName = telegramData.message.from.first_name || telegramData.message.from.username || 'Anonymous';\nlet userMessage = telegramData.message.text;\nconst chatId = telegramData.message.chat.id;\n\nconst commandMatch = userMessage.match(/^\\/(\\w+)(?:@\\w+)?(?:\\s+(.*))?/);\nconst command = commandMatch ? commandMatch[1].toLowerCase() : '';\n\nconst originalMessage = userMessage;\nuserMessage = userMessage.replace(/@GiggleGPTBot/gi, '').trim();\nconst isEmptyAfterTag = !userMessage || userMessage.length === 0;\n\nconst recentMessages = chatHistory.map(item => {\n  const msgText = item.json.message_text || '';\n  const author = item.json.message_type === 'bot' ? 'GiggleGPTBot' : \n                 (item.json.first_name || item.json.username || 'Anonymous');\n  return `${author}: ${msgText}`;\n}).slice(0, 15).join('\\n'); \n\nlet contentType = 'mixed';\nconst lowerMessage = userMessage.toLowerCase();\nif (lowerMessage.includes('joke') || lowerMessage.includes('funny')) {\n  contentType = 'funny';\n} else if (lowerMessage.includes('motivat') || lowerMessage.includes('motivat')) {\n  contentType = 'inspiring';\n}\n\nif (isEmptyAfterTag) {\n  const types = ['funny', 'inspiring', 'mixed'];\n  contentType = types[Math.floor(Math.random() * types.length)];\n}\n\nconst now = new Date();\nconst hour = now.getHours();\nlet timeContext = '';\nif (hour < 6) timeContext = 'night';\nelse if (hour < 12) timeContext = 'morning';\nelse if (hour < 18) timeContext = 'day';\nelse timeContext = 'evening';\n\nreturn [{\n  json: {\n    userId,\n    userName,\n    userMessage: isEmptyAfterTag ? 'Random phrase' : userMessage,\n    originalMessage,\n    chatId,\n    contentType,\n    command,\n    timeContext,\n    recentMessages,\n    chatType: telegramData.message.chat.type,\n    isRandomRequest: isEmptyAfterTag\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "60de834b-47c8-428a-9d28-87ade8fa8a43",
      "name": "Obtenir statistiques utilisateur",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -768,
        64
      ],
      "parameters": {
        "query": "SELECT \n  us.user_id,\n  us.messages_count,\n  us.commands_count,\n  0 as reactions_received,\n  us.last_activity,\n  (SELECT COUNT(*) FROM bot_responses br WHERE br.user_id = us.user_id AND br.chat_id = us.chat_id) as responses_count\nFROM user_stats us\nWHERE us.chat_id = {{ $json.message.chat.id }}\n  AND us.user_id = {{ $json.message.from.id }}\nLIMIT 1;",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "d57380bc-5dc5-4130-a767-463bbf81931c",
      "name": "Obtenir top utilisateurs",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -768,
        224
      ],
      "parameters": {
        "query": "SELECT \n  us.messages_count,\n  us.commands_count,\n  CONCAT(\n    COALESCE((SELECT first_name FROM user_messages WHERE user_id = us.user_id LIMIT 1), 'User'),\n    ' (@',\n    COALESCE((SELECT username FROM user_messages WHERE user_id = us.user_id LIMIT 1), 'no_username'),\n    ')'\n  ) as user_name\nFROM user_stats us\nWHERE us.chat_id = {{ $json.message.from.id }}\n  AND us.messages_count > 0\nORDER BY (us.messages_count + us.commands_count * 2) DESC\nLIMIT 10;",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b12f28fc-6fb0-45ca-8348-202bf5a78332",
      "name": "Réponse IA à commande",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 2,
      "position": [
        -240,
        -80
      ],
      "parameters": {
        "text": "=Command: /{{ $json.command }}\nUser: {{ $json.userName }}\nChat context: {{ $json.recentMessages }}\nTime: {{ $json.timeContext }}\n\nGenerate {{ $json.command === 'joke' ? 'a witty joke' : $json.command === 'inspire' ? 'a motivating line' : $json.command === 'roast' ? 'a sharp roast with folksy sarcasm' : 'a random interesting line' }} in your signature style with subtle humor and playful teasing.\n",
        "options": {
          "systemMessage": "You are GiggleGPTBot — a witty bot with a big heart. Your job: deliver short humor and folksy wisdom with light irony.\n\nStyle:\n• Modern spin on proverbs and sayings.\n• Gentle irony and kind subtext.\n• Emojis: allowed but sparing (0–2 per reply).\n\nAvoid:\n• Crudeness, profanity, cliché \"Soviet-style\" advice.\n• Rambling, long, or confusing imagery.\n• Explaining the joke or meta-notes about the prompt.\n\nReply format:\n• Strictly 1–2 sentences (3 only in rare cases).\n• One clear idea or joke.\n• At most one simple metaphor.\n• Must be easily understood at first read.\n\nCommands:\n/joke — clever short joke with light irony.\n/inspire — gentle, smiley motivation (no pomp).\n/random — unexpected witty line in folksy wisdom style.\n/roast — sharp roast with sarcastic tone. Some edge allowed, mild profanity ok, but NO insults targeting gender, race, nationality, or other protected traits.\n\nExamples:\n/joke → My neighbor runs every morning. I run too… my eyes over the bus schedule 🚌.\n/inspire → Even a snail has a goal — and you’ve got legs that are faster 🐌➡️🏃‍♂️.\n/random → Sometimes the kettle boils longer than love… yet both return to warmth ☕❤️.\n/roast → “Your alarm screams like it’s got a mortgage. You? Just laziness and snoring — also on credit 😏”.\n\nSelf-check before sending:\n• Did I stay within 1–2 sentences?\n• Is there light irony or a clear joke/wisdom?\n• Is it instantly clear to a regular person?\n• No extra fluff, confusion, or weird imagery?\n\nIf not, shorten and rewrite to a simple, clear, witty reply."
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "e1345b2b-f824-40cb-b01d-48031d417b1b",
      "name": "Générer une réponse informationnelle",
      "type": "n8n-nodes-base.code",
      "position": [
        -576,
        144
      ],
      "parameters": {
        "jsCode": "const messageText = $('Webhook Telegram').first().json.message.text\nconst commandMatch = messageText.match(/^\\/(\\w+)(?:@\\w+)?(?:\\s+(.*))?/);\nconst commandData = commandMatch ? commandMatch[1].toLowerCase() : '';\n\nconst safe = (v, d = '') => (v === null || v === undefined ? d : v);\n\nlet userStatsItem;\ntry {\n  userStatsItem = $input.first();\n} catch (_) {\n  userStatsItem = undefined;\n}\n\nlet topUsersItems = [];\ntry {\n  const topNode = $('Get top users');\n  if (topNode && typeof topNode.all === 'function') {\n    const raw = topNode.all() || [];\n    topUsersItems = raw\n      .map(i => (i && i.json) ? i.json : null)\n      .filter(Boolean);\n  }\n} catch (error) {\n  console.log('Top users unavailable:', error.message);\n}\n\nconst userId = safe($('Webhook Telegram').first().json.message.from.id);\nconst userName = safe($('Webhook Telegram').first().json.message.chat.first_name, 'User');\nconst chatId = safe($('Webhook Telegram').first().json.message.chat.id);\nconst command = safe(commandData, '');\n\nlet responseText = '';\n\nconst formatDateRu = (iso) => {\n  try {\n    const d = new Date(iso);\n    if (isNaN(d.getTime())) return 'Unknown';\n    return d.toLocaleString('en-US', { dateStyle: 'short', timeStyle: 'short' });\n  } catch {\n    return 'Unknown';\n  }\n};\n\nconst calcActivity = (u) => {\n  const msgs = Number(u.messages_count || 0);\n  const cmds = Number(u.commands_count || 0);\n  return msgs + cmds * 2;\n};\n\nswitch (command) {\n  case 'stats': {\n    if (userStatsItem && userStatsItem.json) {\n      const s = userStatsItem.json;\n      responseText =\n        `📊 Statistics ${userName}:\\n` +\n        `💬 Messages: ${Number(s.messages_count || 0)}\\n` +\n        `⚡ Commands: ${Number(s.commands_count || 0)}\\n` +\n        `📅 Last activity: ${s.last_activity ? formatDateRu(s.last_activity) : 'Unknown'}`;\n    } else {\n      responseText =\n        `📊 Statistics ${userName}:\\n` +\n        `There is no data yet. Keep chatting and the statistics will appear! 💬`;\n    }\n    break;\n  }\n\n  case 'top': {\n    if (topUsersItems.length > 0) {\n      const sorted = [...topUsersItems]\n        .sort((a, b) => calcActivity(b) - calcActivity(a))\n        .slice(0, 10);\n\n      const lines = sorted.map((u, idx) => {\n        const uname = u.user_name || 'User';\n        const msgs = Number(u.messages_count || 0);\n        const cmds = Number(u.commands_count || 0);\n        const total = calcActivity(u);\n        return `${idx + 1}. ${uname}\\n   💬 ${msgs} messages, ⚡ ${cmds} commands\\n 📊 Activity: ${total} points`;\n      });\n\n      responseText = '🏆 Top Active Users:\\n\\n' + lines.join('\\n\\n');\n    } else {\n      responseText =\n        '🏆 Top Active Users:\\n\\n' +\n        'There are no active users in this chat yet. Be the first! 🚀';\n    }\n    break;\n  }\n\n  case 'help': {\n    responseText =\n      '🤖 GiggleGPTBot commands:\\n\\n' +\n      '😄 /joke — funny joke\\n' +\n      '💪 /inspire — motivation\\n' +\n      '🎲 /random — random phrase\\n' +\n      '🔥 /roast — harsh joke with sarcasm (without insults based on prohibited characteristics)\\n' +\n      '📊 /stats — your statistics\\n' +\n      '🏆 /top — top users\\n' +\n      '❓ /help — this help\\n\\n' +\n      'You can also write @GiggleGPTBot + text — I will answer personally.';\n    break;\n  }\n\n  case 'joke':\n  case 'inspire':\n  case 'random':\n  case 'roast': {\n    responseText =\n      'This command generates a content response and is processed by another node. ' +\n      'Try again - or use /help for a list of available info commands.';\n    break;\n  }\n\n  default: {\n    responseText = 'Unknown command 🤔 Use /help for a list of commands.';\n  }\n}\n\nreturn [{\n  json: {\n    userId,\n    userName,\n    chatId,\n    command,\n    responseText,\n    isInfoCommand: true\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "bf1fd22f-7df0-4891-82b0-6fd1ed3648dd",
      "name": "Type de réponse",
      "type": "n8n-nodes-base.if",
      "position": [
        80,
        112
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "condition1",
              "operator": {
                "type": "boolean",
                "operation": "equal",
                "singleValue": true
              },
              "leftValue": "={{ $json.isInfoCommand }}",
              "rightValue": true
            },
            {
              "id": "78352c71-3779-4ba9-afb7-1e836a019a24",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.responseText }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "6698db5c-408d-43ac-b4b8-edbb7a3ac367",
      "name": "Envoyer réponse info",
      "type": "n8n-nodes-base.telegram",
      "position": [
        272,
        32
      ],
      "webhookId": "20b4671b-ebf4-4562-b40b-c3eba533ab60",
      "parameters": {
        "text": "={{ $json.responseText }}",
        "chatId": "={{ $json.chatId }}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "GNUE3W3kc9bGnXyL",
          "name": "GiggleGPTBot"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a95f6638-4406-4aab-8088-5d86125eedbf",
      "name": "Envoyer réponse IA",
      "type": "n8n-nodes-base.telegram",
      "position": [
        272,
        208
      ],
      "webhookId": "0c3d1f52-87ed-48f4-a056-31beab8dcaf3",
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $('If1').item.json.chatId }}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "GNUE3W3kc9bGnXyL",
          "name": "GiggleGPTBot"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2fc342ba-3372-4e85-91ac-be6cea8b66ae",
      "name": "Réponse IA à mention",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 2,
      "position": [
        -240,
        -288
      ],
      "parameters": {
        "text": "=User: {{ $json.userName }}\n{{ $json.isRandomRequest ? 'Mentioned the bot without text' : 'Message: \"' + $json.userMessage + '\"' }}\n\nChat context:\n{{ $json.recentMessages }}\n\nTime: {{ $json.timeContext }} | Style: {{ $json.contentType }}\n\n{{ $json.isRandomRequest ? 'Make a witty remark about the chat situation.' : 'Reply to the message with subtle humor.' }}\n\nBe witty and tactful! 🎭\n",
        "options": {
          "systemMessage": "You are GiggleGPTBot — a witty bot with subtle humor and a big heart. Be concise and to the point.\n\nStyle:\n• Modern spin on proverbs and sayings.\n• References to classics and folksy wisdom.\n• Soft irony with kind subtext.\n• Emojis: allowed but sparing (0–2 per reply).\n\nAvoid:\n• Crudeness, profanity, tired clichés.\n• Long, tangled, or meaningless phrases.\n• Surreal poetry or explaining your own jokes.\n\nFormat:\n• Max 1–2 sentences (3 only in rare cases).\n• One clear idea or joke.\n• At most one simple metaphor.\n• Do not repeat the user’s text; no digressions.\n\nBehavior by situation:\n• Question — answer the gist in one sentence, add a light ironic note in the second.\n• Joy/success — brief congrats; “what’s characteristic” can be used for charm.\n• Complaint/anxiety — tactful support and gentle hope, no moralizing.\n• User tells a joke — reply with a friendly counter-joke.\n• If a name is mentioned — address them by name.\n\nSelf-check before sending:\n• Did I stay within 1–2 sentences?\n• Is there light irony or clear wisdom?\n• Is it clear at first read, no fluff?\n• ≤1 metaphor, ≤2 emojis, ≤2 signature words?\n\nIf not, shorten and rewrite to a simple, clear, witty reply."
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "alwaysOutputData": false
    },
    {
      "id": "c343e37c-9fe6-47d5-bae3-b1524d766243",
      "name": "Répondre à Mention",
      "type": "n8n-nodes-base.telegram",
      "position": [
        80,
        -288
      ],
      "webhookId": "f77cfa99-a956-4c47-b4ff-41c3267b2505",
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $('Mention Analysis').item.json.chatId }}",
        "additionalFields": {
          "parse_mode": "HTML",
          "reply_to_message_id": "={{ $('Webhook Telegram').first().json.message.message_id }}"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "GNUE3W3kc9bGnXyL",
          "name": "GiggleGPTBot"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d581be16-af5f-48bf-bfe2-9a66cf96612f",
      "name": "Génération de publication IA",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "maxTries": 2,
      "position": [
        -416,
        528
      ],
      "parameters": {
        "text": "=Post type: {{ $json.post_type }}\n\nGenerate {{ $json.post_type === 'morning_joke' ? 'a morning joke' : $json.post_type === 'daily_motivation' ? 'daily motivation' : 'a piece of random wisdom' }} in your style with subtle humor.\n",
        "options": {
          "systemMessage": "IMPORTANT: Respond with PLAIN TEXT ONLY!\nDo NOT use asterisks, underscores, fancy quotes, or formatting symbols.\n\nYou are GiggleGPTBot — a witty storyteller creating short, warm posts.\n\nTopics:\nmorning_joke: morning jokes with kind subtext\ndaily_motivation: day-starter motivation with gentle irony\nrandom_wisdom: everyday observations in an “isn’t that true!” tone\n\nBehavior by topic:\nmorning_joke — one joke and a short warm finish\ndaily_motivation — one clear thesis and a gentle call to action\nrandom_wisdom — an observation and a simple takeaway\n\nStyle:\n• Concise like Chekhov: max 2–3 sentences (prefer 2)\n• Folksy wisdom in a modern spin\n• Intelligent humor with kind subtext\n• Emojis allowed sparingly: 0–2 per post\n• Max one simple metaphor\n\nAvoid:\n• Crudeness, profanity, cliché “Soviet-style” advice\n• Long, tangled, or surreal imagery\n• Hashtags, links, lists, or explaining your own jokes\n\nSelf-check before sending:\n• Within 2–3 sentences?\n• Light irony or clear joke/wisdom?\n• Clear at first read for a general audience?\n• No fluff or confusion?\n\nIf not, shorten and rewrite to a simple, clear, friendly post."
        },
        "promptType": "define"
      },
      "retryOnFail": true,
      "typeVersion": 2
    },
    {
      "id": "06b1468d-5af7-46e9-8e50-ec6a3c49d895",
      "name": "Soumettre publication planifiée",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -112,
        528
      ],
      "webhookId": "d17bb041-f75d-427a-9529-d93f39a51723",
      "parameters": {
        "text": "={{ $json.output }}",
        "chatId": "={{ $('Get scheduled posts').item.json.chat_id }}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "credentials": {
        "telegramApi": {
          "id": "GNUE3W3kc9bGnXyL",
          "name": "GiggleGPTBot"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c538c3eb-0ce6-4f34-80fb-b6668a9fe549",
      "name": "Sauvegarder Réponse Bot",
      "type": "n8n-nodes-base.postgres",
      "position": [
        80,
        -112
      ],
      "parameters": {
        "query": "INSERT INTO bot_responses (user_id, chat_id, user_message, bot_response, response_type) \nVALUES ({{ $('Mention Analysis').item.json.userId }}, \n        {{ $('Mention Analysis').item.json.chatId }}, \n        '{{ $('Mention Analysis').item.json.originalMessage.replace(/'/g, \"''\") }}', \n        '{{ $json.output.replace(/'/g, \"''\") }}', \n        '{{ $('Mention Analysis').item.json.contentType }}');",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "f78d3e69-c2ba-4640-921a-e3bb52988416",
      "name": "Si",
      "type": "n8n-nodes-base.if",
      "position": [
        -624,
        544
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e1310a96-8c67-467e-b50d-fee95851424c",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.chat_id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "8afe12f7-ef5b-4b89-8b08-623024c97b3c",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        -960,
        -32
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "joke",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "1b2506b4-5b0b-48cb-bb27-5684c9bcbd88",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/joke"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "inspire",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6362199a-67f8-47c2-a845-3088f33c3338",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/inspire"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "random",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "f883e421-2f6e-490b-ae2c-9952c5083d2c",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/random"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "roast",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3d6557c4-2eab-4545-af30-3b4848c424fb",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/roast"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "GiggleGPTBot",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "69fbe825-df4d-44c5-85eb-5d69e0f17896",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "@GiggleGPTBot"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "stats",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ac0a71e3-8793-4c32-a5f9-bec6055c04d7",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/stats"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "help",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "062c9bd8-d63d-4c22-9097-8499b04ebc13",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/help"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "top",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ceb18c82-23d7-411d-8a48-c212ea7add91",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $json.message?.text }}",
                    "rightValue": "/top"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "76628b1a-4f38-4e8b-be27-adf5cf078b83",
      "name": "Journaliser commande",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -384,
        64
      ],
      "parameters": {
        "query": "INSERT INTO bot_commands (user_id, chat_id, command) \nVALUES ({{ $json.userId }}, {{ $json.chatId }}, '{{ $json.userMessage.replace(/'/g, \"''\") }}');\n\nUPDATE user_stats \nSET commands_count = commands_count + 1 \nWHERE user_id = {{ $json.userId }} AND chat_id = {{ $json.chatId }};",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "197cb78b-ff9b-46d3-93ca-ff708d45d36d",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        -416,
        -96
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "39d5e005-69f7-4e27-ad73-e00b7a694a4e",
              "operator": {
                "type": "string",
                "operation": "startsWith"
              },
              "leftValue": "={{ $json.originalMessage }}",
              "rightValue": "@GiggleGPTBot"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cd2ae05c-a673-4b30-82fd-9c003610799a",
      "name": "Sauvegarder Réponse Bot2",
      "type": "n8n-nodes-base.postgres",
      "position": [
        -112,
        352
      ],
      "parameters": {
        "query": "INSERT INTO bot_responses (user_id, chat_id, user_message, bot_response, response_type) \nVALUES (0,\n        {{ $('Get scheduled posts').item.json.chat_id }}, \n        'Scheduled post', \n        '{{ $json.output.replace(/'/g, \"''\") }}', \n        '{{ $('Get scheduled posts').item.json.post_type }}');",
        "options": {},
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "Fd7RaI9MHHQBq9hE",
          "name": "Supabase Postgres"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "f66c1418-8664-416b-8e0b-08ed120bb64e",
      "name": "Note adhésive2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2064,
        -416
      ],
      "parameters": {
        "color": 5,
        "width": 700,
        "height": 2844,
        "content": "# GiggleGPTBot — Witty Telegram Bot with AI & Postgres\n\n## 📝 Overview\n\nGiggleGPTBot is a witty Telegram bot built with **n8n**, **OpenRouter**, and **Postgres**.\nIt delivers short jokes, motivational one-liners, and playful roasts, responds to mentions, and posts scheduled witty content.\nThe workflow also tracks user activity and provides lightweight statistics and leaderboards.\n\n---\n\n## ✨ Features\n\n* 🤖 **AI-powered humor engine** — replies with jokes, motivation, random witty lines, or sarcastic roasts.\n* 💬 **Command support** — `/joke`, `/inspire`, `/random`, `/roast`, `/help`, `/stats`, `/top`.\n* 🎯 **Mention detection** — replies when users tag `@GiggleGPTBot`.\n* ⏰ **Scheduled posts** — morning jokes, daily motivation, and random wisdom at configured times.\n* 📊 **User analytics** — counts messages, commands, reactions, and generates leaderboards.\n* 🗄️ **Postgres persistence** — robust schema with tables for messages, responses, stats, and schedules.\n\n---\n\n## 🛠️ How It Works\n\n1. **Triggers**\n\n   * `Telegram Trigger` — receives all messages and commands from a chat.\n   * `Schedule Trigger` — runs hourly to check for planned posts.\n\n2. **Processing**\n\n   * `Switch` routes commands (`/joke`, `/inspire`, `/random`, `/roast`, `/help`, `/stats`, `/top`).\n   * `Chat history` fetches the latest context.\n   * `Mention Analysis` determines if the bot was mentioned.\n   * `Generating an information response` builds replies for `/help`, `/stats`, `/top`.\n   * AI nodes (`AI response to command`, `AI response to mention`, `AI post generation`) craft witty content via **OpenRouter**.\n\n3. **Persistence**\n\n   * `Init Database` ensures tables exist (`user_messages`, `bot_responses`, `bot_commands`, `message_reactions`, `scheduled_posts`, `user_stats`).\n   * Logging nodes update stats and store every bot/user interaction.\n\n4. **Delivery**\n\n   * Replies are sent back via `Telegram Send` nodes (`Send AI response`, `Send info reply`, `Reply to Mention`, `Submit scheduled post`).\n\n---\n\n## ⚙️ Setup Instructions\n\n1. **Create a Telegram Bot** with [@BotFather](https://t.me/BotFather) and get your API token.\n2. **Add credentials** in n8n:\n\n   * `Telegram API` (your bot token)\n   * `OpenRouter` (API key from [openrouter.ai](https://openrouter.ai/))\n   * `Postgres` (use your DB, Supabase works well).\n3. **Run the `Init Database` node once** to create all required tables.\n4. **(Optional) Seed schedule** with the `Adding a schedule` node — it inserts:\n\n   * Morning joke at 06:00\n   * Daily motivation at 09:00\n   * Random wisdom at 17:00\n     (Adjust `chat_id` to your group/channel ID.)\n5. **Activate workflow** and connect Telegram Webhook or Polling.\n\n---\n\n## 📊 Database Schema\n\n* **user\\_messages** — stores user chat messages.\n* **bot\\_responses** — saves bot replies.\n* **bot\\_commands** — logs command usage.\n* **message\\_reactions** — tracks reactions.\n* **scheduled\\_posts** — holds scheduled jokes/wisdom/motivation.\n* **user\\_stats** — aggregates per-user message/command counts and activity.\n\n---\n\n## 🔑 Example Commands\n\n* `/joke` → witty one-liner with light irony.\n* `/inspire` → short motivational phrase.\n* `/random` → unexpected witty remark.\n* `/roast` → sarcastic roast (no offensive targeting).\n* `/stats` → shows your personal stats.\n* `/top` → displays leaderboard.\n* `/help` → lists available commands.\n* `@GiggleGPTBot` + message → bot replies in context.\n\n---\n\n## 🚀 Customization Ideas\n\n* Add new command categories (`/quote`, `/fact`, `/news`).\n* Expand analytics with reaction counts or streaks.\n* Localize prompts into multiple languages.\n* Adjust CRON schedules for posts.\n\n---\n\n## ✅ Requirements\n\n* Telegram Bot token\n* OpenRouter API key\n* Postgres database\n\n---\n\n📦 Import this workflow, configure credentials, run the DB initializer — and your witty AI-powered Telegram companion is ready!\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "7c0fe80e-b260-4241-b8fb-328a99300eb1",
  "connections": {
    "f78d3e69-c2ba-4640-921a-e3bb52988416": {
      "main": [
        [
          {
            "node": "d581be16-af5f-48bf-bfe2-9a66cf96612f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "197cb78b-ff9b-46d3-93ca-ff708d45d36d": {
      "main": [
        [
          {
            "node": "2fc342ba-3372-4e85-91ac-be6cea8b66ae",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b12f28fc-6fb0-45ca-8348-202bf5a78332",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8afe12f7-ef5b-4b89-8b08-623024c97b3c": {
      "main": [
        [
          {
            "node": "84247455-9eed-424d-8ee4-84ece8f10d54",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "84247455-9eed-424d-8ee4-84ece8f10d54",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "84247455-9eed-424d-8ee4-84ece8f10d54",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "84247455-9eed-424d-8ee4-84ece8f10d54",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "84247455-9eed-424d-8ee4-84ece8f10d54",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "60de834b-47c8-428a-9d28-87ade8fa8a43",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "e1345b2b-f824-40cb-b01d-48031d417b1b",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "d57380bc-5dc5-4130-a767-463bbf81931c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5b7c3300-fa5a-43f5-881f-db48314be81c": {
      "main": [
        [
          {
            "node": "756e467d-835a-4166-8972-4edf50b0007f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "84247455-9eed-424d-8ee4-84ece8f10d54": {
      "main": [
        [
          {
            "node": "86872198-4d19-4c3e-b5dd-14dda87a9139",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d57380bc-5dc5-4130-a767-463bbf81931c": {
      "main": [
        [
          {
            "node": "e1345b2b-f824-40cb-b01d-48031d417b1b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bf1fd22f-7df0-4891-82b0-6fd1ed3648dd": {
      "main": [
        [
          {
            "node": "6698db5c-408d-43ac-b4b8-edbb7a3ac367",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "a95f6638-4406-4aab-8088-5d86125eedbf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "86872198-4d19-4c3e-b5dd-14dda87a9139": {
      "main": [
        [
          {
            "node": "197cb78b-ff9b-46d3-93ca-ff708d45d36d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c4dbddca-9165-401f-9a96-995a958a425a": {
      "main": [
        [
          {
            "node": "2f7789fd-645c-436f-91ef-04cb2143aa7d",
            "type": "main",
            "index": 0
          },
          {
            "node": "8afe12f7-ef5b-4b89-8b08-623024c97b3c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d581be16-af5f-48bf-bfe2-9a66cf96612f": {
      "main": [
        [
          {
            "node": "06b1468d-5af7-46e9-8e50-ec6a3c49d895",
            "type": "main",
            "index": 0
          },
          {
            "node": "cd2ae05c-a673-4b30-82fd-9c003610799a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "756e467d-835a-4166-8972-4edf50b0007f": {
      "main": [
        [
          {
            "node": "f78d3e69-c2ba-4640-921a-e3bb52988416",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "60de834b-47c8-428a-9d28-87ade8fa8a43": {
      "main": [
        [
          {
            "node": "e1345b2b-f824-40cb-b01d-48031d417b1b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5369e144-45cd-4a99-9fa6-284ae24ec585": {
      "ai_languageModel": [
        [
          {
            "node": "b12f28fc-6fb0-45ca-8348-202bf5a78332",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "2fc342ba-3372-4e85-91ac-be6cea8b66ae",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "d581be16-af5f-48bf-bfe2-9a66cf96612f",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "b12f28fc-6fb0-45ca-8348-202bf5a78332": {
      "main": [
        [
          {
            "node": "bf1fd22f-7df0-4891-82b0-6fd1ed3648dd",
            "type": "main",
            "index": 0
          },
          {
            "node": "c538c3eb-0ce6-4f34-80fb-b6668a9fe549",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2fc342ba-3372-4e85-91ac-be6cea8b66ae": {
      "main": [
        [
          {
            "node": "c343e37c-9fe6-47d5-bae3-b1524d766243",
            "type": "main",
            "index": 0
          },
          {
            "node": "c538c3eb-0ce6-4f34-80fb-b6668a9fe549",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e1345b2b-f824-40cb-b01d-48031d417b1b": {
      "main": [
        [
          {
            "node": "76628b1a-4f38-4e8b-be27-adf5cf078b83",
            "type": "main",
            "index": 0
          },
          {
            "node": "bf1fd22f-7df0-4891-82b0-6fd1ed3648dd",
            "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é - Chatbot 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œuds27
Catégorie2
Types de nœuds10
Description de la difficulté

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

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34