자동 게시의 어려운 부분은 ‘게시 버튼’이 아니다 — 12개 언어 SNS·뉴스레터를 멈추지 않고 운영하는 설계

읽기 기능 사용법

듣기는 본문을 읽어 줍니다. 속독은 구절을 차례로 표시하며 속도를 조절할 수 있습니다. 언어 연습은 다른 언어판과 번역을 비교합니다. 저장한 북마크는 이 브라우저의 플레이어 목록에서 다시 열 수 있습니다.

이 글 공유하기

이 글 공유하기

광고
광고

SNS 자동화를 “정해진 시간에 올리기”와 “AI가 문구 쓰기”로만 보면 핵심을 놓친다.

진짜 어려운 일은 검증된 글만 배포하고, 중복 게시를 막고, 한 계정의 장애를 전체 장애로 만들지 않고, CAPTCHA 같은 인간 전용 절차를 정직하게 사람에게 넘기며, 이후의 독서 행동을 다음 배포에 반영하는 것이다.

여러 언어와 여러 플랫폼을 다루기 시작하면 배포 시스템은 예약 게시기가 아니라 작은 분산 시스템이 된다.

1. 목표는 ‘완전 무인’이 아니라 ‘사람은 예외만 처리’

CAPTCHA, SMS 인증, 2FA, 본인 확인, 명시적 약관 동의, 개발자 앱 심사는 자동화가 억지로 우회해야 하는 오류가 아니다. 플랫폼이 의도적으로 사람을 요구하는 경계다.

따라서 정상 흐름은 글 생성 → QA → 현지화 → 실제 배포 → 본문 readback → 배포 후보 → locale별 문구 → 전송 → 성과 수집 → 다음 배포 판단이다.

한 계정에서 CAPTCHA가 나오면 그 계정만 기다린다. 다른 언어, 다른 SNS, 뉴스레터, 분석, 다음 글 생성까지 같이 멈출 이유는 없다.

Cloudflare Workflows도 장시간 상태 보존, 자동 재시도, 외부 이벤트나 인간 승인 대기를 지원한다.[1] 중요한 것은 특정 제품이 아니라 ‘사람 대기’를 전체 장애가 아닌 하나의 상태로 모델링하는 것이다.

2. ‘글이 존재한다’와 ‘배포해도 된다’를 분리한다

저장소에 Markdown이 있다고 독자가 완성 페이지를 읽을 수 있는 것은 아니다. 번역 완료나 빌드 성공도 충분한 증거가 아니다.

콘텐츠의 배포 단위는 articleId × locale × contentSha 로 잡고, 실제 전송은 articleId × locale × contentSha × platform × campaignType 으로 확장한다.

contentSha가 있어야 같은 URL의 새 revision과 이전 revision을 구분할 수 있다.

가장 안전한 게이트는 실제 production HTML readback이다. 정확한 locale과 정확한 content revision이 공개된 것을 확인한 뒤 배포 작업을 만든다.

3. timeout은 실패가 아니다. 잘못 재시도하면 쌍둥이 게시물이 생긴다

API에 게시 요청을 보냈는데 응답 전에 timeout이 났다고 하자. provider가 게시를 안 했을 수도 있고, 게시한 뒤 응답만 끊겼을 수도 있다.

그 순간 무조건 재전송하면 중복 게시가 생긴다.

Cloudflare Queues는 기본적으로 at-least-once delivery이므로 드물게 같은 메시지가 두 번 이상 전달될 수 있고, 공식 문서도 unique ID와 idempotency key를 통한 중복 제거를 권장한다.[2]

예를 들어 sha256(articleId + locale + contentSha + platform + campaignType) 같은 결정적 키를 만들고 receipt에 UNIQUE 제약을 둔다.

애매한 timeout 뒤에는 receipt와 provider readback을 먼저 확인하고 실제 효과가 없을 때만 재시도한다.

핵심은 “코드가 정확히 한 번만 실행”이 아니라 “여러 번 실행돼도 외부 결과는 한 번으로 수렴”이다.

4. 장애는 가장 작은 scope에 가둔다

최소 failure domain은 platform × locale × account 정도로 나눈다.

한 한국어 계정 인증이 끊기면 그 계정만 BLOCKED, 한 영어 채널이 rate limit이면 그 채널만 RETRY_WAIT, 본인 확인이 필요하면 해당 scope만 HUMAN_ACTION_REQUIRED다.

상태도 READY, ACTIVE, DEGRADED_BUT_RUNNING, HUMAN_ACTION_REQUIRED, BLOCKED_PROVIDER, RETRY_WAIT, DISABLED_BY_POLICY처럼 구체적으로 둔다.

429는 Retry-After를 존중하고, 5xx는 제한된 exponential backoff를 사용한다. 401/403은 공식 credential refresh 경로를 한 번 시도한 뒤 실패하면 해당 계정만 막는다.

CAPTCHA를 무한 retry한다고 API가 인간이 되지는 않는다.

5. Human Handoff Queue는 ‘확인해주세요’가 아니라 실행 가능한 지시서다

사람에게 “SNS가 멈췄습니다. 확인해주세요”라고 던지면 자동화가 마지막 순간에 일을 통째로 사람에게 돌려준 셈이다.

좋은 handoff에는 platform, locale, account, blocker 종류, 시각, URL, 정확히 할 일, 하지 말아야 할 변경, 완료 후 자동 시스템이 다시 확인할 내용, 막히는 scope가 포함된다.

예를 들어 “공식 계정에 로그인해 현재 표시된 CAPTCHA만 완료하세요. 프로필과 게시 설정은 바꾸지 마세요. 이후 다음 자동 순회에서 인증을 읽고 canary 게시부터 재개합니다”라면 한 번에 이해된다.

CAPTCHA solver나 challenge 위장은 사용하지 않는다. 사람은 반복 게시 담당자가 아니라 시스템이 정당하게 넘을 수 없는 경계만 처리한다.

password, OAuth token, session cookie, SMS/2FA code, recovery code, private API secret는 GitHub와 일반 log에 저장하지 않는다. public handle, state, sanitized error, receipt ID, public post URL 같은 비밀이 아닌 운영 정보만 남긴다.

6. 자동 게시와 engagement bot을 섞지 않는다

자기 사이트 글을 자동 게시하는 것과 자동 좋아요·팔로우·댓글·DM은 서로 다른 위험과 정책을 가진다.

X의 2026년 4월 Automation Rules는 규정에 맞는 정보성 자동 게시를 허용하지만 rate limit 우회, 비API 웹사이트 스크립팅, 스팸·중복 행위, 자동 좋아요를 금지한다.[3]

그래서 초기값은 게시만 켜고 나머지는 끄는 편이 안전하다.

Bluesky 공식 API는 일반 post record와 langs 같은 언어 metadata를 지원한다.[4] 다국어에서는 실제 locale과 metadata를 맞추는 것이 자연스럽다.

정기 전송은 가능한 한 공식 API와 공식 인증을 사용하고, reverse-engineered 내부 API를 상시 경로로 만들지 않는다.

초기 channel map은 ja→X, en→X/Bluesky, ko→X, zh-Hans→Weibo, zh-Hant→Facebook/Threads, es·pt-BR·id·th·vi·fr→Facebook, de→Facebook/X처럼 locale별로 둘 수 있다. Instagram, TikTok, Reels는 자동 media card 생성과 QA가 안정된 뒤 두 번째 단계로 미룬다. 구현 시점에는 각 platform의 최신 API와 automation policy를 다시 확인한다.

7. 12개 언어는 일본어 SNS 문구 하나를 번역하는 작업이 아니다

각 locale에 실제 본문이 있다면, SNS 문구도 그 본문을 읽고 독립적으로 만든다.

형식은 짧아도 된다. 공식 사이트 계정이 자기 글을 읽고 자연스럽게 한마디 남기고 URL을 붙이는 정도다.

“필독”, “충격”, “지금 확인” 같은 과장 광고는 피하고, 제3자의 후기를 가장한 문구도 만들지 않는다.

브랜드는 하나지만 표현은 각 언어에서 자연스러워야 한다.

의료, 법률, 투자, 큰돈, 재난, 범죄, 사망, 자해, 폭력, 성폭력, 미성년자, 안전, 정치·선거, 강한 갈등은 serious mode로 전환한다. 기본적으로 emoji 없이 중립적으로 쓰고, 글보다 강한 주장이나 정치적 지지를 덧붙이지 않는다.

8. 뉴스레터도 같은 배포 철학을 가진 별도 adapter다

뉴스레터는 explicit opt-in, locale, topic, consentAt, status, unsubscribeAt, createdAt를 관리하고 같은 글을 반복 발송하지 않도록 한다.

문의용 inbox와 대량 발송 기반도 논리적으로 분리한다. 답장 주소는 기존 지원 창구를 쓸 수 있지만 발송 provider는 나중에 교체 가능한 adapter로 둔다.

Gmail의 sender guidance는 대량 발송자에게 인증, 원치 않는 메일 회피, 쉬운 unsubscribe를 요구하며 subscription message에서도 해지 기능을 중요하게 다룬다.[5][6]

구독 해지는 다음 달 언젠가가 아니라 향후 캠페인 대상에서 즉시 빠져야 한다.

9. ‘좋아요’를 최적화하면 좋아요를 얻는 기계가 된다

기사 사이트의 좋은 목적함수는 좋아요보다 site visit, meaningful reading, next article, return visit, newsletter signup에 가깝다.

캠페인은 NEW, UPDATED, TRENDING, POPULAR, EVERGREEN으로 나눌 수 있다.

사소한 오탈자 수정은 UPDATED가 아니다. 인기·트렌드도 이미 있는 1st-party 독서 데이터를 재사용하고 별도의 두 번째 인기 순위를 만들지 않는다.

시간대 역시 고정 관념보다 실제 locale × country × platform × weekday × hour 데이터를 보고 탐색한다.

10. 실제 사용법은 ‘게시’가 아니라 상태를 앞으로 이동시키는 것

운영 순서는 다음과 같다.

정확한 locale revision 공개 → production HTML readback → 배포 identity 생성 → locale 본문 기반 문구 생성 → 정책·serious mode 검증 → idempotency key와 함께 outbox → 공식 API 전송 → receipt와 public readback → 독서 행동 attribution → 다음 캠페인 판단.

처음에는 adapter마다 하나의 canary만 실행한다. auth readback, dry run, 실제 글 1건, receipt, public readback, locale 확인, duplicate suppression, analytics attribution을 검증한 다음 넓힌다.

운영자가 보는 상태도 하나의 current-status view로 모은다.

구조적으로는 배포만을 위한 두 번째 article factory나 두 번째 scheduler를 만들기보다, PRODUCTION_VERIFIED 이후 post-publication child로 기존 publication owner에 연결하고 가능한 경우 기존 durable runtime/state store를 재사용한다.

좋은 자동화는 실패가 없는 시스템이 아니다. 실패 위치가 명확하고, 피해 범위가 작고, 합법적인 복구 경로가 있고, 필요한 경우 사람에게 정확한 1건만 넘기며, 복구 뒤 중복 없이 이어지는 시스템이다.

게시 버튼을 없애는 것은 시작일 뿐이다.

진짜 자동화는 실패한 날까지 설계한다.


  1. Cloudflare — “Cloudflare Workflows” (updated 2026-09-18) Used for durable multi-step execution, automatic retries, persistent state, and waiting for external events or human approval. The article does not imply that a separate workflow or scheduler must be created when an existing stateful runtime already provides the needed function developers.cloudflare.com
  2. Cloudflare — “Delivery guarantees” (Cloudflare Queues, updated 2026-04-21) Used for the fact that Queues uses at-least-once delivery by default, rare duplicate delivery can occur, and unique IDs / idempotency keys are recommended when duplicate processing would create unintended effects developers.cloudflare.com
  3. X Help — “Automation rules” (updated 2026-04) Used for the distinction between compliant informational automated posts and prohibited behavior such as rate-limit circumvention, non-API website scripting, spam/duplicative use, and automated likes help.x.com
  4. Bluesky Protocol Services — “Creating a post” Used for official post creation, returned post identifiers, and language metadata through the langs field docs.bsky.app
  5. Gmail Help — “Email sender guidelines FAQ” Used for current high-volume sender requirements around authentication, unwanted mail, and easy unsubscribe support.google.com
  6. Gmail Help — “Learn about bulk email best practices” Used for explicit consent, clear sender identity, non-deceptive content, unsubscribe, and reasonable sending frequency support.google.com

이 글 공유하기

광고

다른 글 찾기

모든 기사

Mendoi-chan

이 글을 쓴 사람

Mendoi-chan

직장과 일상의 불편함을 구조화해 이해하기 쉬운 다음 행동으로 연결하는 글을 씁니다.

사이트 소개
광고

새 글

  1. 1광고가 사라지면 수익도 끝일까? AdBlock 시대의 ‘광고가 0이어도 돈이 남는’ 수익 구조
  2. 2제휴 링크 하나 달고 싶었을 뿐인데 W-8BEN, Payoneer, 여권, 주소 증명까지 소환됐다
  3. 3AI 자동화가 ‘무한 마인크래프트’가 된 날
  4. 4AI 금지는 정말 역량을 지키는가? 미정의·선의 운영·선의 론더링을 드러내는 AI를 두려워하는 직장
  5. 5AI는 ‘질문 상자’에서 ‘회사를 압축하는 장치’로――혼자 가게와 공장을 운영하는 새로운 방법

함께 읽으면 좋은 글

광고