소개
좋은 AI 교육 유튜브 영상들을 혼자 보는 것보다, 스터디원분들이랑 공유하면 좋겠다고 생각했어요. 단순 요약이 아닌, 카드뉴스 형태의 인사이트 정리로 만들고 싶었고, 이걸 HTML 뉴스레터로 발송하고 드라이브에 저장했습니다.
앞으로는 이 카드뉴스를 PNG 이미지로 변환하는 기능도 추가할 예정이에요!
(캔바를 연결하면 될 것 같은데, 유료 결제가 필요한 것 같아 일단 html로 구성했습니다)
진행 방법
✅ 사용한 도구
Google Sheets: 공유하고 싶은 유튜브 영상 링크를 리스트업
n8n: 전체 워크플로우 자동화
Gemini (LLM): 카드뉴스용 콘텐츠 생성
Gmail / Google Drive: 결과물 전송 및 저장
⚙️ 전체 자동화 워크플로우
프로세스의 다른 단계를 보여주는 다이어그램
Google Sheets에 영상 링크 리스트업
항목 목록을 보여주는 Google 스프레드 시트의 스크린 샷
구글시트에서 영상 가져오기
<video ID 추출코드>
const item = $input.first();
const url = item.json["URL"] || "";
let videoId = null;
try {
if (url.includes("youtu.be/")) {
videoId = url.split("youtu.be/")[1].split("?")[0];
} else if (url.includes("youtube.com/watch")) {
const match = url.match(/v=([^&]+)/);
if (match && match[1]) {
videoId = match[1];
}
}
} catch (e) {
videoId = null;
}
return {
...item,
json: {
...item.json,
videoId
}
};자막 추출
Jira 응용 프로그램 설정의 스크린 샷
자막추출은 아래와 같은 코드(유투브의 자막스크립트를 가져오는 코드)를 외부에서 실행할 수 있도록 서버에 올려놓아야합니다. 저는 집에 n8n용으로 서버가 있어서 거기에 구축을 했고, 그 서버의 특정 포트를 스크립트를 가져오는 용도로 지정해놓고 해당 포트를 호출하는 식으로 구축하였습니다. (초보자분들은 클라우드서버에서 실행되도록 하시는게 좋을것 같습니다)
from flask import Flask, request, jsonify from youtube_transcript_api import YouTubeTranscriptApi from youtube_transcript_api._errors import ( TranscriptsDisabled, NoTranscriptFound, VideoUnavailable, CouldNotRetrieveTranscript, ) import time app = Flask(__name__) @app.route("/transcript", methods=["GET"]) def get_transcript(): video_id = request.args.get("id") if not video_id: return jsonify({"error": "Missing 'id' parameter in query"}), 400 for attempt in range(2): # 최대 2번 시도 try: # 자동 생성 자막 포함하여 시도 transcript_list = YouTubeTranscriptApi.list_transcripts(video_id) transcript = transcript_list.find_transcript(['ko', 'en']) return jsonify(transcript.fetch()) except (NoTranscriptFound, TranscriptsDisabled): try: # 자동 생성 자막으로 fallback transcript = transcript_list.find_generated_transcript(['ko', 'en']) return jsonify(transcript.fetch()) except Exception as e: if attempt == 0: time.sleep(1) continue return jsonify({"error": "자막이 없습니다 (수동/자동 모두 실패)"}), 400 except VideoUnavailable: return jsonify({"error": "해당 영상은 삭제되었거나 접근할 수 없습니다."}), 400 except CouldNotRetrieveTranscript: return jsonify({"error": "YouTube에서 자막을 가져오지 못했습니다. (접근 제한, 인증 필요 등)"}), 400 except Exception as e: if attempt == 0: time.sleep(1) # 1초 대기 후 재시도 continue return jsonify({"error": f"알 수 없는 오류: {str(e)}"}), 500 if __name__ == "__main__": app.run(debug=True, host="0.0.0.0", port=5000)AI에게 카드뉴스 도출에 대한 프롬프트를 주고 컨텐츠를 생성하도록 합니다.
# 목표 : 다음 유튜브 영상 스크립트 전체를 꼼꼼히 읽고, 교육 관계자 및 학부모가 관심을 가질 만한 주제를 선정합니다. 이 주제를 바탕으로, 카드뉴스를 구성합니다. ## 첫 번째 카드(도입) - 선정된 주제를 소개하며, 흥미롭게 문제를 제기합니다. - 200자 이내로 작성합니다. ..... <2~4번째 카드도 첫번째 카드와 같은 형식으로 프롬프트를 작성합니다.> 📌 출력 형식 (수정 없이 그대로 따라주세요): { "cards": [ { "title": "카드 1 제목", "text": "카드 1 본문" }, { "title": "카드 2 제목", "text": "카드 2 본문" }, { "title": "카드 3 제목", "text": "카드 3 본문" }, { "title": "카드 4 제목", "text": "카드 4 본문" } ] } [텍스트 시작] {{ $json.combinedText }} [텍스트 끝]Gemini가 카드뉴스 형식으로 HTML 콘텐츠 생성(인사이트 도출)
생성된 컨텐츠를 바탕으로, chatGPT혹은 Gemini에게 <HTML>형식의 카드뉴스 템플릿을 작성해달라고 요청한 뒤, HTML 노드에 적용합니다.
파일을 구글드라이브에 올리기 위해 Base64형태로 저장합니다.
HTML을 Gmail로 발송, Google Drive에도 저장
<결과물>
‘일시 중지하고 생각하는 단어가있는 노란 포스터
🧠 프롬프트 튜닝 경험
초기에는 단순히 "4장의 카드뉴스로 만들어줘"라고 요청했더니:
1시간짜리 강의 내용을 4장으로 요약하려 하다 보니
각 카드가 원론적이고 심심한 요약으로 끝남 😥
그래서 이렇게 개선했어요:
한 가지 인사이트에 집중하도록 프롬프트를 수정
예: 1장 문제제기 → 2~3장 배경/내용 → 4장 질문 던지기
🎨 HTML 카드 제작 중 겪은 점
HTML로 카드 6장을 만들되 디자인 정렬과 반응형 배치에 시간이 꽤 걸렸어요
예쁘게 보이게 하려면 텍스트 길이나 폰트 크기 조정 등 미세 조정 필요
결과와 배운 점
프롬프트의 힘!
단순 지시보다 인사이트 중심의 설계가 훨씬 나은 결과를 만듦콘텐츠 재이해의 기쁨
뉴스레터를 만들다 보니, 흘려봤던 영상도 다시 보고 더 깊이 이해하게 됨앞으로의 계획
카드뉴스를 PNG 이미지로 저장하기