OpenClaw로 서평 자동화 만들기 2부: 사락 리뷰 링크 관리와 포스팅 자동화

OpenClaw로 서평 자동화 만들기 2부: 사락 리뷰 링크 관리와 포스팅 자동화

1부에서 이어지는 내용입니다. 이전 글: OpenClaw로 서평 자동화 만들기 1부: 조회와 신청을 운영 가능한 흐름으로 바꾸기

1부에서 정리한 것은 책 관련 모집글을 발견하고, 신청까지 이어지는 흐름이었다. 그런데 막상 그 부분을 줄이고 나니 바로 다음 병목이 보였다. 신청은 빨라졌지만, 그 이후의 작업은 여전히 손이 많이 갔다.

내가 서평을 남기는 채널은 하나가 아니다. 대표적으로는 YES24의 사락이 있고, 개인 블로그가 있고, 때로는 인스타그램에도 내용을 정리하거나 흔적을 남긴다. 사락은 YES24 안에서 운영되는 독서/리뷰 커뮤니티에 가까운 공간인데, 책을 읽고 남긴 기록이 쌓이는 저장소 역할을 한다. 신청 댓글에 첨부하는 기존 리뷰 링크도 보통 여기서 가져오게 된다.

문제는 채널이 여러 개라는 사실보다, 그걸 계속 손으로 관리하고 있었다는 점이었다. 사락에도 올리고, 블로그에도 정리하고, 필요하면 인스타그램에도 공유하다 보면, 다음 신청 때 참고할 링크를 다시 찾는 일과 무엇을 어디에 썼는지 관리하는 일이 반복된다. 특히 사락 리뷰 링크는 단순 기록이 아니라 다음 활동에서 다시 쓰이는 자산이라 더 자주 꺼내 보게 된다.

결국 조회와 신청 자동화가 어느 정도 자리를 잡고 나니, 이번에는 리뷰 링크 관리와 포스팅 준비 작업이 병목으로 보이기 시작했다.

이 글에서는 그 다음 단계를 정리한다. 사락 리뷰 URL을 어떻게 수집하고, 왜 “전부 넣기” 대신 선별 기준을 두었는지, 상태 파일을 어떤 인터페이스로 다뤘는지, 그리고 여러 채널에 흩어진 서평 기록을 어떻게 다시 포스팅 흐름과 연결했는지를 중심으로 다룬다.

다음 병목: 신청보다 리뷰 링크 관리가 더 번거로움

처음에는 리뷰 링크가 몇 개 없어서 큰 문제가 아니었다. 하드코딩으로 3~4개 정도 넣어두고, 필요하면 가끔 수정하면 됐다.

하지만 서평 활동을 계속하면 상황이 달라진다.

  • 리뷰 링크는 계속 늘어난다.
  • 최신 글이 무엇인지 매번 다시 확인해야 한다.
  • 어떤 링크를 신청 댓글에 넣을지 골라야 한다.
  • 너무 많이 넣으면 댓글이 지저분해진다.
  • 너무 적게 넣으면 활동 이력이 약해 보인다.

즉, 문제는 단순히 “링크를 저장한다”가 아니었다. 늘어나는 링크를 어떤 기준으로 관리하고, 어떤 시점에, 어떤 형식으로 꺼내 쓸 것인가가 핵심이었다.

개인 자동화는 앞단을 자동화하고 나면 뒷단의 수작업이 더 선명하게 드러난다. 이번에도 마찬가지였다. 신청 자동화가 어느 정도 정리되자, 그 다음엔 링크 관리의 비효율이 더 크게 보이기 시작했다.

사락 리뷰 수집: 페이지 파싱보다 API가 더 나았던 이유

사락 페이지는 처음 보면 단순 HTML 파싱으로 해결할 수 있을 것 같지만, 실제로는 Nuxt 기반으로 렌더링되는 구조라 공개 페이지에서 정적인 링크 목록만 바로 뽑아오기 어렵다.

처음에는 리뷰 목록 페이지 HTML에서 링크를 직접 찾으려 했다. 하지만 원하는 형태의 리뷰 목록이 서버 HTML에 정직하게 박혀 있지 않았고, 렌더링 이후 구조에 의존하면 DOM 형태가 바뀔 때 쉽게 깨질 가능성이 높았다. 목록 수집만 하려고 브라우저 자동화를 붙이는 것도 과했다.

그래서 DevTools 네트워크를 확인해 실제로 리뷰 목록을 내려주는 API를 먼저 찾았다. 이쪽은 적어도 “내 블로그의 리뷰 목록”이라는 도메인 개체를 더 직접적으로 다루고 있었고, 응답 구조도 링크/작성일/평점 같은 필요한 필드를 다루기 쉬웠다.

결과적으로는 내 사락 블로그(jake220)의 리뷰 목록을 API로 조회해서, 필요한 필드만 추려 JSON 상태 파일로 저장하는 구조로 정리했다.

  • 리뷰 URL
  • 제목
  • 작성일
  • 평점
  • 정렬/선별에 필요한 메타데이터

이 작업이 중요한 이유는 단순하다.

  • 리뷰가 새로 올라오면 링크 목록도 같이 갱신된다.
  • 신청 댓글은 더 이상 하드코딩된 옛날 링크에 의존하지 않는다.
  • 링크 관리가 사람 기억에 의존하지 않게 된다.

자동화의 가치는 보통 “버튼을 대신 눌러준다”는 데 있지 않다. 오히려 사람이 잊어버리기 쉬운 상태를 시스템이 기억하게 만드는 것에 더 가깝다.

왜 DB가 아니라 상태 파일이었나

이 시점에서 선택지는 두 가지였다. 작은 DB를 붙이거나, JSON 상태 파일로 유지하거나.

이번에는 후자를 택했다. 이유는 단순하다.

첫째, 데이터 규모가 작다. 리뷰 링크 몇십~몇백 개 수준에서는 관계형 조회나 복잡한 인덱스가 필요한 상황이 아니다. 둘째, 개인 자동화에서는 투명성이 중요하다. 상태 파일은 열어보면 현재 시스템이 무엇을 알고 있는지 바로 확인할 수 있다. 셋째, 장애가 났을 때 복구가 쉽다. 파일 하나를 백업하거나 비교하면 끝나는 문제가 많다.

그래서 리뷰 URL은 memory/sarak-jake220-reviews.json 같은 파일로 관리했다. 여기서 중요한 것은 파일 자체보다, 이 파일이 “수집 결과를 다른 단계에서 소비하는 계약”이 된다는 점이다. 이후 신청 댓글 생성 로직이나 글감 정리 흐름은 이 파일만 읽으면 된다.

개인 프로젝트에서 상태 파일은 종종 임시 캐시 취급을 받지만, 실제로는 작은 데이터 모델 역할을 한다. 그리고 이런 식의 느슨한 연결이 유지보수에는 오히려 유리하다.

링크 선별 기준: 전부 넣는 것이 최선은 아님

리뷰 링크가 자동으로 수집된다고 해서 문제 해결이 끝나는 것은 아니다. 전부 넣는 방식은 곧 또 다른 문제를 만든다.

링크가 계속 늘어나는 구조에서는 결국 댓글 길이가 과도해지고, 가독성이 떨어진다. 신청 댓글은 어디까지나 보조 자료여야지, 링크 모음집처럼 보여서는 안 된다. 반대로 너무 적게 넣으면 활동 이력이 약해 보이고, 최근 활동성이 잘 드러나지 않는다.

그래서 링크 노출에는 선별 기준을 넣었다.

현재는 아래 기준으로 최대 10개를 사용한다.

  • 평점 높은 순
  • 같은 평점이면 최신 작성일 순
  • 최대 10개까지만 사용

이 기준을 둔 이유도 나름 명확하다.

  • 최신성만 보면 최근 글이 많을 때 품질 편차가 그대로 노출된다.
  • 평점만 보면 오래된 리뷰가 상단을 독점할 수 있다.
  • 전부 노출하면 댓글이 본문보다 링크 목록처럼 보인다.

결국 “평점 우선 + 최신성 보정 + 개수 제한”이 가장 무난했다. 이건 완벽한 알고리즘이라기보다, 실제로 댓글을 읽는 사람 입장에서 길이, 신뢰도, 최신성의 균형을 맞춘 운영 정책에 가깝다.

중요한 점은, 이 기준이 내부 정책이라는 것이다. 실제 댓글에는 “평점 높은 최근 10개” 같은 설명을 드러내지 않는다. 시스템 내부는 선별 로직을 갖되, 외부 노출 텍스트는 아래처럼 단순하게 유지한다.

서평 신청합니다! 좋은 도서를 읽고 후기 남기고 싶습니다.

[사락 서평 링크]
...저장된 링크들

이렇게 하면 내부적으로는 더 나은 선택을 하면서도, 사용자에게 보이는 결과는 군더더기 없이 유지할 수 있다. 개인적으로 자동화 설계에서 이런 분리를 중요하게 본다. 내부 구현의 영리함이 사용자 경험을 복잡하게 만들어서는 안 되기 때문이다.

실제로 겪은 문제: 수집은 되는데 쓰기 좋은 데이터가 아니었던 순간

초기에 가장 단순한 버전은 “리뷰 URL만 모아두는” 방식이었다. 그런데 곧 문제가 드러났다. 링크만 저장하면 실제 사용 단계에서 다시 정렬 기준이 필요해지고, 어떤 링크가 최신인지, 어떤 글이 더 보여줄 만한지 판단할 근거가 부족했다.

즉, 수집은 성공했지만 소비하기 좋은 데이터 모델은 아니었던 것이다.

이 문제를 겪고 나서 저장 포맷을 다시 잡았다. URL만 저장하는 대신, 최소한 아래 정보는 같이 들고 가도록 바꿨다.

  • URL
  • 제목
  • 작성일
  • 평점
  • 마지막 갱신 시각

이렇게 바꾸고 나니 링크 선별 로직이 훨씬 단순해졌다. 정렬 규칙도 파일을 읽는 쪽에서 즉시 적용할 수 있었고, 나중에 다른 용도로 재활용하기도 쉬워졌다. 개인 자동화에서 데이터 모델을 너무 늦게 생각하면, 결국 뒤 단계에서 사람이 다시 해석 비용을 떠안게 된다.

주기적 갱신: 수집과 사용을 분리한 이유

사락 리뷰 링크는 신청할 때마다 즉흥적으로 가져오게 만들 수도 있었다. 하지만 운영 측면에서는 주기적으로 갱신된 상태 파일을 읽어오는 쪽이 더 안정적이었다.

그래서 리뷰 URL은 별도 스크립트로 주기적으로 갱신해 memory/sarak-jake220-reviews.json에 저장하도록 했다. 실행 주기는 매주 일요일로 두되, 실제로는 마지막 갱신 시점을 보고 14일 이내면 건너뛰게 해서 결과적으로 격주 업데이트처럼 운용했다.

이렇게 한 이유는 세 가지다.

  • 링크 목록이 댓글 작성 시점마다 흔들리지 않는다.
  • 신청 흐름에서 외부 요청이 줄어들어 실패 지점이 적어진다.
  • 수집 로직과 소비 로직을 독립적으로 수정할 수 있다.

즉, 신청 단계는 “이미 정리된 상태”를 읽기만 하면 된다. 수집과 사용을 한 트랜잭션으로 묶지 않으면 장애 범위가 줄어들고, 문제를 디버깅하기도 쉬워진다.

포스팅 흐름 자동화: 글을 대신 쓰게 하는 게 아니라 준비 비용을 줄이는 것

이 단계에서 흐름은 자연스럽게 포스팅 쪽으로 이어졌다. 이유는 단순하다. 책을 찾고, 신청하고, 읽고, 리뷰를 남기고, 그 기록을 다시 다음 활동에 연결하는 흐름 전체가 하나의 루프이기 때문이다.

흐름을 길게 보면 대략 이렇다.

  1. 모집글을 찾는다.
  2. 신청한다.
  3. 책을 받는다.
  4. 리뷰를 쓴다.
  5. 리뷰 링크가 쌓인다.
  6. 다음 신청에서 그 링크를 다시 활용한다.
  7. 의미 있는 자동화 경험은 블로그 포스팅으로 정리한다.

이렇게 보면 자동화는 단순히 신청 시간을 줄이는 도구가 아니다. 읽고, 쓰고, 기록하고, 다음 활동에 다시 연결하는 콘텐츠 파이프라인이 된다.

여기서 내가 줄이고 싶었던 것은 글쓰기 자체가 아니다. 오히려 글을 쓰기 전후에 반복적으로 붙는 준비 비용이었다.

예를 들면 이런 것들이다.

  • 어떤 주제를 글로 남길지 정리하는 일
  • 관련 링크나 스크립트 경로를 다시 찾는 일
  • 여러 시행착오 중 무엇을 핵심 서사로 남길지 고르는 일
  • 1부/2부 같은 구조로 나누고 목차를 잡는 일
  • 버그, 의사결정, 운영 원칙을 글로 풀 수 있는 단위로 재정리하는 일

즉, 포스팅 자동화의 핵심은 “글을 AI에게 대신 쓰게 한다”가 아니라, 내가 써야 할 글의 핵심에 더 빨리 도달할 수 있게 보조하는 것에 가깝다.

OpenClaw를 포스팅 보조 런타임으로 쓴 방식

이 부분에서도 OpenClaw를 단순 채팅 도구처럼 쓰지는 않았다. 오히려 자동화 과정에서 남아 있는 상태와 이벤트를 다시 글감으로 회수하는 인터페이스로 썼다.

예를 들면 아래 같은 흐름이다.

  • 수집/신청 자동화에서 남은 상태 파일을 읽는다.
  • 어떤 정책과 예외 처리가 있었는지 다시 추적한다.
  • 실제로 발생한 버그와 수정 이력을 대화로 정리한다.
  • 초안의 목차를 잡고, 사람이 최종 문제의식을 입힌다.

이렇게 하면 블로그 포스팅은 “기억을 더듬어 쓰는 글”이 아니라, 운영 흔적을 재구성해 만드는 글이 된다. 자동화를 잘 만들수록 글감도 더 선명해진다는 점이 흥미로웠다. 작업 로그가 곧 서사의 재료가 되는 셈이다.

기술적 의사결정: 자동화 범위보다 경계 설정이 더 중요함

이 작업을 하며 다시 느낀 것은, 자동화에서 더 중요한 것은 “얼마나 많이 자동화했는가”보다 어디서 멈출 것인가를 명확히 정하는 일이라는 점이다.

예를 들어 리뷰 링크 관리는 자동으로 수집하고 선별할 수 있지만, 글의 최종 표현이나 포스팅의 문제의식까지 전부 기계적으로 넘기는 것은 좋은 선택이 아니다. 링크를 자동으로 정리하는 것과, 그 링크를 바탕으로 어떤 이야기를 할 것인지 결정하는 일은 다른 층위의 문제이기 때문이다.

그래서 이번 자동화도 어디까지나 아래 선에서 끊었다.

  • 링크 수집과 정리는 자동화
  • 신청 댓글 반영은 자동화
  • 포스팅 소재 정리와 구조화는 자동화 보조
  • 최종 글의 톤과 문제의식은 사람이 결정

이 선을 지키는 편이 결국 더 좋은 결과를 만든다. 특히 글쓰기는 자동완성보다 사람의 경험과 판단이 남아 있어야 읽을 만한 기록이 되기 때문이다.

마무리: 작은 자동화가 작업 방식을 바꾸는 순간

서평 자동화를 만들기 전에는 이 작업이 그냥 자잘한 생활 편의 개선에 가깝다고 생각했다. 그런데 막상 만들어보니, 이건 단순히 몇 분을 아끼는 수준의 문제가 아니었다.

조회 자동화는 모집글 확인이라는 반복 작업을 줄였고, 신청 자동화는 외부 행동의 실행 비용을 줄였으며, 리뷰 링크 관리 자동화는 그 결과물이 다시 다음 활동의 근거가 되도록 연결했다. 그리고 그 위에서 포스팅 보조 흐름까지 붙이자, 자동화는 시간을 절약하는 도구를 넘어 개인의 읽기와 기록 루틴을 구조화하는 장치가 됐다.

개인적으로 OpenClaw를 흥미롭게 본 이유도 여기에 있다. 단순한 대화형 도구를 넘어서, 크론과 상태 파일, 브라우저 자동화, 메시지 인터페이스를 묶고, 나중에는 그 운영 흔적을 다시 글쓰기 재료로 회수하는 런타임처럼 쓸 수 있었기 때문이다.

이번 2부에서 남은 교훈은 이렇다.

  • 자동화의 핵심은 버튼 클릭 대행보다 상태를 기억하고 재사용하는 구조에 있다.
  • 수집 데이터는 “모을 수 있느냐”보다 바로 소비 가능한 형태냐가 더 중요하다.
  • 외부 노출 텍스트는 단순하게, 내부 정책은 유연하게 분리하는 편이 오래 간다.
  • 포스팅 자동화의 목표는 글 대행이 아니라 글쓰기 전후의 준비 비용 절감에 가깝다.

결국 자동화는 거창한 문제에서만 의미가 생기는 것이 아니다. 반복되지만 자주 미뤄지는 일, 사소하지만 계속 시간을 잡아먹는 일, 그래서 늘 “언젠가 정리해야지”라고 생각하게 만드는 일에서 오히려 더 큰 효과가 난다.

책을 읽고 기록하는 흐름 전체를 자동화 관점에서 다시 바라보니, 자연스럽게 다음 글감과 다음 자동화 포인트까지 이어졌다.