Jinyoung Hong

Journal of building things, business and life

Threads API

  • Day 11 · 실행하기 (5)

    어제 일지를 “내일 아침엔 Actions 목록부터 확인해야겠다”로 끝냈는데,
    아침에 눈 뜨자마자 확인해 보니..
    새벽 1시 50분에 실행됐다 ^^;
    GitHub Actions 예약 지연, 이틀 연속이다.

    수요일 20:17 예약이 GitHub 대기열에서 5시간 넘게 밀려 목요일 새벽에 돈 것.
    스크립트는 실제 실행 시각을 기준으로 요일을 정해서
    목요일 주제인 ‘우월 기능 소개’ 글이 새벽에 올라갔고, 링크 댓글까지 야무지게 달렸다.
    결과적으로 수요일 글은 증발하고, 목요일 글은 새벽 배송 ㅋㅋ

    이틀 연속 이러니 결심했다.
    GitHub 예약은 지연이 들쭉날쭉해서 시간을 당기든 미루든 해결이 안 된다.
    어제 말해둔 플랜 B, cron-job.org로 갈아타기로!

    GitHub Actions 예약 지연 탈출기

    원래는 GitHub이 정해진 시간에 알아서 워크플로를 실행하는 구조였다.
    이제는 외부 예약 서비스(cron-job.org)가 정해진 시간에 GitHub API를 직접 호출해서 실행시킨다.
    대기열을 안 거치니 시간이 정확하다.

    1. 실행용 토큰 발급
      cronjob-trigger라는 이름의 Fine-grained 토큰을 만들었다. 이 저장소만, Actions 읽기/쓰기 권한만 딱.
      터미널에서 curl로 dry_run = 1 호출을 보내서 204 응답과 Actions 실행(#10)까지 확인!
    2. cron-job.org 설정
      매일 21:00(Asia/Seoul)에 GitHub API로 POST, 헤더 4개, 본문은 dry_run = 0. 실패하면 메일 알림이 오게 했다.
      TEST RUN을 돌려보니 204 응답, Actions #11에서 “오늘 이미 게시함”으로 얌전히 건너뜀. (새벽에 이미 올라갔으니까 ^^)
    3. GitHub 예약 제거
      daily-post.yml에서 schedule을 지웠다. 안 지우면 새벽에 또 중복으로 돌 수 있으니까.
      토큰 자동 갱신 단계는 예약 실행 대신 실제 게시 실행(dry_run ≠ 1)에서 돌도록 조건을 바꿨다. 갱신은 여전히 월요일에만!
    4. 뒷정리
      터미널에 남은 토큰 변수는 unset으로 깔끔하게 정리.
    github action 성공 리스트
    cron-job.org GitHub Actions 예약 실행 설정 화면

    예약 시간은 다시 21:00으로 돌아왔다.
    어제는 정각이 붐빈다고 20:17로 피했는데, 이제 대기열을 안 타니 굳이 피할 이유가 없다 ^ㅁ^

    남은 확인

    오늘(목) 21시: 정각쯤 실행이 찍히고 “오늘 이미 게시함”이 뜨면 성공. cron-job.org의 첫 정시 호출 테스트다.
    내일(금) 21시: 드디어 첫 정시 게시! ‘참여 유도 질문’ 글이 21시 직후에 올라오는지, 반말이랑 태그는 잘 붙었는지 볼 예정.

    그리고, 특허

    10월 목표 4번 ‘특허 준비’도 오늘 첫발을 뗐다.
    변리사님과 통화로 상담을 받고,
    특허 검토 요청 자료를 정리해서 메일로 보냈다.
    무슨 내용인지는… 출원 전이라 비밀 ^^
    답장 오면 또 기록해야지.

    봇 돌보기 3일 차.
    내일 저녁 9시엔 제발 제시간에 올라와 주라 ㅠㅠ

    (새벽 배송 사건의 시작은 Day 10 · 실행하기 (4)에서 ^^)

  • Day 10 · 실행하기 (4)

    어제 만든 스레드 자동포스팅 봇이
    만든 지 하루 만에 사고를 쳤다 ㅠㅠ
    새벽 2시 12분, GitHub에서 날아온 메일 한 통.
    Daily Threads Post 실패…!!!!!!!!

    (뭐 하나 쉽게 되는 일이 없지 하여간 ^^……..)

    로그를 열어보니 원인은 두 가지였다.
    하나는 Threads에 올리는 단계에서 API access blocked (code 200) 오류.
    글 생성까지는 멀쩡히 됐는데, 올리는 순간 막힌 것이다.
    다른 하나는 화요일 21시에 돌았어야 할 예약 실행이
    GitHub 서버 사정으로 5시간 넘게 밀려서 새벽에 실행된 것 ^^;
    (저녁 9시에 올라가야 할 글이 새벽 2시에 올라갈 뻔했다..)

    Meta 개발자 사이트에 로그인해 보니 로봇이 아님을 인증하라는 요청이 떠 있었다.
    인증하고 나니 계정은 바로 복원 완료.
    생각해 보면 의심받을 만했다..
    새로 만든 Facebook 계정으로 가입하자마자 개발자 등록하고, API로 게시하고,
    테스트한다고 몇 분 사이에 게시·삭제를 여러 번 반복했으니..
    누가 봐도 봇이다. (실제로 봇이긴 함 ^^)

    Analyze Tags를 돌려서 토큰도 살아 있고 API 차단도 풀린 것까지 확인했다. 휴,,

    차단 풀린 김에 태그도 손봤다.
    지난 게시글 1,254개를 분석해서 태그를 다시 정리했는데,
    주제 태그는 ‘결혼준비’와 ‘결혼준비 스하리2000명프로젝트’를 2:1 비율로 쓰고,
    본문 해시태그는 예비부부, 결혼비용, 웨딩트렌드, 결혼준비, 스드메, 웨딩꿀팁, 웨딩예산, 예식장, 예산자동관리, 체크리스트, 스하리 중에서 랜덤으로 뽑아
    3~5개씩 달리게 했다.
    물론 #우월은 무조건 고정 ^ㅁ^

    예약 시간도 21:00 → 20:17로 바꿨다.
    정각은 다들 예약을 걸어두는 시간이라 붐비니까, 애매한 시간으로 살짝 피해 가기로.
    지연 방지 코드는 일단 보류. 문제가 또 생기면 그때 넣기로 했다.

    그리고 재차단을 막기 위해 개발자용 Facebook 계정에 프로필 사진도 넣고, 2단계 인증까지 완료했다.
    사람인 척(?) 열심히 하는 중..

    그리고 저녁 9시, 두근두근하며 스레드를 확인했는데….
    글이 안 올라왔다 ㅠㅠㅠㅠㅠ
    Actions 목록을 봤더니 오늘 예약 실행 기록 자체가 없다.
    실패한 게 아니라 아직 대기열에서 순서를 기다리는 중인 것 같다.
    GitHub 예약 실행은 정확한 시간을 보장해 주지 않아서
    서버가 붐비면 몇 시간씩 밀리거나 아예 취소될 수도 있다고 한다.
    알고 쓰긴 했지만 이틀 연속 이러니 좀 서운하다 ^^;

    (현시간 워크플로우,,, 왜 왜왜 아직도 대기열인거야!??!!? ㅠㅁㅠ)

    내일 아침엔 Actions 목록부터 확인해야겠다.
    자정 전에 돌아서 올라갔으면 얼마나 밀렸는지 확인하고,
    자정 넘어서 돌았으면 목요일 글이 새벽에 올라갔을 거고 (그럼 목요일 저녁 실행은 건너뛰게 된다),
    기록 자체가 없으면 GitHub이 대기 중인 실행을 취소해 버린 거다.

    지연이 계속 반복되면 cron-job.org 같은 외부 예약 서비스로 정확한 시간에 워크플로를 호출하는 방식으로 바꾸고,
    그때 지연 방지 코드도 같이 넣을 예정이다.

    당분간 지킬 규칙: 수동으로 실제 게시는 금지, 테스트는 dry_run = 1로만!
    또 차단당하면 이번엔 진짜 울어버릴지도 ㅠㅠ

    자동화하면 편해질 줄 알았는데, 자동화를 돌보는 일이 또 생겼다 ^^;
    그래도 매일 저녁 알아서 글이 올라가는 그날까지..!

    (배포 삽질기는 Day 08 · 실행하기 (2)에서 ^^)

  • Day 09 · 실행하기 (3)

    오늘은 iOS 심사 통과 소식과 함께, 드디어 스레드 자동화를 만든 날이다!

    오늘은 진짜 내가 기억하는 한 처음으로 iOS 심사가 한 방에 통과한 기념적인 날이다!!!!!
    새벽 3시 50분쯤 실눈으로 휴대폰 알람을 확인하는 순간,,
    심사 통과가 되고 1.1.9(21) 버전으로 배포가 정상적으로 되어 있었다 ^^
    (어제 분명 호락호락하지 않을 것 같다고 썼는데 ㅎ 기분이가 좋다 우하하)

    오늘의 우선순위는 (iOS 심사 대응을 안 해도 되기 때문에 ^^)
    아주 기본적인,, 마케팅용으로 스레드 자동 글쓰기 스크립트를 개발할 계획이었다.
    월초에 9월에 꼭 해야 할 일로 AOS, iOS 배포 (및 묵은 로그인 이슈 해결)
    그리고 스레드 자동화!! 새삼 세상 너무 좋아졌다 느낀다… (메모장에 코딩했던 시절도 있는데 ㅎ)

    스레드 자동화 개발에 앞서
    모두의창업 2차 지원 결과를 트래킹하고 있는데,,
    결과는 아직이지만 어제 링크드인, 디스콰이엇에 프로필 업데이트한 김에
    모두의창업 홈페이지 내에 내 프로필도 링크드인, 디스콰이엇과 통일해서
    업데이트해 줬다. (어제 널리널리 알리기로 했으니, 업데이트하면서 다시 한번 ‘우월’의 의미를 각성하였다. 그리고 링크드인은 어떻게 사용하는 건지 아직 어색하기도 하고 잘 모르겠슨 ㅠㅠㅠㅠ)

    (팔로워는 1명도 없.. 팔로우 좀 해 주세요 ^_ㅠ)

    그리고,, 본격적으로 스레드 글쓰기 자동화를 진행하였다.

    1. 프로젝트 만들기

    맥에 ourwallet-threads-bot 폴더를 만들고, 터미널에서 파일 6개를 생성했다: post.py, refresh_token.py, requirements.txt, posts_history.json, README.md, .github/workflows/daily-post.yml
    brew install gh로 GitHub CLI를 설치하고 gh auth login으로 로그인.
    gh repo create로 private 저장소를 만들고 업로드했다.

    2. Claude API 연결

    우월 전용 계정으로 Claude Console에 가입하고, 5달러를 충전(내가 하려는 작업으로는 5~6개월까지도 쓸 만큼 작은 비용이라고 함). 자동 충전은 꺼짐 상태로 두었다.
    API 키(threads-bot, 만료 없음)를 발급하고 cURL로 동작을 확인했다.
    GitHub Secrets에 ANTHROPIC_API_KEY로 등록했다.
    Actions에서 dry_run = 1로 테스트해서 글 생성을 확인했다.

    3. Threads API 연결

    Meta 개발자 계정(우월 이메일, 실명)을 만들고 앱 OurWallet Poster를 생성. 이용 사례는 Threads API 액세스를 선택.
    권한 threads_basic, threads_content_publish를 확인했고, 앱 역할에 _superiority.official을 Threads 테스터로 추가, Threads의 설정 → 계정 → 웹사이트 권한에서 초대를 수락했다.
    토큰 생성기에서 _superiority.official로 로그인해 장기 토큰을 발급했다.
    /me 호출로 계정을 확인한 뒤 gh secret set으로 THREADS_ACCESS_TOKEN을 등록했다.
    토큰 자동 갱신용 GitHub Fine-grained 토큰(이 저장소만, Secrets 읽기/쓰기)을 GH_PAT으로 등록했다.
    플레이스토어 링크를 Variables에 ANDROID_URL로 등록했다.

    4. 첫 게시와 개선

    dry_run = 0으로 첫 실제 게시에 성공했지만, 기존 내 게시글이 반말 톤이었기 때문에 말투를 반말로 통일함.
    dry_run이 중복 게시 검사에 막히던 버그를 수정하고, 태그 방식을 업데이트함.
    주제 태그 1개는 API 옵션(topic_tag)으로 지정하고, 본문 해시태그 3~5개(#우월 고정 + 랜덤)는 코드가 붙이는 방식.
    태그 분석 스크립트(analyze_tags.py)와 수동 실행 워크플로(Analyze Tags)를 추가하고, 게시 기록 초기화 및 새 방식으로 재게시했다.

    – 스레드 자동화, 지금 동작하는 방식

    매일 21시(KST)에 GitHub Actions가 실행되는 중이다.
    Claude Sonnet 5.5가 요일별 주제로 반말 글을 쓰고, 태그를 붙여 Threads에 올린 뒤 기록을 깃에 커밋하고 있다.
    목·일요일에는 다운로드 링크를 댓글로 달고, 매주 월요일에는 Threads 토큰을 자동으로 갱신한다.
    (비용은 월 1달러 안팎이라고 함 ^ㅇ^ 매우 저렴해서 마음에 든다.)

    – 남은 할 일

    • 내일 21시 반쯤: 첫 자동 게시 확인 (Threads + Actions의 schedule 실행)
    • Analyze Tags 실행: 결과를 보고 KEYWORD_TAGS 목록 다듬기
    • 첫 일주일: 매일 글 톤을 확인하고 필요하면 요일별 프롬프트 조정

    너무나 신기한 경험이었다.
    우월 덕에 오늘도 이런 신문물을 알게 되는구나!

    <=========결과물===========>

    (우왕우왕 진짜 왕신기 ㅎㅎㅎㅎㅎ)

    스레드 운영해 보고 돈 조금 더 들여서
    올해 안으로 숏폼 자동화 인스타 업로드도 반영해야겠다.

    할 일이 산더미네!!!!!!! 요즘 너무 재밌다 ^ㅇ^