포스트

네이버 블로그 발행 자동화 — 텔레그램 기록을 AI가 글로, Playwright가 초안까지

매일 남긴 기록을 텔레그램으로 받아 AI가 에세이로 쓰고 Playwright가 네이버 스마트에디터에 임시저장까지 무인으로 돌리는 파이프라인. 계획·실행·결과와, 조용히 죽던 08시 잡을 자가복원으로 고친 기록.

네이버 블로그 발행 자동화 — 텔레그램 기록을 AI가 글로, Playwright가 초안까지

🧭 이 글의 한 줄 “매일 블로그 글을 사람이 쓰는 대신, 하루치 기록만 남기면 AI가 초안을 써서 네이버에 임시저장까지 해두고, 발행 버튼만 사람이 누른다.” 그걸 어떻게 계획하고 만들고, 무엇이 남았는지.

계획

목표는 하나였다. 매일 블로그 한 편을, 손으로 쓰지 않고 남긴다. 단 두 가지 제약을 처음부터 못 박았다.

  • 발행은 사람이 누른다. 자동화는 임시저장(초안)까지만. 검수 없이 공개되면 위치 노출·사실 오류가 그대로 나간다(실제로 초기에 공개 글에 생활권 사진이 잘못 나간 사고가 있었다).
  • 수치는 창작 금지. 시간·용량·체중·날짜·횟수는 남긴 기록에 있는 값만 쓴다. 없으면 비운다.

이 두 제약에서 자연스럽게 4단 구조가 나왔다.

  1. 입력 — 텔레그램 봇: 모바일에서 사진·몸무게·컨디션을 툭 던지면 봇이 받아 기록으로 저장. (클라우드 세션은 첨부 이미지의 원본 바이트를 못 읽어서, 텔레그램을 “정식 입력 경로”로 삼았다.)
  2. 생성 — AI 컴파일: 하루치 로그를 사람 톤 에세이로 변환. 작가 → 휴머나이저 → 사실검수(PD) 3패스.
  3. 발행(초안) — Playwright: 네이버는 공식 글쓰기 API가 없다. 브라우저 자동화로 스마트에디터에 임시저장.
  4. 운영 — 매일 08:00 무인 실행: 맥 launchd가 위 흐름을 매일 자동으로. 발행 버튼만 사람 몫.

🧭 기획자·사업자라면 “완전 자동 발행”은 기술적으로 어렵지 않다. 그런데도 마지막 1마일(공개)을 일부러 수동으로 남겼다. 자동화의 ROI를 계산할 때, 틀린 것이 그대로 세상에 나갈 때의 평판·규제 비용을 함께 넣으면 “사람 게이트 1개”가 가장 싼 리스크 헷지가 되는 구간이 있다.

실행

입력·생성 — 기록이 글이 되기까지

텔레그램 봇은 getUpdates 폴링으로 메시지를 가져와(offset으로 위치 추적) 사진·영상을 그날 폴더에 저장하고, 영상은 ffmpeg로 GIF로 바꾼다(네이버는 GIF를 무음 자동반복으로 심어줘 사진처럼 배치된다). 그 하루치 로그를 AI가 3패스로 에세이화한다 — 작가가 초안, 휴머나이저가 일기 톤, PD가 로그·사진과 사실 대조표를 만들어 근거 없는 수치를 차단한다.

발행 — 스마트에디터라는 지뢰밭

네이버 스마트에디터 자동화는 “성공 로그”가 거짓말을 한다. 명령은 나갔는데 캡션이 본문으로 새고, 소제목 폰트는 조용히 안 먹고, 콜라주는 글 맨 아래로 밀린다. 이 함정들과 잡는 법은 따로 정리했다 → 네이버 스마트에디터 Playwright 함정 5가지. 저장소가 봇 커밋으로 계속 움직이는 라이브 repo라 커밋 규율도 따로 필요했다 → 봇이 커밋하는 파이프라인의 git 규율.

진짜 문제 — 무인 파이프라인이 “조용히” 죽었다

가장 값진 교훈은 여기서 나왔다. 이틀 연속, 08:00 자동 실행이 글을 한 편도 안 냈다.

  • 첫날: API Error: Unable to connect to API (ENOTFOUND) — 그 순간 네트워크(DNS)가 끊겨 AI 호출이 실패.
  • 다음날: API Error: Connection closed mid-response — 생성 도중 연결이 끊김.

문제는 실패 자체가 아니라 아무도 몰랐다는 것이다. 로그엔 조용히 남고, 사람이 블로그를 열어보기 전까지 며칠이고 방치될 수 있었다. 원인을 갈라보니 두 겹이었다.

  • 치명(글 미생성): AI 생성 단계에 재시도가 없었다. 순간 끊김 한 번 = 그날 글 증발.
  • 부수(GIF 실패): launchd는 최소 PATH로 실행돼 ffmpeg를 못 찾았다(대화형 셸에선 잡혀 재현이 안 됐다). 이건 GIF 변환만 실패시켰다.

고친 방향은 “실패해도 스스로 만회하고, 실패하면 사람을 부른다”였다.

08:00 잡이 조용히 죽던 것을 자가복원으로 — 실패 감지·재시도·누락일 스캔·텔레그램 알림 흐름

  • 누락일 자동 스캔: 매 실행 때 최근 5일 중 로그는 있는데 초안도 발행도 안 된 날을 찾아 함께 처리. 하루 놓쳐도 다음 실행이 만회한다.
  • 생성 재시도 3회: 성공 판정을 종료코드가 아니라 결과 파일 존재로 한다(부분 실패에 exit 0을 줄 수 있어서). 2·4분 백오프.
  • 텔레그램 알림: 실행 결과(임시저장/실패)를 폰으로 통지. “조용한 실패”를 없앴다.
  • PATH 고정: 무인 실행에서도 ffmpeg를 찾게.
1
2
3
4
5
6
# 성공을 '종료코드'가 아니라 '결과물 존재'로 판정 — 부분 실패 방어
for attempt in $(seq 1 "$GEN_RETRIES"); do
  "$CLAUDE" -p "/mj-compile $DATE" --dangerously-skip-permissions --max-turns 60 || true
  [ -f "posts/$DATE.md" ] && break
  sleep $((attempt * 120))   # 2분·4분 백오프
done

🧭 기획자·사업자라면 무인 시스템의 진짜 비용은 구축이 아니라 “조용한 실패”다. 잘 돌 때의 데모는 쉽지만, 안 돌 때 아무도 모르는 구조는 언젠가 반드시 사고가 된다. 알림·재시도·자가만회는 “있으면 좋은 것”이 아니라 무인 운영의 최소 사양이다.

결과

  • 매일 08:00, 어제 글이 자동으로 임시저장된다. 사람은 검수하고 발행 버튼만 누른다.
  • 자가복원이 실측으로 증명됐다. 위 실패 다음날, 놓쳤던 날짜의 글이 스캔·재시도로 자동 만회 발행됐다(사람 개입 없이).
  • 첫 투약일부터 매일 기록이 쌓이는 중. 한 편 한 편이 텔레그램 몇 줄에서 시작한다.
  • 남은 것: 노트북을 닫으면 맥이 잠들어 08:00 잡이 밀린다 → 상시 켜둘 호스트(윈도우 등)로 이전 준비 중. 발행 스타일 일부(인용구 종류)는 아직 수동 손질.

사용한 기술

  • Playwright — 공식 API 없는 네이버 스마트에디터를 브라우저 자동화로 임시저장.
  • 텔레그램 Bot API (getUpdates 폴링 + offset) — 모바일 입력 수집. 웹훅 없이 폴링이라 상태를 git으로 동기화.
  • claude(구독) -p 헤드리스 — 로그 → 에세이 3패스 컴파일. API 키가 아니라 구독으로 구동.
  • launchd (macOS) — 매일 08:00 + 봇 폴링 스케줄.
  • ffmpeg — 영상 → GIF(네이버가 무음 자동반복으로 심는 포맷).
  • Bash + Python — 파이프라인 오케스트레이션(누락일 스캔·재시도·알림).

정리

  • 자동화의 목표를 “글을 대신 쓰기”가 아니라 “초안까지만, 발행은 사람”으로 잡으니 리스크가 통제됐다.
  • 무인 파이프라인은 조용한 실패를 못 없애면 미완성이다 — 재시도·자가만회·알림이 본체다.
  • “성공했다”의 판정을 종료코드가 아니라 결과물로 바꾸는 작은 결정이, 하루치 글을 살렸다.

글 다음은 영상이었다 같은 블로그의 네이버 클립(세로 숏폼)도 손으로 만들고 있었다. 컷시트 한 장을 ffmpeg에 넣어 찍어내도록 바꾼 과정은 여기에 있다 → 릴스도 쇼츠도 네이버 클립도 결국 같은 세로 영상

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.