AutomationFlowsAI & RAG › AI Lyrics Study Bot for Telegram — Translation, Summary, Vocabulary

AI Lyrics Study Bot for Telegram — Translation, Summary, Vocabulary

ByRaphael De Carvalho Florencio @followdrabbit on n8n.io

This workflow turns a Telegram bot into an AI-powered lyrics assistant. Users send a command plus a lyrics URL, and the flow downloads, cleans, and analyzes the text, then replies on Telegram with translated lyrics, summaries, vocabulary, poetic devices, or an interpretation—all…

Webhook trigger★★★★★ complexityAI-powered30 nodesTelegramHTTP RequestOpenAI
AI & RAG Trigger: Webhook Nodes: 30 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #7195 — we link there as the canonical source.

This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "id": "347d3502-3620-4b03-bb13-ab2e25fbf020",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        1360
      ],
      "parameters": {
        "width": 572,
        "height": 375,
        "content": "## Fallback for Unsupported Commands\nWhen the message doesn\u2019t match any **Switch** case, send a friendly default reply:\n- **Expected input:** text starting with `/command`.\n- **Action:** return a message listing valid commands and usage examples.\n- **Why:** avoids silent failures when users send unknown commands (e.g., `/foo`).\n- **Tip:** keep this list in sync with the README.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2865a11c-4eae-4fa6-9e39-94daf3383ff7",
      "name": "Send error message",
      "type": "n8n-nodes-base.telegram",
      "position": [
        512,
        1584
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f Opa\\! Esse comando ainda n\u00e3o \u00e9 suportado\\.\n\nPara ver a lista completa de comandos dispon\u00edveis, digite\\:\n\\/start\n\nOu envie um dos comandos v\u00e1lidos seguidos da URL da letra da m\u00fasica\\.\n\nExemplo\\:\n\\/get\\_lyrics https:\\/\\/www\\.letras\\.mus\\.br\\/lana\\-del\\-rey\\/summertime\\-sadness\\/\n",
        "chatId": "={{ $('Settings').first().json.chat_id }}",
        "additionalFields": {
          "parse_mode": "MarkdownV2"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "307ddb89-1fc0-4d2e-be60-23f528187142",
      "name": "Webhook que recebe as mensagens",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2592,
        496
      ],
      "parameters": {
        "path": "lyrics-bot",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "bba60d2f-2f57-4379-8d3f-c62f32a00df0",
      "name": "Text reply",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1104,
        464
      ],
      "parameters": {
        "text": "={{ $json.message.content }}",
        "chatId": "={{ $('Settings').first().json.chat_id }}",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "11c69d81-0095-4ce8-a1d6-4e4b2640f86b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 731,
        "height": 516,
        "content": "## Download & Cleanup (ETL)\nPipeline to extract and normalize text from a URL:\n1) **Extract_URL (Code):** expects `/command <URL>` and reads `parts[1]`.\n   - **If URL is missing:** route to \u201cIncomplete_Command\u201d.\n2) **Download_URL (HTTP Request):** downloads `{{$json.url}}`.\n   - Suggestions: set `timeout=10000`, follow redirects, set a `User-Agent`.\n3) **CleanUp (Code):** remove `<script>`, `<style>`, comments and tags; normalize whitespace.\n   - **Outputs:** `clean_text`, `preview` (first 300 chars), `length`.\n**Limitations:** JS-heavy pages may yield little text; consider a fallback source.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cec43e23-395e-4207-b65f-7a8432bbeead",
      "name": "CleanUp",
      "type": "n8n-nodes-base.code",
      "position": [
        -544,
        528
      ],
      "parameters": {
        "jsCode": "// HTML bruto da p\u00e1gina\nconst html = $input.item.json.data;\n\n// Limpa coment\u00e1rios, scripts e estilos\nlet clean = html\n  .replace(/<!--[\\s\\S]*?-->/g, '')                        // Remove coment\u00e1rios\n  .replace(/<script[\\s\\S]*?<\\/script>/gi, '')             // Remove <script>\n  .replace(/<style[\\s\\S]*?<\\/style>/gi, '')               // Remove <style>\n  .replace(/<\\/?(head|meta|link|iframe|noscript)[^>]*>/gi, '') // Remove head/meta/etc\n  .replace(/<[^>]+>/g, '')                                // Remove todas as tags HTML\n  .replace(/\\s{2,}/g, ' ')                                // Reduz m\u00faltiplos espa\u00e7os\n  .replace(/\\n{2,}/g, '\\n')                               // Reduz m\u00faltiplas quebras\n  .trim();\n\n// Opcional: manter quebras de linha coerentes\nclean = clean.replace(/\\r\\n|\\r/g, '\\n');\n\nreturn [\n  {\n    json: {\n      clean_text: clean,\n      preview: clean.slice(0, 300) + '...',\n      length: clean.length\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "969da478-569f-4158-bb7d-3d5d1339d9c2",
      "name": "Download_URL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -704,
        528
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "067ffcb3-5310-4bfd-8a99-5593cda7792a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 411,
        "height": 388,
        "content": "## Send to Telegram\n- **chatId:** `{{$('Settings').first().json.chat_id}}`\n- **parse_mode:** standardize to **MarkdownV2** (prevents formatting issues). Always escape: `_ * [ ] ( ) ~ ` > # + - = | { } . !`\n- **Long messages:** Telegram limit is ~4096 chars; split long outputs into chunks.\n- **Errors:** keep messages short, clear; do not expose internal details.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9fd83667-b874-458d-8c20-e74394369f4a",
      "name": "Extract_URL",
      "type": "n8n-nodes-base.code",
      "position": [
        -1088,
        528
      ],
      "parameters": {
        "jsCode": "const message = $json.body.message.text;\nconst parts = message.split(\" \");\nconst url = parts[1];\n\nreturn [\n  {\n    json: {\n      url: url\n    }\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f5736ecf-b3d1-4634-ade7-c5e3a05e7767",
      "name": "Settings",
      "type": "n8n-nodes-base.set",
      "position": [
        -1856,
        480
      ],
      "parameters": {
        "values": {
          "number": [
            {
              "name": "model_temperature",
              "value": 0.8
            },
            {
              "name": "token_length",
              "value": "=4096"
            },
            {
              "name": "chat_id",
              "value": "={{ $json.body.message.chat.id }}"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "45b4bedf-4201-4161-8682-478bdcfbe9e6",
      "name": "Message_Filter",
      "type": "n8n-nodes-base.if",
      "position": [
        -2400,
        496
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "fb710608-960b-4b73-9f83-b512a85e5c4f",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.body.message.text !== undefined }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "118c5813-5918-4af0-b7e4-44358ca3aa39",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -1424,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0cd737c4-e0d4-4e39-b1e7-d0ebf3d616db",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body.message.text }}",
              "rightValue": "/start"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f81bff82-0402-4ab0-87ac-8c56e4a40e81",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -2192,
        608
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "bc2c18fa-57a9-4135-8674-3b3c96522967",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -320
      ],
      "parameters": {
        "color": 4,
        "width": 567,
        "height": 1636,
        "content": "## AI Interaction (OpenAI Chat)\nCommands \u2192 specific prompts:\n- **/start:** welcome + usage tips.\n- **/get_lyrics:** original lyrics + line-by-line translation.\n- **/interpret_lyrics:** emotional/symbolic reading.\n- **/study_lyrics:** idioms, slang, figures of speech.\n- **/summarize_lyrics:** short summary (\u2264 5 sentences).\n- **/vocabulary_lyrics:** key vocabulary with meanings.\n- **/lyrics_poetic_analysis:** poetic/literary devices.\n**Config:** uses `Settings.model_temperature` and `Settings.token_length`.  \n**Formatting:** always return Telegram-safe Markdown; avoid overly wide tables.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "33460650-dbf0-481f-ae75-a25759c6319a",
      "name": "/start",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        32
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=Este \u00e9 o primeiro contato do usu\u00e1rio `{{ $json.body.message.from.first_name }}`.  Gere uma mensagem de boas-vindas amig\u00e1vel e curta, no idioma `{{ $json.body.message.from.language_code }}`, explicando que este \u00e9 o *Lyrics Assistant Bot*, com foco em an\u00e1lise de letras de m\u00fasicas.  Inclua a mensagem abaixo no mesmo idioma, formatada em **Markdown V2** para renderizar corretamente no Telegram:  \ud83d\udc4b Ol\u00e1\\\\! {{ $json.body.message.from.first_name }} Seja bem\\-vindo ao *Lyrics Assistant Bot* \ud83c\udfb6  Com este bot voc\u00ea pode **analisar letras de m\u00fasicas** de forma completa, seja para entender melhor a mensagem, estudar um idioma ou apenas se emocionar com as palavras\\\\.    *\ufe0f\u20e3 *Como usar*:  Basta enviar um dos comandos abaixo seguido da **URL da letra da m\u00fasica** \\(em qualquer idioma\\)\\:  *Exemplo:*   \\- \\`\\/get_lyrics https:\\/\\/www\\.letras\\.mus\\.br\\/lana\\-del\\-rey\\/summertime\\-sadness\\/\\`   \\- \\`\\/interpret_lyrics https:\\/\\/genius\\.com\\/Eminem\\-lose\\-yourself\\-lyrics\\`  \ud83e\udde0 *Comandos dispon\u00edveis*: \\- \\`\\/start\\`: Exibe a Sauda\u00e7\u00e3o e orienta\u00e7\u00f5es de uso com exemplos de comandos. \\- \\`\\/get_lyrics\\`: Retorna a letra completa da m\u00fasica com tradu\u00e7\u00e3o em PT-BR, se estiver em outro idioma.   \\- \\`\\/interpret_lyrics\\`: Fornece uma interpreta\u00e7\u00e3o emocional e simb\u00f3lica da m\u00fasica.   \\- \\`\\/study_lyrics\\`: Retorna um estudo lingu\u00edstico com g\u00edrias, express\u00f5es idiom\u00e1ticas e figuras de linguagem.   \\- \\`\\/summarize_lyrics\\`: Gera um resumo curto da letra da m\u00fasica. \\- \\`\\/vocabulary_lyrics\\`: Lista palavras dif\u00edceis ou relevantes com explica\u00e7\u00f5es simples.  \\- \\`\\/lyrics_poetic_analysis\\`: Analisa os recursos po\u00e9ticos e liter\u00e1rios da letra, como rimas, met\u00e1foras e alitera\u00e7\u00f5es.   \ud83c\udfa7 Use m\u00fasicas para aprender, sentir e crescer\\\\\\!"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "19eb1700-85d6-426f-9e0c-78ef3d5febe1",
      "name": "/get_lyrics",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        208
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=> Voc\u00ea \u00e9 um especialista em idiomas e tradu\u00e7\u00e3o de letras musicais.\n> Sua fun\u00e7\u00e3o \u00e9 analisar letras de m\u00fasicas enviadas em qualquer idioma e apresentar o resultado com a seguinte estrutura:\n>\n> * Mantenha a letra da m\u00fasica no idioma original, linha por linha, respeitando a ordem e a formata\u00e7\u00e3o originais.\n> * Abaixo de cada linha, adicione a tradu\u00e7\u00e3o correspondente para o idioma **\\[Portugu\u00eas / ou outro idioma-alvo se necess\u00e1rio]**.\n> * Preserve express\u00f5es idiom\u00e1ticas e figuras de linguagem sempre que poss\u00edvel, oferecendo uma tradu\u00e7\u00e3o que mantenha o sentido e o tom original.\n> * **N\u00e3o modifique** o conte\u00fado original, apenas traduza de forma contextualizada e fiel.\n>\n> Exemplo de formata\u00e7\u00e3o esperada:\n>\n> ```\n> Original line 1  \n> Tradu\u00e7\u00e3o linha 1\n>\n> Original line 2  \n> Tradu\u00e7\u00e3o linha 2\n> ```\n\n{{ $json.clean_text }}"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "078d4df3-ec9a-498a-94ab-8c920f0e8c12",
      "name": "/interpret_lyrics",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        384
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=Voc\u00ea \u00e9 um especialista em an\u00e1lise liter\u00e1ria, semi\u00f3tica e interpreta\u00e7\u00e3o de letras de m\u00fasicas. Receber\u00e1 abaixo a letra completa de uma m\u00fasica (pode estar em qualquer idioma). Sua tarefa \u00e9:\n\n1. Apresentar uma **interpreta\u00e7\u00e3o emocional e simb\u00f3lica** da m\u00fasica, explicando:\n   - Quais sentimentos ela transmite?\n   - Qual a poss\u00edvel **mensagem central** da letra?\n   - Existe uma **hist\u00f3ria impl\u00edcita** sendo contada?\n   - Quais eventos, met\u00e1foras ou s\u00edmbolos s\u00e3o importantes para a interpreta\u00e7\u00e3o?\n\n2. Caso a letra esteja em outro idioma, **considere a tradu\u00e7\u00e3o para PT-BR** ao interpretar.\n\n3. Mantenha um tom **profundo, reflexivo e acess\u00edvel**, como um cr\u00edtico musical que conversa com o p\u00fablico geral.\n\n### Letra da m\u00fasica:\n{{ $json.clean_text }}\n"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "a1316152-7eb7-49dc-b07f-d1b8ecfdc79f",
      "name": "/study_lyrics",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        560
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=Voc\u00ea \u00e9 um especialista em lingu\u00edstica aplicada ao ensino de idiomas e an\u00e1lise de letras de m\u00fasicas. Receber\u00e1 abaixo a letra de uma m\u00fasica (em qualquer idioma). Sua tarefa \u00e9 ajudar um estudante de idiomas a aprender com essa m\u00fasica, explicando os elementos lingu\u00edsticos relevantes.\n\n1. **Identifique e explique g\u00edrias, express\u00f5es idiom\u00e1ticas e figuras de linguagem** encontradas na letra. Para cada item, forne\u00e7a:\n   - A **frase original**\n   - Uma **tradu\u00e7\u00e3o literal** (se aplic\u00e1vel)\n   - Uma **explica\u00e7\u00e3o do significado** ou uso cultural\n\n2. Destaque **express\u00f5es \u00fateis para estudantes de idioma**, mesmo que n\u00e3o sejam g\u00edrias.\n\n3. Caso a letra esteja em outro idioma, forne\u00e7a os exemplos com tradu\u00e7\u00e3o para **PT-BR** e mantenha a explica\u00e7\u00e3o nesse idioma.\n\n4. Organize a resposta em t\u00f3picos numerados ou uma tabela, para facilitar a leitura e o estudo.\n\n### Letra da m\u00fasica:\n{{ $json.clean_text }}\n"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "75a78819-a978-4159-b3a3-ab305a7d3ac3",
      "name": "/summarize_lyrics",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        752
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=Voc\u00ea \u00e9 um especialista em an\u00e1lise musical e linguagem. Receber\u00e1 a letra completa de uma m\u00fasica e deve produzir um **resumo conciso**, destacando a ideia central e os principais temas abordados.\n\n1. Resuma o **conte\u00fado da letra** de forma clara, objetiva e com no m\u00e1ximo **5 frases curtas**.\n2. Evite repetir a letra; use **suas pr\u00f3prias palavras** para transmitir a mensagem.\n3. Se a m\u00fasica contar uma hist\u00f3ria, indique os **principais eventos ou sentimentos envolvidos**.\n4. Caso a letra esteja em outro idioma, considere a tradu\u00e7\u00e3o para PT-BR ao elaborar o resumo.\n\n### Letra da m\u00fasica:\n{{ $json.clean_text }}\n"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "087d78ae-7a87-4c56-99cd-60f11ba52513",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        -144,
        448
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "c303e78e-8d8e-4fbb-8827-f5601fb17876",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $('Settings').first().json.body.message.text }}",
                    "rightValue": "/get_lyrics"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6a1368ea-dbe4-4dc5-9457-e39e0ebb9325",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $('Settings').first().json.body.message.text }}",
                    "rightValue": "/interpret_lyrics"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6d4b8947-4396-487a-8f57-8eb0c94d085e",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $('Settings').first().json.body.message.text }}",
                    "rightValue": "/study_lyrics"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "58ca41e8-9a90-4229-84f0-257bc24afcee",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $('Settings').first().json.body.message.text }}",
                    "rightValue": "/summarize_lyrics"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "99d7d69f-0506-4acf-8480-4fc9f5f2ff65",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $('Settings').first().json.body.message.text }}",
                    "rightValue": "/vocabulary_lyrics"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cedca88b-7397-400f-a316-b173003f1fa0",
                    "operator": {
                      "type": "string",
                      "operation": "startsWith"
                    },
                    "leftValue": "={{ $('Settings').first().json.body.message.text }}",
                    "rightValue": "/lyrics_poetic_analysis"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        },
        "looseTypeValidation": true
      },
      "typeVersion": 3.2
    },
    {
      "id": "a421483e-55f9-4000-8b1f-1cf2772c61d1",
      "name": "/vocabulary_lyrics",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        944
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=Voc\u00ea \u00e9 um especialista em ensino de idiomas e aquisi\u00e7\u00e3o de vocabul\u00e1rio por meio de m\u00fasicas. Receber\u00e1 a letra completa de uma m\u00fasica (em qualquer idioma). Seu objetivo \u00e9 ajudar um estudante brasileiro a aprender **novas palavras e express\u00f5es** com base nessa letra.\n\n1. Identifique e selecione de **5 a 15 palavras ou express\u00f5es relevantes**, com base nos seguintes crit\u00e9rios:\n   - Vocabul\u00e1rio de uso comum, mas **\u00fatil para estudantes**\n   - Palavras **desafiadoras** ou com **m\u00faltiplos significados**\n   - Express\u00f5es idiom\u00e1ticas ou **verbos frasais** (se aplic\u00e1vel)\n\n2. Para cada item, forne\u00e7a:\n   - A **palavra ou express\u00e3o original**\n   - A **tradu\u00e7\u00e3o para o portugu\u00eas (PT-BR)**\n   - Uma **defini\u00e7\u00e3o clara e breve**\n   - (Opcional) Um **exemplo de uso simples**\n\n3. Caso a m\u00fasica esteja em ingl\u00eas (ou outro idioma), escreva as defini\u00e7\u00f5es e exemplos em **portugu\u00eas**.\n\n4. Organize a resposta em formato de lista ou tabela, adequada para revis\u00e3o e estudo.\n\n### Letra da m\u00fasica:\n{{ $json.clean_text }}\n"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "d1c4c7d3-b352-4881-98cd-6ff509fb473e",
      "name": "/lyrics_poetic_analysis",
      "type": "n8n-nodes-base.openAi",
      "position": [
        512,
        1152
      ],
      "parameters": {
        "prompt": {
          "messages": [
            {
              "content": "=Voc\u00ea \u00e9 um especialista em literatura, poesia e an\u00e1lise estil\u00edstica de textos. Receber\u00e1 a letra completa de uma m\u00fasica e dever\u00e1 identificar os **recursos po\u00e9ticos e liter\u00e1rios** utilizados pelo(a) compositor(a).\n\n1. Analise a letra destacando:\n   - **Met\u00e1foras** e compara\u00e7\u00f5es\n   - **Rimas** (se presentes)\n   - **Alitera\u00e7\u00f5es**, **asson\u00e2ncias** ou repeti\u00e7\u00f5es sonoras\n   - **Paralelismos**, **an\u00e1foras**, **hip\u00e9rboles**, **personifica\u00e7\u00f5es** ou outras figuras de linguagem\n   - Uso de **ritmo**, **estrutura po\u00e9tica** ou repeti\u00e7\u00f5es que contribuam para a est\u00e9tica do texto\n\n2. Para cada recurso encontrado, forne\u00e7a:\n   - O **verso ou trecho** onde aparece\n   - O **nome do recurso** identificado\n   - Uma **breve explica\u00e7\u00e3o** do efeito liter\u00e1rio ou simb\u00f3lico causado\n\n3. Se a letra estiver em outro idioma, use a **tradu\u00e7\u00e3o em PT-BR como base para an\u00e1lise** e mantenha a explica\u00e7\u00e3o em portugu\u00eas.\n\n4. Apresente a an\u00e1lise de forma organizada e compreens\u00edvel mesmo para quem n\u00e3o \u00e9 especialista, com tom educativo.\n\n### Letra da m\u00fasica:\n{{ $json.clean_text }}\n"
            }
          ]
        },
        "options": {
          "maxTokens": "={{ $('Settings').first().json.token_length }}",
          "temperature": "={{ $('Settings').first().json.model_temperature }}"
        },
        "resource": "chat",
        "requestOptions": {}
      },
      "typeVersion": 1
    },
    {
      "id": "049d20b1-1a84-4879-be79-ae0350061bbb",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        -896,
        528
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0cd737c4-e0d4-4e39-b1e7-d0ebf3d616db",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.url }}",
              "rightValue": "/start"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "489c9b4c-97e9-40c1-b56f-792c8eafb2ff",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1136,
        784
      ],
      "parameters": {
        "width": 736,
        "height": 311,
        "content": "## Error \u2014 Incomplete/Invalid Command\nTriggers when input is not `/command <URL>`:\n- **Validations:** presence of `message.text`, supported command, and `URL`.\n- **Response:** show correct usage with a concrete example for each command.\n- **Goal:** educate without blocking; reduce user rework.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "d244263a-91d9-42a6-a5a7-bce0fea89b76",
      "name": "Incomplete_Command",
      "type": "n8n-nodes-base.telegram",
      "position": [
        -704,
        944
      ],
      "parameters": {
        "text": "=\u26a0\ufe0f O comando est\u00e1 incompleto ou incorreto\\.\n\nVerifique se voc\u00ea escreveu o comando corretamente e incluiu a URL da letra da m\u00fasica\\.\n\nExemplo de uso correto:  \n\\/get\\_lyrics https:\\/\\/www\\.letras\\.mus\\.br\\/lana\\-del\\-rey\\/summertime\\-sadness\\/\n\nSe tiver d\u00favidas, digite:  \n\\/start  \npara ver todos os comandos dispon\u00edveis e como us\u00e1\\-los\\.",
        "chatId": "={{ $('Settings').first().json.chat_id }}",
        "additionalFields": {
          "parse_mode": "MarkdownV2"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "11a61da7-7fb6-4684-81e0-6ccb0286069b",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3600,
        240
      ],
      "parameters": {
        "color": 5,
        "width": 848,
        "height": 2816,
        "content": "## What this template does\nThis workflow turns a Telegram bot into a **lyrics analysis assistant**.  \nSend a command plus a **song lyrics URL**, and the bot will **download, clean, and analyze the text**, then reply on Telegram with one of the following:\n- Full lyrics with **line-by-line translation**\n- **Emotional/symbolic interpretation**\n- **Idioms/slang & figures of speech** for study\n- **Concise summary** (\u2264 5 short sentences)\n- **Vocabulary list** with meanings\n- **Poetic/literary devices** (rhyme, metaphor, alliteration, etc.)\n\n## Scope & limitations\nThis flow targets **private chats and groups**. It is **not intended for channels**, because Telegram channel updates have a different JSON structure than what this workflow handles.\n\n## Apps & nodes used\nTelegram \u2022 Webhook \u2022 HTTP Request \u2022 Code \u2022 Set \u2022 Switch/IF \u2022 OpenAI \u2022 Sticky Note\n\n## Prerequisites\n- A Telegram bot token from **@BotFather**\n- An **OpenAI** API key configured as an n8n Credential  \n> No API keys are hardcoded in nodes. All secrets are stored in **Credentials**.\n\n## How it works\n1. **Telegram \u2192 Webhook** receives the message.\n2. **Routing (Switch/IF)** checks which command was sent.\n3. **URL Extract + Download (HTTP Request)** fetches the page containing the lyrics.\n4. **Cleanup (Code)** removes HTML, scripts, and styles, and normalizes whitespace.\n5. **OpenAI** formats the output according to the chosen command and returns text.\n6. **Telegram** sends the final answer back to the user.\n7. **Error handling** sends a friendly message for unsupported or incomplete commands.\n\n## Supported commands\n`/start` \u2013 Welcome + usage tips  \n`/get_lyrics <URL>` \u2013 Original lyrics + line-by-line translation  \n`/interpret_lyrics <URL>` \u2013 Emotional & symbolic interpretation  \n`/study_lyrics <URL>` \u2013 Idioms, slang, figures of speech  \n`/summarize_lyrics <URL>` \u2013 Short summary (\u2264 5 sentences)  \n`/vocabulary_lyrics <URL>` \u2013 Key vocabulary with meanings  \n`/lyrics_poetic_analysis <URL>` \u2013 Literary/poetic devices\n\n## Setup\n1) Create **Telegram API** credentials in n8n and paste your BotFather token.  \n2) Create **OpenAI** credentials and paste your API key.  \n3) Publish the webhook and copy its URL:  \n   - Test: `https://[YOUR_DOMAIN]/webhook-test/[YOUR_PATH]`  \n   - Prod: `https://[YOUR_DOMAIN]/webhook/[YOUR_PATH]`  \n4) In Telegram, send a message to your bot to confirm it responds.  \n5) Test each command with a public lyrics URL.\n\n## Telegram webhook configuration\nSet your webhook to the **n8n Webhook URL** (test or prod). You can do this with a simple GET:\n```\n[https://api.telegram.org/bot](https://api.telegram.org/bot)\\<YOUR\\_BOT\\_TOKEN>/setWebhook?url=https\\://\\[YOUR\\_DOMAIN]/webhook/\\[YOUR\\_PATH]\n````\n\nOr POST with JSON (useful to restrict update types):\n```bash\ncurl -X POST https://api.telegram.org/bot<YOUR_BOT_TOKEN>/setWebhook \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://[YOUR_DOMAIN]/webhook/[YOUR_PATH]\",\n    \"allowed_updates\": [\"message\"]\n  }'\n```\n\n## Allowed update types\n\nIf you don\u2019t set `allowed_updates`, Telegram sends **all** update kinds. Common options:\n* `message` \u2014 Regular user messages\n* `edited_message` \u2014 Edited messages\n* `channel_post` \u2014 Posts in channels\n* `edited_channel_post` \u2014 Edited channel posts\n* `callback_query` \u2014 Inline button clicks\n* `inline_query` \u2014 Inline mode queries\n* `poll` \u2014 Poll updates\n* `chat_member` \u2014 Member status changes\n\n## Check, disable, and test updates\n\n* **Check current webhook:**\n```\nhttps://api.telegram.org/bot<YOUR_BOT_TOKEN>/getWebhookInfo\n```\n* **Disable webhook (e.g., to use polling):**\n```\nhttps://api.telegram.org/bot<YOUR_BOT_TOKEN>/deleteWebhook\n```\n* **Polling test (works only if webhook is disabled):**\n```\nhttps://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates\n```\n\n## Troubleshooting\n\n* **No reply?** Ensure the webhook is reachable from the internet and the Telegram token is valid.\n* **Empty output?** Verify that the URL actually contains lyrics text (some sites render behind JS).\n* **Bad formatting on Telegram?** Ensure `parse_mode` (Markdown/MarkdownV2) matches your message and escape special characters for MarkdownV2.\n\n## Privacy & Security\n\n* The workflow **does not store** user messages by default.\n* Secrets are kept in **Credentials**, not in nodes or environment variables in plain text.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cf33261a-b9dd-41ed-8ac9-94fc31eb3379",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1568,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 512,
        "content": "## Routing (If)\n- **If:** detects `/start` and sends the welcome message.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cb3f71b1-93b3-49ec-a761-bb3b065657fb",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 496,
        "height": 512,
        "content": "## Routing (Switch)\n- **Switch (startsWith):** `/get_lyrics`, `/interpret_lyrics`, `/study_lyrics`, `/summarize_lyrics`, `/vocabulary_lyrics`, `/lyrics_poetic_analysis`.\n- **Fallback:** Switch \u201celse\u201d \u2192 unsupported-command reply.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "0a32c476-7084-474f-9e07-d7b5f13c0e0f",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2000,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 512,
        "content": "## Settings & Credentials\n- **model_temperature:** 0.8 (creativity control)\n- **token_length:** 4096 (practical upper bound to avoid truncation)\n- **chat_id:** `{{$json.body.message.chat.id}}` (derived from Webhook)\n- **Security:** Telegram/OpenAI tokens live in **Credentials** (never hardcoded in nodes)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "9ddf823e-5ba0-490e-a1b7-6142abfa5091",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2672,
        240
      ],
      "parameters": {
        "color": 4,
        "width": 640,
        "height": 512,
        "content": "## Trigger & Intake (Webhook + Telegram)\n- **Webhook:** `POST /webhook/MusicAiBot`\n- **Text source:** `$json.body.message.text`\n- **Chat origin:** `chat_id \u2190 $json.body.message.chat.id` (stored in **Settings**)\n- **Initial flow:** Webhook \u2192 Message_Filter (ensures `text`) \u2192 If(/start) \u2192 Switch(other commands)\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "/start",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract_URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "Download_URL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Incomplete_Command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/start": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "/get_lyrics",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "/interpret_lyrics",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "/study_lyrics",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "/summarize_lyrics",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "/vocabulary_lyrics",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "/lyrics_poetic_analysis",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send error message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CleanUp": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Settings": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/get_lyrics": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract_URL": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download_URL": {
      "main": [
        [
          {
            "node": "CleanUp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/study_lyrics": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message_Filter": {
      "main": [
        [
          {
            "node": "Settings",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/interpret_lyrics": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/summarize_lyrics": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/vocabulary_lyrics": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "/lyrics_poetic_analysis": {
      "main": [
        [
          {
            "node": "Text reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook que recebe as mensagens": {
      "main": [
        [
          {
            "node": "Message_Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow turns a Telegram bot into an AI-powered lyrics assistant. Users send a command plus a lyrics URL, and the flow downloads, cleans, and analyzes the text, then replies on Telegram with translated lyrics, summaries, vocabulary, poetic devices, or an interpretation—all…

Source: https://n8n.io/workflows/7195/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Listens for completed Fireflies transcripts, qualifies whether a proposal is needed using OpenAI, drafts structured proposal content, populates a Google Doc template, converts to PDF, and sends it to

HTTP Request, OpenAI, Google Drive +3
AI & RAG

LU. Uses telegram, openAi, httpRequest. Webhook trigger; 28 nodes.

Telegram, OpenAI, HTTP Request
AI & RAG

Accelerate your real estate marketing by moving from "photo capture" to "published listing" in seconds. This workflow automates the entire listing process by hosting property photos via UploadToURL, u

N8N Nodes Uploadtourl, OpenAI, HTTP Request +2
AI & RAG

Ask questions like “How much did I spend on food last month?” and get instant answers from your financial data — directly in Telegram.

Telegram Trigger, OpenAI, Google Sheets +2
AI & RAG

AI Institutional Stock Valuation Engine with Risk Scoring & Scenario Targets

Google Sheets, XML, HTTP Request +3