Youtube 영상 요약 : 단순히 URL만 텔레그램에 입력하면 요약해서 텔레그램으로 반환해 주는 자동화 - n8n + Gemini

소개

유튜브 영상을 볼 시간이 부족한 친구들을 위해, 영상 링크만 보내면 핵심 내용을 요약해서 다시 돌려주는 텔레그램 봇을 만들어봤어요. 요약에는 Gemini 모델을 사용했고, 전체 플로우는 n8n으로 구성했어요. 처음엔 자막을 불러오는 방식에 애를 먹었지만, 여러 번의 시행착오 끝에 만족스러운 결과를 얻었습니다 😄

진행 방법

사용 도구

  • n8n: 전체 자동화 워크플로우 설계

  • Telegram Bot: 유저 인터페이스 역할

  • Youtube Transcript 노드: 자막 추출 (스크래핑 기반)

  • Gemini 2.5 Flash (Google PaLM): 자막 요약

  • LLM Chain 노드: Gemini와 연결해 프롬프트 기반 요약

  • Youtube API: 영상 제목/채널명/조회수 가져오기

흐름 구성 요약

노드별 기능 정리

  • Telegram Trigger: 사용자가 텔레그램 봇에 보낸 메시지를 트리거로 감지

  • Extract Video ID (Code 노드): 메시지에서 유튜브 링크를 파싱하고, videoId 및 chatId 추출

    한국의 메시지를 보여주는 웹 페이지의 스크린 샷
    // Run Once for All Items 모드 가정
    const items = $input.all();
    const message = items[0].json.message;
    
    // 1) 텍스트가 없으면 중단
    if (typeof message.text !== 'string') {
      return [];
    }
    
    let text = message.text.trim();
    
    // 2) 선두의 슬래시 커맨드(예: "/https://..." 혹은 "/start 유튜브링크")
    //    처리: URL 앞의 "/"만 제거하거나, 봇 커맨드 부분을 스킵
    if (text.startsWith('/')) {
      // "/https://..." 같이 URL 바로 뒤에 붙어온 경우
      if (/^\/https?:\/\//.test(text)) {
        text = text.slice(1);
      } else {
        // "/start https://..." 처럼 커맨드 뒤에 스페이스로 URL이 오는 경우
        const parts = text.split(' ');
        // 첫 토큰이 "/..." 형태면 제거
        if (parts[0].startsWith('/')) {
          parts.shift();
          text = parts.join(' ');
        }
      }
    }
    
    // 3) videoId 매칭
    const match = text.match(/(?:v=|youtu\.be\/)([A-Za-z0-9_-]{11})/);
    if (!match) {
      return [];
    }
    
    // 4) chatId, videoId만 downstream에 전달
    return [
      {
        json: {
          chatId: message.chat.id,
          videoId: match[1],
        }
      }
    ];
    
  • Youtube Transcript 노드: 해당 영상에서 자막 텍스트를 스크래핑 방식으로 추출

  • HTTP Request (YouTube API): videoId를 기반으로 영상의 제목, 채널명, 조회수, 발행일 등 메타정보를 가져옴

  • Merge 노드: 자막 데이터와 메타데이터를 하나의 JSON으로 통합

  • LLM Prompt 작성 (Set 노드): 자막과 제목을 포함한 요약 프롬프트를 구성

    기본 LMM 체인
    • User Prompt

      다음 유튜브 영상의 자막(transcript)을 System Prompt에 맞춰 요약해주세요:
      
      영상명: {{ $json.items[0].snippet.title }}
      자막 내용:
      {{ $json.transcript }}
      
      요약 형식:
      [핵심 요약] (2-3문장)
      \n\n
      - 주요 포인트 1
      \n\n
      - 주요 포인트 2
      \n\n
      - 주요 포인트 3
      \n\n
      핵심 인사이트 (1문장)
    • System Prompt

      당신은 유튜브 영상 자막을 간결하고 유용하게 요약하는 전문가입니다. 
      다음 규칙을 따라 요약해주세요:
      1. 핵심 내용을 3-5개의 주요 포인트로 정리
      2. 각 포인트는 1-2문장으로 간결하게 작성
      3. 불필요한 접속사나 반복되는 내용 제거
      4. 실용적이고 액션 가능한 정보,“핵심 아이디어와 “중요 정보(숫자, 통계, 고유명사 등)" 추출
      5. 한국어로 자연스럽게 요약
      6. 이모지 사용 금지, 깔끔한 텍스트로만 구성
  • Gemini 요약 (LLM Chain): Gemini LLM에 프롬프트를 전달하여 요약 결과 생성

  • Telegram 응답 보내기: 요약 결과 및 영상 정보를 텔레그램 채팅에 전송

    • Text

      Youtube 채널명 :  {{ $('Merge').item.json.channelName }}
      
      제목 : {{ $('Merge').item.json.items[0].snippet.title }}
      조회수 : {{ $('Merge').item.json.items[0].statistics.viewCount }}
      업로드 : {{ $('Merge').item.json.items[0].snippet.publishedAt }}
      
      Summary
      {{ $json.text }}
      
      URL : https://www.youtube.com/watch?v={{ $('Merge').item.json.items[0].id }}

결과와 배운 점

결과

  • 텔레그램에 유튜브 링크만 입력하면 요약된 결과를 다시 텔레그램으로 받아볼 수 있음

  • 영상 제목, 채널명, 조회수, 요약 내용을 깔끔하게 정리해 전달됨

    한국 문자 메시지의 스크린 샷

시행착오와 개선

  • 초기 시도
    자막 유무를 확인해

    • 자막이 있으면 → captions.download API로 수동 자막 다운로드

      프로세스의 다른 단계를 보여주는 다이어그램
    • 자막이 없으면 → Youtube Script 노드로 자동 자막 확보
      를 구현하려 했음.

  • AI의 오정보로 인한 시행착오
    GPT, Gemini, Claude를 오가는 수많은 디버깅 끝에,

    • YouTube API 정책 변경으로 인해 captions.download는 채널 소유자만 접근 가능하다는 사실을 알게 됨 😱

  • 전략 전환
    결국 다음과 같이 워크플로우를 단순화하고 안정화함:

    • 무조건 Youtube Script 노드로 자막 확보

    • 영상 메타데이터 (제목, 채널명, 조회수 등)는 YouTube API로 가져와

    • 최종 결과를 요약 + 정보 포함 형태로 텔레그램에 통합 전송

배운 점

항목

내용

🎯 YouTube Data API 자막 제한

captions.download영상 소유자만 접근 가능하므로, 다른 채널 영상 자막은 불가능함.

❌ timedtext 방식 실패

video.google.com/timedtext는 현재 대부분 작동하지 않으며, signature 파라미터 필요.

✅ 현실적 대안

Youtube Transcript (커뮤니티 노드)가 가장 안정적이고 범용적으로 작동함.

🧾 프롬프트 설계 중요성

요약 품질은 프롬프트 구성 방식에 따라 크게 달라짐. 템플릿화된 포맷이 핵심.

1

뉴스레터 무료 구독