AutomationFlowsAI & RAG › Extract Post-call Glossary Terms From Transcripts with Anthropic Claude and…

Extract Post-call Glossary Terms From Transcripts with Anthropic Claude and…

Original n8n title: Extract Post-call Glossary Terms From Transcripts with Anthropic Claude and Telegram

ByMarco Venturi @mventuri on n8n.io

This workflow accepts a meeting transcript via an n8n form or webhook, uses Anthropic Claude to extract technical terms and acronyms into a JSON glossary, and then sends either the formatted glossary or a “nothing to add” confirmation to Telegram. Receives a transcript either…

Event trigger★★★★☆ complexityAI-powered15 nodesForm TriggerAgentAnthropic ChatTelegram
AI & RAG Trigger: Event Nodes: 15 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Agent → Form Trigger 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
{
  "id": "OcCtnHxSp53PVvYz",
  "name": "Transcript_assistant",
  "tags": [],
  "nodes": [
    {
      "id": "7149568c-e6da-45f9-aced-41f6d03b7f4a",
      "name": "Setup Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -496,
        -192
      ],
      "parameters": {
        "width": 448,
        "height": 724,
        "content": "## \ud83d\udcdd Post-Call Glossary \u2014 Setup\n\n**How it works:**\nAfter a meeting, feed in the full transcript/minutes (manually via the form, or automatically via webhook from your transcription tool). The Agent scans the whole text and extracts ALL technical terms/acronyms it finds, then sends you a single Telegram message with the full glossary \u2014 or a short \"nothing to add\" message if no relevant terms are found.\n\n**Two ways to trigger:**\n1. **Form** \u2014 open the form URL, paste the transcript, submit. Good for manual review.\n2. **Webhook** \u2014 POST `{ \"transcript\": \"...\", \"sessionId\": \"optional\" }` to the webhook URL. Good for connecting Otter/Fireflies/Recall.ai or a Drive-based automation.\n\n**Required setup:**\n1. Anthropic (or any other LLM) credentials on the Chat Model node\n2. Telegram Bot credentials on both Telegram nodes + your chat_id\n\n**Note:** both triggers wire directly into the same Agent \u2014 a single execution only ever comes from one trigger at a time, so no merge step is needed."
      },
      "typeVersion": 1
    },
    {
      "id": "60480a9e-2663-4ff7-897e-9ce66d3105b7",
      "name": "Section: Inputs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -192
      ],
      "parameters": {
        "width": 412,
        "height": 836,
        "content": "### 1\ufe0f\u20e3 Inputs\n\nTwo independent entry points, normalized into the same shape (`transcript`, `sessionId`) before reaching the Agent:\n\n- **Form**: for pasting a transcript by hand right after a call.\n- **Webhook**: for wiring up an automated transcription tool.\n\nOnly one trigger fires per execution \u2014 there's no merge step, both \"Normalize\" nodes feed the Agent directly."
      },
      "typeVersion": 1
    },
    {
      "id": "603bf48e-736f-4131-954f-464506cbe1df",
      "name": "Form: Paste Transcript",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        48,
        288
      ],
      "parameters": {
        "options": {},
        "formTitle": "Post-Call Glossary Extractor",
        "formFields": {
          "values": [
            {
              "fieldType": "textarea",
              "fieldLabel": "Transcript",
              "requiredField": true
            },
            {
              "fieldLabel": "Session ID (optional)"
            }
          ]
        },
        "formDescription": "Paste the meeting transcript/minutes below to extract a glossary of technical terms."
      },
      "typeVersion": 2.2
    },
    {
      "id": "898cfe95-da49-42d5-9925-fc30d4eb3c01",
      "name": "Webhook: Receive Transcript",
      "type": "n8n-nodes-base.webhook",
      "position": [
        48,
        480
      ],
      "parameters": {
        "path": "post-call-glossary",
        "options": {
          "rawBody": true
        },
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "51b8b51d-02c2-4380-815e-b58bf5bdb0c7",
      "name": "Normalize: Form Input",
      "type": "n8n-nodes-base.set",
      "position": [
        272,
        288
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "assign-transcript",
              "name": "transcript",
              "type": "string",
              "value": "={{ $json.transcript }}"
            },
            {
              "id": "assign-session",
              "name": "sessionId",
              "type": "string",
              "value": "={{ $json.sessionId || 'form-session' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f63ac55f-616b-4d2d-a9f2-e757973a2e53",
      "name": "Normalize: Webhook Input",
      "type": "n8n-nodes-base.set",
      "position": [
        272,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "assign-transcript-wh",
              "name": "transcript",
              "type": "string",
              "value": "={{ $json.body.transcript }}"
            },
            {
              "id": "assign-session-wh",
              "name": "sessionId",
              "type": "string",
              "value": "={{ $json.body.sessionId }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e6d9c7ee-8da3-4ac0-b6d1-8d8afb4b8833",
      "name": "Section: AI Extraction",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        16
      ],
      "parameters": {
        "width": 516,
        "height": 736,
        "content": "### 2\ufe0f\u20e3 AI Extraction\n\nThe Agent reads the full transcript in one pass and returns a strict JSON block listing every distinct technical term/acronym found, each with a short definition. No streaming, no chunking \u2014 full context in, full glossary out.\n\nSwap the Chat Model node for any provider you like; only the Agent's system prompt matters for output format."
      },
      "typeVersion": 1
    },
    {
      "id": "628e2a8f-6844-4a99-9e19-257219109fb4",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        496,
        384
      ],
      "parameters": {
        "text": "={{ $json.transcript }}",
        "options": {
          "systemMessage": "You are an assistant that reviews meeting transcripts/minutes after the call has ended. Read the ENTIRE text provided by the user and identify ALL technical concepts, complex acronyms, or methodologies mentioned (e.g. 'Confusion matrix', 'EBITDA', 'SLA').\n\nRules:\n1. ALWAYS respond ONLY with a valid JSON object wrapped in a markdown code block.\n2. The structure must always be:\n```json\n{\n  \"found\": true or false,\n  \"terms\": [\n    { \"term\": \"Term name\", \"definition\": \"Concise definition (max 25 words)\" }\n  ]\n}\n```\n3. If you find one or more relevant terms, set \"found\": true and list every distinct term once in \"terms\" (no duplicates, even if mentioned multiple times in the text).\n4. If you find NO relevant terms, respond with `{ \"found\": false, \"terms\": [] }`.\n5. Do not add any explanation or text outside the json block."
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "0ab46341-eee6-4464-9aff-7b15fc7c96de",
      "name": "Section: Output Routing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1056,
        -96
      ],
      "parameters": {
        "width": 592,
        "height": 736,
        "content": "### 3\ufe0f\u20e3 Output Routing\n\nThe raw Agent output is parsed into structured JSON, then routed:\n\n- **Terms found** \u2192 formatted into one numbered glossary message and forwarded to Telegram\n- **Nothing relevant** \u2192 a short \"nothing to add\" Telegram message instead\n\nEither way, you get a Telegram notification confirming the review happened."
      },
      "typeVersion": 1
    },
    {
      "id": "d803108f-b76b-42a3-9dcc-8df8faedf81f",
      "name": "Extract JSON",
      "type": "n8n-nodes-base.code",
      "position": [
        848,
        384
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const text = $input.item.json.output || '';\nconst match = text.match(/```json\\s*([\\s\\S]*?)\\s*```/);\n\nif (match) {\n  try {\n    const parsed = JSON.parse(match[1].trim());\n    if (!Array.isArray(parsed.terms)) parsed.terms = [];\n    return { json: parsed };\n  } catch (e) {\n    return { json: { found: false, terms: [], error: 'Parsing error: ' + e.message, raw: text } };\n  }\n}\n\nreturn { json: { found: false, terms: [], error: 'No JSON block found', raw: text } };"
      },
      "typeVersion": 2
    },
    {
      "id": "87439025-10a8-455e-9828-3d05793282d2",
      "name": "Any Terms Found?",
      "type": "n8n-nodes-base.if",
      "position": [
        1072,
        384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bfa86fa7-c104-44b4-8db6-bdc56dfa2839",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.found }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "93bbfe86-a545-471c-864b-553f2de11b0d",
      "name": "Format Glossary Message",
      "type": "n8n-nodes-base.code",
      "position": [
        1296,
        288
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const terms = $input.item.json.terms || [];\n\nconst lines = terms.map((t, i) => `${i + 1}. *${t.term}*\\n   ${t.definition}`);\n\nconst message = `\ud83d\udcda *Post-Call Glossary*\\n_${terms.length} term${terms.length === 1 ? '' : 's'} found_\\n\\n${lines.join('\\n\\n')}`;\n\nreturn { json: { message } };"
      },
      "typeVersion": 2
    },
    {
      "id": "ac4798f6-3165-49ad-8eaa-f8de7bb509ac",
      "name": "Anthropic Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        576,
        608
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.5
    },
    {
      "id": "ad1b61fc-b6de-4880-a1a5-369d83b94243",
      "name": "OK - Send to Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1520,
        288
      ],
      "parameters": {
        "text": "={{ $json.message }}",
        "chatId": "<CHAT_ID>",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "cbfd0892-0b3b-4480-a27c-14562271b004",
      "name": "KO - Send to Telegram",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1296,
        480
      ],
      "parameters": {
        "text": "=Nothing to add ",
        "chatId": "<CHAT_ID>",
        "additionalFields": {
          "parse_mode": "Markdown"
        }
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "7a50129a-5727-4143-abc5-7ce88992b6bd",
  "nodeGroups": [],
  "connections": {
    "AI Agent": {
      "main": [
        [
          {
            "node": "Extract JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract JSON": {
      "main": [
        [
          {
            "node": "Any Terms Found?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Any Terms Found?": {
      "main": [
        [
          {
            "node": "Format Glossary Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "KO - Send to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Anthropic Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Normalize: Form Input": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form: Paste Transcript": {
      "main": [
        [
          {
            "node": "Normalize: Form Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Glossary Message": {
      "main": [
        [
          {
            "node": "OK - Send to Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize: Webhook Input": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: Receive Transcript": {
      "main": [
        [
          {
            "node": "Normalize: Webhook Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

This workflow accepts a meeting transcript via an n8n form or webhook, uses Anthropic Claude to extract technical terms and acronyms into a JSON glossary, and then sends either the formatted glossary or a “nothing to add” confirmation to Telegram. Receives a transcript either…

Source: https://n8n.io/workflows/16598/ — 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

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Form Trigger, Google Sheets, HTTP Request +3
AI & RAG

A powerful n8n automation workflow that scrapes the latest Reuters news articles using Bright Data's web scraping capabilities and delivers intelligent news summaries directly to your Telegram chat.

Anthropic Chat, HTTP Request Tool, Form Trigger +3
AI & RAG

Personal Assistant. Uses memoryBufferWindow, agent, agentTool, httpRequestTool. Event-driven trigger; 77 nodes.

Memory Buffer Window, Agent, Agent Tool +15
AI & RAG

Generate research-backed article with n8n

Form Trigger, HTTP Request, Email Send +2
AI & RAG

This workflow is designed for marketers, founders, agencies, and product teams who want to understand how real customers talk about a product category, market, or problem space.

Reddit, Agent, Output Parser Structured +3