본문 바로가기

AI 콘텐츠 자동화

유튜브 모니터링 텔레그램 알림 봇, 중복 메시지 폭탄을 해결하기까지

유튜브 모니터링 텔레그램 알림 봇, 중복 메시지 폭탄을 해결하기까지

매일 아침 반복되는 리서치 업무를 코드로 해결하려던 시도와, 그 과정에서 겪은 에러 해결기를 정리했다.

유튜브 API 연동 코드 작업 화면
유튜브 API 연동 코드 작업 화면

위 화면은 텔레그램 봇이 유튜브 새 영상을 확인하고 전송하도록 짜인 초기 파이썬 코드다. 이 코드는 정상적으로 작동하는 것처럼 보였지만, 곧 서버에 치명적인 문제를 일으켰다.

💡 발단: 매일 아침 30분, 반복 업무를 없애고 싶었다

사업을 운영하다 보면 업계 트렌드를 기민하게 파악하는 것이 필요적입니다. 저 역시 매일 아침 업무 시작 전, 유튜브에 핵심 키워드를 검색해 경쟁사 동향과 신기술 트렌드를 파악하는 것이 중요한 일과였습니다. 방대한 정보가 모이는 유튜브는 훌륭한 리서치 채널이었기 때문입니다.

하지만 문제는 '단순 반복'이었습니다. 매일 똑같은 키워드를 검색하고, 어제 본 영상과 오늘 새로 올라온 영상을 육안으로 걸러내는 작업은 생각보다 피로도가 높았습니다. 바빠서 며칠 리서치를 건너뛰면 중요한 정보를 놓치기 일쑤였죠.

"이 지루한 단순 반복 작업을 굳이 내가 매일 해야 할까?"

문득 코딩을 통해 이 과정을 자동화한다면 매일 아침 소중한 30분을 아낄 수 있겠다는 확신이 들었습니다. 그렇게 '나만의 트렌드 비서'를 만들기 위한 유튜브-텔레그램 자동화 봇 개발이 시작되었습니다.

 

🚀 기획: 알아서 트렌드를 배달해 주는 봇 설계

제가 구상한 자동화 시나리오는 직관적이었습니다.

  1. 데이터 수집: 파이썬(Python)으로 YouTube Data API에 접근해 지정된 핵심 키워드를 검색합니다.
  2. 정보 추출: 새로 업로드된 영상의 '제목, 채널명, 링크'만 깔끔하게 추출합니다.
  3. 알림 전송: Telegram Bot API를 활용해 제 개인 텔레그램 채널로 메시지를 보냅니다.
  4. 자동화: 이 스크립트를 클라우드 서버에 올리고, 스케줄러를 통해 '1시간마다' 알아서 실행되도록 설정합니다.

로컬 환경에서 테스트해 보니 첫 텔레그램 메시지가 제 스마트폰에 성공적으로 도착했습니다. 코드는 성공적해 보였고, 모든 것이 순조롭게 흘러가는 듯했습니다.


테스트 성공의 기쁨도 잠시, 봇 설계의 빈틈은 끔찍한 알림 폭탄으로 되돌아왔다.

서버 로그를 뜯어보며 디버깅하는 파이선생 캐릭터
서버 로그를 뜯어보며 디버깅하는 파이선생 캐릭터

서버 로그를 뜯어보며 디버깅을 진행한 결과, 코드가 멈추지 않고 계속 실행되며 API 한도를 초과하게 만든 두 가지 논리적 오류를 발견했다.

🚨 위기: 새벽 3시, 알림 테러와 API 한도 초과

그러나 스크립트를 서버에 배포하고 맞이한 첫날 밤, 대참사가 벌어졌습니다. 새벽 3시경 텔레그램 알림음이 미친 듯이 울리기 시작한 것입니다.

깜짝 놀라 화면을 켜보니, 봇이 똑같은 유튜브 영상 링크 5개를 1분 간격으로 쉴 새 없이 쏟아내고 있었습니다. 황급히 서버에 접속해 스크립트를 강제 종료시키려던 찰나, 갑자기 봇이 메시지 전송을 멈췄습니다.

문제가 해결된 것이 아니었습니다. 서버 로그를 확인해 보니 봇이 멈춘 진짜 이유는 'YouTube API 일일 요청 할당량(Quota) 초과'였습니다. 제대로 된 리서치는 시작도 해보기 전에, 무한 루프에 빠져 하루 치 API 사용량을 새벽에 모두 허공으로 날려버린 셈입니다.

 

🔍 디버깅: 범인은 스케줄러가 아니었다

처음에는 주기적 실행을 담당하는 리눅스 크론탭(crontab)이나 파이썬 스케줄러의 설정 오류인 줄 알았습니다. 1시간마다 실행되어야 할 코드가 1분마다 돌고 있다고 의심했기 때문입니다. 하지만 설정값은 정상이었습니다. 텔레그램 API의 네트워크 지연으로 인한 '무한 재시도(Retry)' 문제인가 싶어 타임아웃을 건드려 보기도 했지만, 이 역시 헛다리였습니다.

코드를 한 줄씩 뜯어보며 집요하게 디버깅한 끝에, 두 가지 치명적인 논리적 오류를 발견했습니다.

1. '기억력'이 없는 상태(Stateless) 구조

제 스크립트는 매번 새롭게 실행될 뿐, 과거의 기록을 기억하지 못했습니다. 검색 상단에 있는 최신 영상 5개를 가져오기만 할 뿐, "이 영상을 전에 보냈던가?"를 확인하는 절차가 없었던 것입니다. 그러니 1시간 뒤에 실행되어도 아까 보냈던 그 5개의 영상을 똑같이 다시 전송할 수밖에 없었습니다.

2. 시간대(Timezone)가 만든 9시간의 함정

중복 전송을 막기 위해 나름대로 "최근 1시간 이내에 올라온 영상만 가져오기"라는 조건을 걸어두긴 했습니다. 하지만 치명적인 기준의 차이가 있었습니다. * 유튜브 API: 협정 세계시(UTC) 기준 반환 * 내 서버(파이썬): 한국 표준시(KST) 기준 계산

두 시간대 사이에는 9시간의 시차가 존재합니다. 한국 시간이 유튜브 시간보다 9시간 빠르다 보니, 파이썬 조건문은 항상 '참(True)'을 뱉어냈습니다. 1시간이 훌쩍 지난 영상도 계속해서 '방금 올라온 최신 영상'으로 착각하고 있었던 것입니다.

 

🛠 해결: 봇에게 기억을 심어주고, 기준의 영점을 맞추다

문제의 원인을 성공적히 파악한 후, 즉시 두 가지 해결책을 적용했습니다.

  • 상태(State) 관리 도입: 복잡한 DB 대신 가벼운 sent_videos.json 파일을 생성했습니다. 한 번 전송한 영상의 고유 아이디(videoId)를 이 파일에 기록하게 했습니다. 코드가 실행될 때 "JSON 파일에 이미 있는 ID라면 건너뛰고(Continue), 새로운 ID만 전송 후 업데이트하라"는 로직을 추가하여 봇에게 '기억'을 심어주었습니다.