클로드에게 '인스타 올려줘' 한마디로 자동 업로드하는 법, 처음이어도 따라 하는 10단계

표지
인스타를 꾸준히 하다 보면 '올리는 일' 자체가 숙제가 됩니다. 사진은 다 만들어 놨는데 올릴 시간을 놓치고, 바빠서 폰을 못 보고, 그러다 한 주가 훌쩍 비어 버리죠.
그래서 오늘은 클로드(Claude)에게 "인스타 올려줘" 한마디만 하면 게시물이 올라가게 만드는 방법을 알려 드릴게요. 날짜를 말하면 예약도 돼요. 예약한 게시물은 PC가 꺼져 있어도 그날 아침 알아서 올라갑니다.
코딩은 몰라도 괜찮아요. 필요한 코드는 이 글에 다 들어 있고, 복사해서 붙여 넣기만 하면 됩니다. 누를 버튼은 전부 화면에 빨간 네모와 번호로 표시해 두었어요. 번호 순서대로만 누르면 됩니다.
오늘 할 순서 (목차)
LEVEL 1. 어떻게 돌아가는지 보기
LEVEL 2. 인스타를 프로페셔널 계정으로 바꾸기 (폰)
LEVEL 3. Meta 개발자 사이트에서 앱 만들기
LEVEL 4. 인스타그램 API 켜고 올리기 허락 받기
LEVEL 5. 내 인스타 계정을 테스터로 등록하기
LEVEL 6. 인스타 열쇠(토큰)와 계정 번호 받기
LEVEL 7. GitHub 가입하고 저장소 만들기
LEVEL 8. GitHub에 코드 파일 2개 올리기
LEVEL 9. 인스타 열쇠를 금고(Secrets)에 넣기
LEVEL 10. 클로드 연결하고 "올려줘" 해 보기
그리고 사진 준비 규칙 · ⚠️ 토큰 연장 · 클로드 없이 올리는 법 · 막혔을 때 · 체크리스트
시작하기 전에 알아 둘 4가지
1) 클로드 유료 구독이 필요해요. 나머지는 모두 무료예요.

필요한 비용 정리
조금 더 자세히 말하면 이렇습니다.
· 클로드: 이 방법은 '클로드 코드'라는 기능을 써요. 클로드 무료 요금제에는 이 기능이 없어서 Pro 이상 구독이 필요해요. Pro는 월 20달러(1년치를 한 번에 내면 월 17달러, 세금 별도)예요. 이미 구독 중이라면 추가로 낼 돈은 없어요.
· 인스타그램 API(프로그램이 인스타에 글을 올리는 통로)는 Meta가 사용료를 받지 않아요. 대신 하루(24시간)에 100개까지만 올릴 수 있는데, 개인이 쓰기엔 넉넉합니다.
· GitHub와 GitHub Actions(자동으로 일해 주는 로봇)는 공개(Public) 저장소에서 무료예요. 이 방법은 인스타가 사진을 인터넷 주소로 가져가야 해서 어차피 공개 저장소로 만들어요. 그래서 따로 돈 낼 일이 없습니다.
· GitHub나 Meta에서 카드 등록이나 '유료 플랜으로 바꾸기'가 보여도 누르지 않아도 돼요.
2) PC가 필요해요. 클로드 코드는 PC(윈도우·맥)에서 돌아가요. 처음 세팅은 1시간쯤 잡아 주세요.
3) 메모장을 하나 열어 두세요. 따라 하다 보면 적어 둘 게 6개 생겨요. 인스타 계정 번호, 인스타 토큰, 토큰 받은 날짜, GitHub 아이디, 저장소 이름, GitHub 토큰. 나오는 대로 메모장에 차곡차곡 적어 두면 뒤에서 훨씬 편해요.
4) 세팅 뒤에도 60일에 한 번, 1분짜리 숙제가 있어요. 인스타 '토큰'이라는 열쇠를 새로 바꿔 끼우는 일입니다. 이걸 잊으면 자동 업로드가 어느 날 조용히 멈춰요. 방법은 LEVEL 10 뒤의 '60일마다 인스타 토큰 연장'에 그림으로 정리해 두었어요.
하루에 한두 개를 직접 만들어 시간만 예약하면 되는 경우라면, 인스타 앱에 있는 예약 기능이나 Meta Business Suite로도 충분해요. 이 글은 말 한마디로 올리고, 한 번 만들어 두면 사람 손 없이 계속 올라가는 '진짜 자동'을 만드는 방법입니다.
LEVEL 1. 어떻게 돌아가는지 먼저 봐요 (3분)
길을 알고 출발하면 중간에 헤매지 않아요. 전체 모습은 이렇습니다.

클로드로 인스타 자동 업로드 전체 흐름
① 내 PC에 게시물 폴더를 만들고 사진과 캡션을 넣어요.
② 클로드에게 "올려줘"라고 말하고, 클로드가 보여 주는 사진과 캡션을 확인해요.
③ 클로드가 사진을 GitHub(깃허브)라는 무료 인터넷 창고에 올려요. 인스타는 사진을 '인터넷 주소'로만 받아 가서, 사진이 인터넷에 올라가 있어야 하거든요.
④ GitHub에 사는 무료 로봇(GitHub Actions)이 발행 코드를 실행해요. 예약한 게시물은 그날 아침 로봇이 스스로 일어나 올려서, 내 PC가 꺼져 있어도 돼요.
⑤ 인스타그램이 열쇠(토큰)를 확인하고 내 인스타에 올려요.
준비물은 이래요. 인스타 계정(LEVEL 2에서 프로페셔널 계정으로 바꿔요), 페이스북 계정(Meta 개발자 계정으로 로그인할 때 써요), GitHub 계정(LEVEL 7에서 같이 만들어요), 클로드 Pro 이상 구독, 그리고 PC.
글에 계속 나오는 어려운 말 다섯 개만 미리 쉽게 바꿔 둘게요.
· 클로드 코드 — 클로드가 내 PC에서 파일을 보고 프로그램을 실행해 주는 기능. 이게 있어야 "올려줘"가 돼요
· API — 프로그램이 인스타에 글을 올릴 수 있게 열어 둔 문
· 토큰 — 문을 여는 열쇠. 이 글엔 두 개가 나와요. 인스타 토큰(60일마다 연장)과 GitHub 토큰(기한 없이 만들 수 있어요)
· 저장소(repository) — GitHub에 만드는 인터넷 폴더
· 워크플로(workflow) — 로봇에게 주는 일 순서표
✔ 확인: 흐름이 대충 이해됐다면 다음으로 넘어가요. 다 몰라도 괜찮습니다. 따라 하다 보면 알게 돼요.
LEVEL 2. 인스타를 '프로페셔널 계정'으로 바꿔요 (3분)
자동 업로드는 프로페셔널 계정에서만 돼요. 개인 계정이라면 먼저 바꿔 주세요. 돈은 들지 않고, 나중에 다시 개인 계정으로 돌릴 수도 있어요. 이 단계는 폰의 인스타 앱에서 합니다.

인스타 앱에서 프로페셔널 계정으로 전환 (예시 그림)
① 내 프로필 → 오른쪽 위 ≡ 메뉴 → 설정 및 활동에서 계정 유형 및 도구를 눌러요.
② 프로페셔널 계정으로 전환을 눌러요.
③ 크리에이터와 비즈니스 중 아무거나 골라도 돼요. 나머지 질문은 대충 골라도 괜찮습니다.
✔ 확인: 내 프로필에 '프로페셔널 대시보드'라는 글자가 보이면 성공!
LEVEL 3. Meta 개발자 사이트에서 '앱'을 만들어요 (7분)
'앱'이라고 하니 어렵게 들리죠? 진짜 앱을 만드는 게 아니에요. 인스타에게 "이 프로그램은 내가 허락한 거야"라고 보여 줄 출입증을 만드는 거예요.
여기부터는 PC로 해요. 인터넷 주소창에 developers.facebook.com을 치고 들어가요. 로그인이 안 되어 있으면 아래 화면이 나와요.

Meta for Developers 로그인 화면
① Facebook으로 계속하기를 눌러 페이스북 계정으로 로그인해요.
Meta 개발자 사이트가 처음이라면, 로그인한 뒤 개발자 등록을 한 번 해야 해요. 아래 4단계예요.

처음 한 번만 하는 Meta 개발자 등록 4단계 (예시 그림)
① 시작하기를 눌러요.
② 약관을 확인하고 다음.
③ 휴대폰 번호와 이메일을 넣으면 각각 숫자(인증번호)가 와요. 그 숫자를 넣어요.
④ 직업을 물어보면 가장 가까운 걸 골라요. 잘 모르겠으면 '개발자'를 골라도 괜찮아요.
등록이 끝나면(이미 등록된 분은 바로) 맨 위의 내 앱을 눌러요.

Meta 개발자 사이트 → 내 앱 → 앱 만들기
① 오른쪽 위 초록색 앱 만들기를 눌러요. (처음이면 아래 앱 목록은 비어 있어요.)
이제 5칸짜리 단계를 차례로 지나가요. 화면 위에 '앱 상세 정보 → 이용 사례 → 비즈니스 → 요구 사항 → 개요'로 지금 어디쯤인지 보여 줘요.
1단계 · 앱 상세 정보

앱 만들기 1단계 — 앱 이름 입력
① 앱 이름을 영어로 적어요. 예) my-auto-upload
② 앱 연락처 이메일은 내 이메일이 이미 들어가 있어요. 그대로 두면 돼요.
③ 다음
앱 이름에 insta, gram, face, book, fb 같은 글자를 넣으면 안 돼요. 인스타·페이스북 이름과 헷갈린다며 아래처럼 빨간 경고가 뜨고 다음으로 안 넘어가요. 저도 처음에 my-insta-auto라고 적었다가 막혔어요. auto-upload처럼 상관없는 이름으로 지으세요.

앱 이름에 insta가 들어가면 나오는 경고
2단계 · 이용 사례
여기가 제일 헷갈리는 곳이에요. 처음 열리면 '추천' 목록이 나오는데, 거기엔 인스타그램이 없어요. 당황하지 말고 왼쪽 필터를 바꿔 주세요.

앱 만들기 2단계 — 이용 사례에서 Instagram 고르기
① 왼쪽 '필터 기준'에서 콘텐츠 관리를 눌러요.
② Instagram에서 메시지 및 콘텐츠 관리 줄 오른쪽 네모에 체크해요. 아래에 '이용 사례 1건 추가됨'이라고 떠요.
③ 다음
3단계 · 비즈니스

앱 만들기 3단계 — 비즈니스 포트폴리오 연결 안 함
① 맨 아래 아직 비즈니스 포트폴리오를 연결하고 싶지 않음을 골라요. (비즈니스 포트폴리오 = 회사 정보를 묶어 두는 곳. 없어도 돼요.) 위에 회사 이름이 여러 개 보여도, 없어도 상관없어요.
② 다음
4단계 · 요구 사항 → 5단계 · 개요
요구 사항 화면에는 '확인된 요구 사항이 없습니다'라고 나와요. 마지막 확인 화면에는 '이 앱의 이용 사례에는 요구 사항이 없습니다'라고 나와요. 그냥 다음을 누르면 마지막 확인 화면이 나와요.

앱 만들기 5단계 — 개요 확인 후 앱 만들기
① 이용 사례에 Instagram에서 메시지 및 콘텐츠 관리가 들어 있는지 확인해요.
② 오른쪽 아래 초록색 앱 만들기. 페이스북 비밀번호를 한 번 더 물어볼 수 있어요.
앱이 만들어지면 아래 같은 '대시보드' 화면이 열려요.

앱 대시보드 → 이용 사례 맞춤 설정
① Instagram에서 메시지 및 콘텐츠 관리 맞춤 설정 이용 사례 줄을 눌러요. 앞으로 설정은 대부분 이 안에서 해요.
✔ 확인: 왼쪽 위에 내가 정한 앱 이름이 보이면 성공!
LEVEL 4. 인스타그램 API를 켜고 '올리기 허락'을 받아요 (3분)

Instagram 로그인이 포함된 API 설정
① 왼쪽에서 Instagram 로그인이 포함된 API 설정을 눌러요. 두 칸 아래에 'Facebook 로그인이 포함된 API 설정'이라는 비슷한 메뉴가 있는데, 그건 누르지 마세요. 우리는 위쪽을 써요. 이쪽은 페이스북 페이지가 없어도 돼서 훨씬 쉬워요.
② 파란 버튼 Add all required permissions를 눌러요. '필요한 허락을 한꺼번에 받기' 버튼이에요.
③ 그 아래 계정 추가 버튼은 LEVEL 6에서 누를 거예요. 어디 있는지만 봐 두세요.
허락이 잘 들어갔는지 확인해 볼게요. 왼쪽 '권한 및 기능'을 누르고 화면을 아래로 내려요.

instagram_business_content_publish가 '테스트 준비 완료'인지 확인
① instagram_business_content_publish를 찾아요. 이름이 길지만 뜻은 '게시물 올리기 허락'이에요.
② 옆에 테스트 준비 완료라고 적혀 있으면 OK.
여기 꼭 확인하세요! 앞에서 누른 'Add all required permissions'에는 이 '게시물 올리기 허락'이 들어 있지 않을 수 있어요(그 버튼은 메시지·댓글용 허락을 넣어 줘요). 줄 오른쪽 버튼을 보세요. 이미 들어간 권한은 옵션 ▾으로, 아직 안 들어간 권한은 + 추가로 보여요. '+ 추가'가 보이면 꼭 눌러 주세요. 이걸 빼먹으면 모든 세팅을 다 하고도 마지막에 "권한이 없다"는 오류가 나요. 그리고 이 허락은 LEVEL 6에서 토큰을 만들기 전에 넣어야 해요. 토큰을 먼저 만들었다면 허락을 넣은 뒤 토큰을 다시 만드세요.
'앱 검수', '비즈니스 인증', '게시' 같은 안내가 보여도 무시해도 돼요. 내 계정에 내가 올리는 거라면 지금 상태('개발 모드' = 나와 테스터만 쓰는 연습용 상태) 그대로 쓸 수 있어요. 화면 곳곳에 보이는 'Webhook'도 이 글에선 쓰지 않으니 무시하세요.
LEVEL 5. 내 인스타 계정을 '테스터'로 등록해요 (5분)
지금 만든 출입증은 아직 '연습용'이라서, 테스터로 등록된 계정에만 쓸 수 있어요. 그래서 ① Meta에서 내 인스타를 초대하고 ② 인스타에서 초대를 받아들이는, 두 가지를 해야 해요. 많은 분들이 두 번째를 빼먹어서 막혀요.

앱 역할 → Instagram 테스터 → 사람 추가
① 왼쪽 아래 앱 역할을 펼치고 역할을 눌러요.
② 위쪽 탭에서 Instagram 테스터를 눌러요.
③ 오른쪽 파란 버튼 사람 추가 → 내 인스타 아이디를 적고 추가해요.
④ 상태에 대기 중이라고 떠요. 아직 끝난 게 아니에요! 이제 인스타에서 받아들여야 해요.
PC 인터넷 창에서 인스타그램에 로그인한 뒤, 주소창에 instagram.com/accounts/manage_access를 치고 들어가요. (인스타 설정의 '앱 및 웹사이트'와 같은 곳이에요.)

인스타 → 앱 및 웹사이트 → 테스터 초대 → 수락 (예시 그림)
① 테스터 초대 탭을 누르고 ② 방금 만든 앱 옆의 수락을 눌러요. 초대가 안 보이면 5분쯤 기다렸다가 새로고침(F5)해 보세요.
✔ 확인: Meta 화면으로 돌아가 새로고침했을 때 '대기 중'이 사라졌으면 성공!
LEVEL 6. 인스타 열쇠(토큰)와 계정 번호를 받아요 (5분) — 제일 중요!
시작 전에 한 번만 확인해요. LEVEL 4의 '게시물 올리기 허락'(instagram_business_content_publish)이 '테스트 준비 완료'인가요? 그렇다면 LEVEL 4 화면으로 돌아가서, 봐 두었던 계정 추가를 눌러요. 인스타 로그인 창이 뜨면 로그인하고 '허용'을 눌러요. (로그인 창이 안 뜨면 인터넷 창 주소창 오른쪽의 '팝업 차단' 표시를 눌러 허용해 주세요.) 그러면 아래처럼 내 계정이 목록에 나타나요.

액세스 토큰 생성 — 계정 번호와 토큰 생성
① 계정 이름 아래 파란 숫자(17841…로 시작해요)가 계정 번호예요. 복사해서 메모장에 붙여 두세요.
② 토큰 생성을 누르면 아주 긴 글자가 나와요. 이게 열쇠(토큰)예요. 역시 복사해서 메모장에 붙여 두세요. 창에 '이해했습니다' 같은 체크 칸이 있으면 체크해야 복사 버튼이 눌려요.
메모장에는 이렇게 정리해 두면 나중에 헷갈리지 않아요.
IG_USER_ID = 17841…(계정 번호)
IG_ACCESS_TOKEN = IGAA…(토큰. 아주 길어요)
토큰 받은 날 = 2026-10-01 ← 이 날짜가 중요해요
⏰ 지금 바로 폰 달력에 알림을 하나 넣어 주세요. 날짜는 오늘부터 50일 뒤, 제목은 "인스타 토큰 연장". 토큰은 60일이 지나면 못 쓰게 되고, 그러면 자동 업로드도 멈춰요. 연장은 1분이면 되지만 잊어버리기 정말 쉬워요.
토큰은 비밀번호와 같아요. 캡처해서 남에게 보내거나, 단톡방에 붙여 넣거나, 파일에 적어서 GitHub에 올리면 안 돼요. 이 글자만 있으면 누구든 내 계정에 글을 올릴 수 있거든요.
✔ 확인: 메모장에 숫자(계정 번호)와 긴 글자(토큰)가 있으면 성공! 제일 어려운 구간은 이제 지났어요.
LEVEL 7. GitHub 가입하고 저장소를 만들어요 (7분)
GitHub는 화면이 영어예요. 겁먹지 않도록 자주 누를 버튼만 먼저 뜻을 적어 둘게요.
· Sign up 가입하기 · Create repository 저장소(폴더) 만들기
· Add file 파일 추가 · Create new file 새 파일 만들기 · Upload files 파일 올리기
· Commit changes 저장하기 · Settings 설정 · Secrets 비밀 금고
· Actions 로봇 작업실 · Run workflow 로봇 일 시키기
크롬에서 오른쪽 클릭 → '한국어로 번역'을 눌러도 되지만, 버튼 이름이 바뀌어서 이 글과 달라 보일 수 있어요. 가능하면 영어 그대로 보세요.
이제 사진과 코드를 올려 둘 인터넷 폴더를 만들 거예요. 주소창에 github.com을 치고 들어가 오른쪽 위 Sign up(가입)을 눌러요.

GitHub 가입 화면
① 이메일을 적어요.
② 아이디(Username)를 영어로 정해요. 이 아이디는 나중에 주소에 들어가니 메모장에 적어 두세요.
③ Create account를 눌러요. 이메일로 가입하면 비밀번호를 정하는 칸이 더 있고, 사람인지 확인하는 퍼즐이 나오면 풀어요. 이메일로 온 숫자를 입력하면 가입 끝이에요. (위 그림은 구글 계정으로 가입하는 화면이라 비밀번호 칸이 없어요.) 요금제를 고르라고 하면 무료(Free)를 고르면 돼요.
로그인하면 첫 화면 왼쪽에 초록 버튼이 있어요.

GitHub 첫 화면 → Create repository
① Create repository(저장소 만들기)를 눌러요.

저장소 만들기 화면
① 저장소 이름을 영어로 적어요. 예) insta-auto. 이것도 메모장에 적어 두세요.
② 공개 범위는 꼭 Public(공개)으로 골라요.
③ Create repository를 눌러요.
왜 공개여야 하냐면, 인스타는 누구나 볼 수 있는 인터넷 주소에서만 사진을 가져가기 때문이에요. 어차피 인스타에 공개될 사진이라 괜찮지만, 올리기 전 사진도 누구나 볼 수 있다는 건 기억해 주세요. 열쇠(토큰)는 이 폴더에 넣지 않고 LEVEL 9의 금고에 따로 넣으니 안전해요. 공개 저장소라서 GitHub 로봇도 무료로 쓸 수 있어요.
✔ 확인: 화면 맨 위에 내 저장소 이름과 'Public' 표시가 보이면 성공!
LEVEL 8. GitHub에 코드 파일 2개를 올려요 (7분)
저장소를 만들면 바로 아래 화면이 나와요.

저장소를 만든 직후 화면 → creating a new file
① 파란 상자 안의 creating a new file을 눌러요. 'GitHub 안에서 바로 새 파일 만들기'라는 뜻이에요. 코드 파일 2개를 모두 이 방법으로 만들어요. 내 컴퓨터에 파일을 저장할 필요가 없어서 실수할 일이 적어요.
첫 번째 파일: publish.py (인스타에 올려 주는 코드)
새 파일 만들기 화면은 아래처럼 생겼어요. (그림은 두 번째 파일을 만들 때 모습이에요. 이름 칸에 적는 것만 달라요.)

GitHub에서 새 파일 만들기 (예시 그림)
① 위쪽 이름 칸에 publish.py라고 적어요.
② 큰 칸에 아래 코드를 처음부터 끝까지 전부 복사해서 붙여 넣어요. 한 글자도 고치지 않아도 돼요.
③ 오른쪽 위 초록 버튼 Commit changes... → 작은 창이 뜨면 한 번 더 Commit changes. ('Commit'은 GitHub에서 '저장'이라는 뜻이에요.)
▼ publish.py
# publish.py — 폴더 안의 사진(1~10장)과 caption.txt를 인스타에 올립니다
import os, sys, glob, time, urllib.parse, requests
API = "https://graph.instagram.com/v21.0"
USER = os.environ["IG_USER_ID"]
TOKEN = os.environ["IG_ACCESS_TOKEN"]
BASE = os.environ["IMG_BASE"].rstrip("/")
folder = sys.argv[1].strip("/")
def call(path, **data):
data["access_token"] = TOKEN
r = requests.post(f"{API}/{path}", data=data, timeout=60).json()
if "error" in r:
e = r["error"]
sys.exit(f"오류(#{e.get('code')}): {e.get('message')}")
return r["id"]
if os.path.exists(f"{folder}/posted.txt"):
sys.exit(f"{folder}는 이미 올린 폴더예요. 다시 올리려면 posted.txt를 지우세요")
photos = sorted(p for p in glob.glob(f"{folder}/*") if p.lower().endswith((".jpg", ".jpeg")))[:10]
if not photos:
sys.exit(f"{folder} 폴더에 JPG 사진이 없어요")
cap_file = f"{folder}/caption.txt"
caption = open(cap_file, encoding="utf-8").read() if os.path.exists(cap_file) else ""
urls = [BASE + "/" + urllib.parse.quote(p.replace("\\", "/")) for p in photos]
if len(urls) == 1:
box = call(f"{USER}/media", image_url=urls[0], caption=caption)
else:
kids = [call(f"{USER}/media", image_url=u, is_carousel_item="true") for u in urls]
box = call(f"{USER}/media", media_type="CAROUSEL", children=",".join(kids), caption=caption)
# 인스타가 사진을 다 받아 갈 때까지 기다립니다
for _ in range(20):
state = requests.get(f"{API}/{box}", params={"fields": "status_code", "access_token": TOKEN}, timeout=30).json()
if state.get("status_code") in ("FINISHED", "ERROR"):
break
time.sleep(3)
post_id = call(f"{USER}/media_publish", creation_id=box)
open(f"{folder}/posted.txt", "w").write(post_id) # 두 번 올라가지 않게 표시
print("게시 완료! 게시물 번호:", post_id)
어느 화면에 있든 저장소 첫 화면으로 돌아가려면 맨 위의 저장소 이름(예: insta-auto)을 누르면 돼요. 길을 잃으면 일단 여기로 돌아오세요.
두 번째 파일: publish.yml (로봇에게 주는 일 순서표)
이 파일은 들어가야 하는 자리가 정해져 있어요. 방법은 첫 번째 파일과 같아요.
1. 저장소 첫 화면에서 Add file → Create new file을 눌러요. (파일이 하나라도 생기면 'creating a new file' 대신 이 버튼이 보여요.)
2. 이름 칸에 .github/workflows/publish.yml을 그대로 적어요. 맨 앞의 점(.)까지 똑같이요! 빗금(/)을 치면 폴더가 자동으로 만들어져요.
3. 큰 칸에 아래 코드를 통째로 붙여 넣어요.
4. Commit changes... → 한 번 더 Commit changes.
▼ .github/workflows/publish.yml
name: 인스타 자동 업로드
on:
workflow_dispatch:
inputs:
folder:
description: "올릴 폴더 이름 (예: posts/2026-10-01)"
required: true
schedule:
- cron: "0 0 * * *" # 매일 오전 9시(한국 시간). 실제 실행은 늦어질 수 있어요
permissions:
contents: write # 올린 폴더에 posted.txt를 남기기 위해 필요해요
concurrency: publish # 두 번 겹쳐 돌지 않게 한 번에 하나씩만 실행해요
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install requests
- name: 발행
env:
IG_USER_ID: ${{ secrets.IG_USER_ID }}
IG_ACCESS_TOKEN: ${{ secrets.IG_ACCESS_TOKEN }}
IMG_BASE: ${{ secrets.IMG_BASE }}
FOLDER: ${{ inputs.folder }}
run: |
if [ -n "$FOLDER" ]; then
# 버튼으로 직접 실행: 문제가 있으면 빨간 X로 알려 줘요
if [ ! -d "$FOLDER" ]; then echo "오류: $FOLDER 폴더가 없어요. 폴더 이름을 확인하세요"; exit 1; fi
if [ -f "$FOLDER/posted.txt" ]; then echo "오류: $FOLDER는 이미 올린 폴더예요. 다시 올리려면 posted.txt를 지우세요"; exit 1; fi
else
# 아침 예약 실행: 오늘 날짜 폴더가 없거나 이미 올렸으면 조용히 쉬어요
FOLDER="posts/$(TZ=Asia/Seoul date +%F)"
if [ ! -d "$FOLDER" ] || [ -f "$FOLDER/posted.txt" ]; then echo "오늘($FOLDER)은 올릴 게 없어서 쉬어요"; exit 0; fi
fi
python publish.py "$FOLDER"
- name: 올린 표시 저장
run: |
git config user.name "github-actions"
git config user.email "github-actions@users.noreply.github.com"
git add -A
git commit -m "올린 표시(posted.txt) 저장" || exit 0
git push
✔ 확인: 저장소 첫 화면에 .github 폴더와 publish.py가 보이면 성공!
LEVEL 9. 인스타 열쇠를 금고에 넣어요 — Secrets 3개 (5분)
LEVEL 6에서 메모장에 적어 둔 것들을 GitHub의 비밀 금고(Secrets)에 넣어요. 금고에 넣은 값은 나중에 나도 다시 볼 수 없고, 로봇만 꺼내 쓸 수 있어요. 그래서 공개 저장소라도 안전해요.
먼저 저장소 맨 위의 탭 줄을 봐 주세요. 앞으로 두 개를 자주 써요.

저장소 위쪽 탭 — Actions와 Settings
① Actions — 로봇이 일한 기록을 보는 곳 (뒤의 '클로드 없이 올리는 법')
② Settings — 설정. 금고(Secrets)가 여기 안에 있어요 (지금)
창이 좁으면 Settings가 안 보이고 오른쪽 끝 ··· 안에 숨어 있어요.

Settings → Secrets and variables → Actions
저장소 맨 위 오른쪽의 Settings(설정) 탭을 눌러요.
① 왼쪽 메뉴에서 Secrets and variables를 펼치고 Actions를 눌러요.
② 초록 버튼 New repository secret을 눌러요.

금고에 값 하나 넣기 (예시 그림)
① Name(이름) 칸에 이름을 적고 ② Secret(값) 칸에 값을 붙여 넣고 ③ Add secret. 이걸 세 번 해요.
· 첫 번째 — 이름 IG_USER_ID / 값: 메모장의 계정 번호(17841…)
· 두 번째 — 이름 IG_ACCESS_TOKEN / 값: 메모장의 토큰(IGAA…)
· 세 번째 — 이름 IMG_BASE / 값: https://raw.githubusercontent.com/내아이디/저장소이름/main
예) 아이디가 hong-gildong, 저장소가 insta-auto라면
https://raw.githubusercontent.com/hong-gildong/insta-auto/main
이름은 대문자와 밑줄(_)까지 똑같이 적어야 해요. 한 글자만 달라도 로봇이 못 찾아요. 앞뒤에 빈칸이 들어가지 않게도 조심하세요.
✔ 확인: 위의 Secrets 목록 캡처 ③처럼 3개가 보이면 성공! 값은 가려져서 안 보이는 게 정상이에요.
LEVEL 10. 클로드를 연결하고 "올려줘" 해 봐요 (15분)
마지막이에요. 클로드가 내 GitHub에 사진을 올리고 로봇에게 일을 시킬 수 있게 연결해요. 4단계예요.
10-1. 클로드 코드 준비하기
먼저 클로드(claude.ai) Pro 이상 구독 계정이 있어야 해요. 그다음 PC에 클로드 코드를 설치해요. 윈도우라면 시작 메뉴 검색창에 PowerShell을 쳐서 열고, 아래 한 줄을 붙여 넣은 뒤 엔터를 눌러요.
▼ 윈도우 PowerShell에 붙여 넣기
irm https://claude.ai/install.ps1 | iex
맥이라면 '터미널' 앱을 열고 이 줄을 붙여 넣어요.
▼ 맥 터미널에 붙여 넣기
curl -fsSL https://claude.ai/install.sh | bash
설치가 끝나면 창을 닫았다가 다시 열고 claude라고 쳐서 엔터. 처음 한 번은 인터넷 창이 열리면서 클로드 계정으로 로그인하라고 해요. 로그인 방법을 물으면 구독 중인 클로드 계정(Claude account)을 고르세요. 'Console'이나 'API' 쪽을 고르면 구독과 별도로 요금이 나가요. 로그인하면 준비 끝이에요. (검은 창이 어렵다면 클로드 데스크톱 앱에서도 클로드 코드를 쓸 수 있어요.)
클로드는 파일을 만들거나 프로그램을 실행하기 전에 "해도 될까요?"라고 물어요. 이 글에서 시키는 일이라면 Yes를 고르면 돼요. 매번 묻는 게 번거로우면 '다음부터 묻지 않기'(don't ask again) 같은 선택지를 골라도 괜찮아요.
업로드 코드는 파이썬(Python)이라는 프로그램으로 돌아가요. PC에 없으면 python.org에서 받아 설치하세요. 윈도우는 설치 첫 화면에서 Add python.exe to PATH에 꼭 체크해야 해요. 맥은 설치가 끝나면 열리는 Python 폴더에서 Install Certificates.command를 한 번 더블클릭해 주세요(인터넷 연결에 필요한 준비예요). 맥에서는 python 대신 python3라는 이름으로 설치되는데, 클로드가 알아서 맞춰 써요. 잘 모르겠으면 클로드를 켜고 "파이썬 설치돼 있는지 확인해줘"라고 하면 확인해 줘요.
10-2. GitHub 토큰 만들기
클로드는 내 GitHub에 로그인한 사람이 아니에요. 그래서 "이 프로그램은 내가 허락했어"라는 열쇠를 하나 더 만들어 줘야 해요. 이게 GitHub 토큰이에요. 인스타 토큰과는 다른 열쇠예요.
GitHub 오른쪽 위 프로필 사진 → Settings → 왼쪽 맨 아래 Developer settings → Personal access tokens → Fine-grained tokens → Generate new token. 주소창에 github.com/settings/personal-access-tokens/new 를 치면 바로 가요.

GitHub 토큰 — 이름과 기간
① Token name: 아무 이름이나 영어로(예: insta-upload)
② Expiration(기간)을 누르고
③ No expiration(기한 없음)을 골라요. 이러면 이 열쇠는 연장할 필요가 없어요. 기한 없는 열쇠가 걱정되면 Custom으로 1년을 골라도 되는데, 그러면 1년 뒤에 새로 만들어야 해요.

GitHub 토큰 — 어느 저장소에, 어떤 권한
① Repository access에서 Only select repositories(고른 저장소만)
② Select repositories를 눌러 LEVEL 7에서 만든 저장소(예: insta-auto) 하나만 골라요. 다른 저장소는 건드리지 못하게 하는 안전장치예요.
③ Add permissions(권한 추가)를 눌러요.

권한 목록에서 고르기
① Add permissions를 누르면 작은 창이 열려요. ② 검색 칸에 이름을 쳐서 ③ 체크해요. 두 개를 체크해야 해요.
· Actions — 로봇에게 일 시키기
· Contents — 저장소에 사진 올리기

권한 두 개를 Read and write로 바꾸기
두 권한이 목록에 생기면 각각 옆의 Access: Read-only를 눌러 Read and write(읽기와 쓰기)로 바꿔요. 그림처럼 ① Actions ② Contents 둘 다 'Read and write'가 되면 OK예요. 기본값이 Read-only라서 안 바꾸면 클로드가 아무것도 못 해요. Metadata는 자동으로 붙는 거라 그대로 두세요.
③ 맨 아래 Generate token.

토큰 만들기 완료 — 이 화면에서 딱 한 번만 보여요
① 초록 상자 안의 복사 버튼을 눌러 토큰(github_pat_로 시작)을 복사해 메모장에 붙여 둬요. 이 화면을 벗어나면 다시 볼 수 없어요. 놓쳤으면 토큰 이름을 눌러 Regenerate token으로 새로 만들면 돼요.
② 기한이 여기 적혀 있어요. (그림은 기한을 정해서 만든 예라 날짜가 보여요. No expiration을 골랐다면 기한이 없다고 나와요.)
GitHub 토큰도 비밀번호와 같아요. 캡처해서 남에게 보내거나 단톡방에 붙여 넣으면 안 돼요. 혹시 노출됐다면 같은 화면에서 Delete로 지우고 새로 만드세요.
10-3. 내 PC에 '인스타자동' 폴더 만들기
바탕 화면에 인스타자동이라는 폴더를 만들어요. 앞으로 게시물은 전부 이 폴더 안에서 다뤄요. 다 만들면 이런 모양이 돼요.

인스타자동 폴더 모양 (예시 그림)
① 비밀 파일 2개는 메모장으로 직접 만들어요. 토큰을 클로드와의 대화에 붙여 넣지 않으려고요.
· 새 메모장에 GitHub 토큰만 붙여 넣고 → 파일 → 저장 → 인스타자동 폴더에 이름 github_token으로 저장 (.txt는 자동으로 붙어요)
· 새 메모장에 내아이디/저장소이름(예: hong-gildong/insta-auto) 한 줄만 쓰고 → 이름 github_repo로 저장
· 맥은 '텍스트 편집기'를 열고 위쪽 메뉴 포맷 → 일반 텍스트로 만들기를 누른 뒤 같은 방법으로 저장하세요. 안 그러면 .txt가 아닌 다른 파일로 저장돼요.
· 윈도우는 보통 파일 이름 뒤의 .txt를 숨겨서 보여 줘요. 폴더에 'github_token'이라고만 보여도 정상이에요.
② 코드 파일 2개는 클로드가 만들어요. 인스타자동 폴더에서 클로드를 켜요. 여는 방법은 아래 그림처럼요.

인스타자동 폴더에서 클로드 켜기 (예시 그림)
① 파일 탐색기로 인스타자동 폴더를 열고, 위쪽 주소 칸을 눌러 글자를 지운 뒤 powershell이라고 쓰고 엔터 (맥은 터미널을 열고 cd 한 칸 띄우고 인스타자동 폴더를 창에 끌어다 놓은 뒤 엔터)
② 검은(또는 파란) 창이 열리면 claude라고 쓰고 엔터
③ 처음엔 '이 폴더를 믿느냐'고 물어요. Yes를 고르면 돼요.
클로드가 켜지면 아래 글을 통째로 복사해서 보내 주세요. 뒤에 붙은 코드 두 개까지 한 번에요. 클로드가 이 폴더에 파일 두 개를 만들어 줘요.
▼ 클로드에게 보낼 첫 메시지 (통째로 복사)
이 폴더에 아래 두 파일을 내용 그대로 만들어줘. 한 글자도 바꾸지 말고, 다 만들면 이 폴더의 파일 목록만 보여줘. github_token.txt 파일은 열어 보지 마.
===== 파일 1: CLAUDE.md =====
# 인스타 자동 업로드 도우미
이 폴더에서 사용자가 "인스타 올려줘", "10월1일 폴더 올려줘", "10월 5일에 올려줘" 같은 말을 하면 아래 순서대로 한다.
1. 어떤 사진 폴더인지 확인한다. 말하지 않았으면 이 폴더 안의 하위 폴더 목록을 보여 주고 물어본다.
2. 그 폴더의 사진 파일 이름(이름 순서 = 인스타에 올라가는 순서)과 caption.txt 내용을 보여 주고
"이대로 올릴까요?"라고 꼭 확인받는다. 인스타에 한 번 올라가면 이 방법으로는 지울 수 없다.
3. 확인을 받으면 실행한다.
- 지금 올리기: `python insta_upload.py "사진폴더"`
- 날짜 예약(내일 이후, 하루 1개): `python insta_upload.py "사진폴더" 2026-10-05`
- 맥에서 `python`이 없으면 `python3`로 실행한다.
4. 결과를 쉬운 한국어로 짧게 알려 준다. 실패하면 '오류' 줄의 뜻을 풀어서 설명하고 해결 방법을 알려 준다.
- `#190` → 인스타 토큰이 틀렸거나 60일이 지남. 블로그의 '60일마다 인스타 토큰 연장'대로 바꾸게 안내
- `#10` / permission → Meta 앱의 '게시물 올리기 허락'(instagram_business_content_publish) 확인
- `aspect ratio` → 사진 비율을 4:5~1.91:1 사이로 잘라야 함
- `GitHub 401` → GitHub 토큰이 틀렸거나 기한이 지남
- `GitHub 403/404` → github_repo.txt의 저장소 이름이나 GitHub 토큰 권한 확인
## 지켜야 할 것
- github_token.txt 안의 글자는 절대 화면에 보여 주거나, 다른 파일에 옮기거나, 다른 곳에 보내지 않는다.
- 사용자가 "올려"라고 확인하기 전에는 insta_upload.py를 실행하지 않는다.
- 폴더 안에 올림완료.txt가 있으면 이미 올렸거나 예약한 폴더다. 사용자에게 알려 주고, 다시 올리라고 분명히 말할 때만 그 파일을 지우고 실행한다.
===== 파일 2: insta_upload.py =====
# insta_upload.py — 내 PC 폴더의 사진과 캡션을 GitHub에 올리고, 인스타 발행까지 시킵니다
# 사용법
# 지금 바로 올리기: python insta_upload.py "사진폴더"
# 날짜 예약하기: python insta_upload.py "사진폴더" 2026-10-05
# 같은 폴더에 github_token.txt(GitHub 토큰)와 github_repo.txt(예: hong-gildong/insta-auto)가 있어야 해요.
import base64, datetime, glob, json, os, sys, time, urllib.error, urllib.request
try:
sys.stdout.reconfigure(encoding="utf-8")
except Exception:
pass
HERE = os.path.dirname(os.path.abspath(__file__))
KST = datetime.timezone(datetime.timedelta(hours=9))
def read_setting(name):
path = os.path.join(HERE, name)
if not os.path.exists(path):
sys.exit(f"오류: {name} 파일이 없어요. 블로그 LEVEL 10을 확인하세요")
return open(path, encoding="utf-8").read().strip()
TOKEN = read_setting("github_token.txt")
REPO = read_setting("github_repo.txt")
def gh(method, path, body=None):
"""GitHub에 요청을 보내고 (상태 번호, 받은 내용)을 돌려줍니다."""
url = path if path.startswith("http") else f"https://api.github.com/repos/{REPO}/{path}"
data = json.dumps(body).encode() if body is not None else None
req = urllib.request.Request(url, data=data, method=method, headers={
"Authorization": f"Bearer {TOKEN}",
"Accept": "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
})
try:
with urllib.request.urlopen(req, timeout=60) as r:
raw = r.read()
status = r.status
except urllib.error.HTTPError as e:
raw, status = e.read(), e.code
try:
return status, json.loads(raw) if raw else None
except ValueError:
return status, raw.decode("utf-8", "replace")
class _NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, *args, **kwargs):
return None
def fetch_log(job_id):
"""실행 기록(로그)을 가져와요. GitHub가 다른 주소로 넘겨주면 그 주소는 토큰 없이 열어요."""
req = urllib.request.Request(f"https://api.github.com/repos/{REPO}/actions/jobs/{job_id}/logs",
headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/vnd.github+json"})
try:
with urllib.request.build_opener(_NoRedirect).open(req, timeout=60) as r:
return r.read().decode("utf-8", "replace")
except urllib.error.HTTPError as e:
if e.code in (301, 302, 303, 307) and e.headers.get("Location"):
with urllib.request.urlopen(e.headers["Location"], timeout=60) as r:
return r.read().decode("utf-8", "replace")
except Exception:
pass
return ""
def check(status, reply, what):
if status == 401:
sys.exit("오류(GitHub 401): GitHub 토큰이 틀렸거나 기한이 지났어요. github_token.txt를 확인하세요")
if status in (403, 404):
sys.exit(f"오류(GitHub {status}): {what} 실패. 저장소 이름(github_repo.txt)과 토큰 권한(Contents·Actions 읽기와 쓰기)을 확인하세요")
if status >= 300:
sys.exit(f"오류(GitHub {status}): {what} 실패 — {reply}")
# 1) 내 PC 폴더 확인
if len(sys.argv) < 2:
sys.exit('사용법: python insta_upload.py "사진폴더" [예약날짜 2026-10-05]')
src = sys.argv[1].rstrip("\\/")
if not os.path.isdir(src):
sys.exit(f"오류: {src} 폴더가 없어요")
photos = sorted(p for p in glob.glob(os.path.join(src, "*")) if p.lower().endswith((".jpg", ".jpeg")))
if not photos:
sys.exit("오류: 폴더에 JPG 사진이 없어요 (PNG·HEIC는 JPG로 바꿔 주세요)")
if len(photos) > 10:
sys.exit(f"오류: 사진이 {len(photos)}장이에요. 한 게시물은 10장까지예요")
for p in photos:
if os.path.getsize(p) > 8 * 1024 * 1024:
sys.exit(f"오류: {os.path.basename(p)}이(가) 8MB보다 커요")
done = os.path.join(src, "올림완료.txt")
if os.path.exists(done):
sys.exit("오류: 이 폴더는 이미 올렸거나 예약했어요 (" + open(done, encoding="utf-8").read().strip() + "). "
"다시 올리려면 폴더 안의 올림완료.txt를 지우세요")
cap = os.path.join(src, "caption.txt")
caption = open(cap, encoding="utf-8").read() if os.path.exists(cap) else ""
# 2) GitHub 안에 만들 폴더 이름 정하기
now = datetime.datetime.now(KST)
if len(sys.argv) >= 3:
day = sys.argv[2]
try:
if datetime.date.fromisoformat(day) <= now.date():
sys.exit("오류: 예약은 내일 이후 날짜만 돼요. 오늘 올리려면 날짜 없이 '지금 올려줘'라고 하세요")
except ValueError:
sys.exit("오류: 날짜는 2026-10-05 처럼 적어 주세요")
target, scheduled = f"posts/{day}", True
else:
target, scheduled = f"posts/now-{now:%Y%m%d-%H%M%S}", False
status, _ = gh("GET", f"contents/{target}")
if status == 200:
sys.exit(f"오류: {target[6:]}에는 이미 예약된 게시물이 있어요. 예약은 하루에 1개만 돼요")
# 3) 사진과 캡션 올리기 (사진 이름은 01.jpg, 02.jpg … 로 바꿔서 올려요)
files = [(f"{i:02d}.jpg", open(p, "rb").read()) for i, p in enumerate(photos, 1)]
files.append(("caption.txt", caption.encode("utf-8")))
for name, content in files:
status, reply = gh("PUT", f"contents/{target}/{name}", {
"message": f"{target} 올림",
"content": base64.b64encode(content).decode(),
})
check(status, reply, f"{name} 올리기")
print(f" GitHub에 올림: {target}/{name}")
if scheduled:
open(done, "w", encoding="utf-8").write(f"{target[6:]} 예약")
print(f"\n예약 완료! {target[6:]} 아침 9시쯤 인스타에 올라가요. (GitHub 사정으로 늦어질 수 있어요)")
sys.exit(0)
# 4) 로봇에게 발행 시키기
time.sleep(5) # 방금 올린 사진이 인터넷 주소로 열릴 때까지 잠깐 기다려요
started = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(seconds=30)
status, reply = gh("POST", "actions/workflows/publish.yml/dispatches",
{"ref": "main", "inputs": {"folder": target}})
check(status, reply, "발행 시작")
print("\n로봇에게 발행을 시켰어요. 1~2분 기다려 주세요…")
# 5) 결과 기다리기
for _ in range(60):
time.sleep(5)
status, reply = gh("GET", "actions/workflows/publish.yml/runs?event=workflow_dispatch&per_page=5")
check(status, reply, "실행 기록 보기")
run = next((r for r in reply.get("workflow_runs", [])
if datetime.datetime.fromisoformat(r["created_at"].replace("Z", "+00:00")) >= started), None)
if run and run["status"] == "completed":
break
else:
sys.exit("오류: 5분이 지나도 끝나지 않았어요. GitHub의 Actions 탭에서 확인하세요")
if run["conclusion"] == "success":
open(done, "w", encoding="utf-8").write(f"{now:%Y-%m-%d %H:%M} 올림")
print(f"\n✅ 인스타에 올라갔어요! ({target})")
sys.exit(0)
# 실패했으면 오류 줄을 찾아서 보여 줘요
message = ""
status, jobs = gh("GET", f"actions/runs/{run['id']}/jobs")
if status == 200 and jobs.get("jobs"):
log = fetch_log(jobs["jobs"][0]["id"])
if log:
lines = [l.split(" ", 1)[-1] for l in log.splitlines() if "오류" in l and "echo" not in l]
message = lines[-1] if lines else ""
sys.exit(f"\n❌ 올라가지 않았어요. {message or '이유는 GitHub의 Actions 탭에서 확인하세요'}\n{run['html_url']}")
✔ 확인: 인스타자동 폴더에 CLAUDE.md, insta_upload.py, github_token.txt, github_repo.txt 4개가 있으면 성공! CLAUDE.md는 클로드가 이 폴더에서 켜질 때마다 읽는 '일 설명서'예요. "올려줘"라고 하면 무엇을 할지, 올리기 전에 꼭 확인받으라는 규칙이 적혀 있어요.
10-4. "인스타 올려줘" 해 보기
인스타자동 폴더 안에 게시물 폴더를 하나 만들어요(예: 10월1일). 그 안에 사진(JPG)과 caption.txt(인스타에 쓸 글. 메모장으로 쓰고 이름을 caption으로 저장)를 넣어요. 그리고 클로드에게 말해요.

클로드에게 '올려줘'라고 말하기 (예시 그림)
클로드가 사진 순서와 캡션을 보여 주고 "이대로 올릴까요?"라고 물어요. 내용이 맞으면 "응"이라고 하면 1~2분 뒤 인스타에 올라가요. 처음 한 번은 사진 1장짜리로 시험해 보세요.
예약도 말로 해요. "10월5일 폴더를 10월 5일에 올려줘"라고 하면 클로드가 사진을 GitHub에 올려 두고 끝나요. 그날 아침 GitHub 로봇이 알아서 올려요. 이때는 내 PC가 꺼져 있어도 돼요. 예약은 내일 이후 날짜만 되고, 하루에 1개까지예요. 오늘 올릴 건 그냥 "지금 올려줘"라고 하세요.
예약 시간은 딱 맞지 않아요. GitHub 로봇은 바쁠 때 늦게 일어나서, 9시로 정해도 점심때쯤 올라가는 날도 있고 가끔은 건너뛰기도 해요. 꼭 그 시간에 올라가야 하는 게시물은 그날 "지금 올려줘"라고 하세요.
같은 게시물이 두 번 올라가지 않게도 막아 뒀어요. 올리거나 예약한 폴더에는 올림완료.txt라는 파일이 생기고, 클로드는 이 파일이 있는 폴더는 다시 올리지 않아요. 일부러 한 번 더 올리고 싶으면 이 파일을 지우면 돼요.
사진 준비 규칙 — 이거 안 지키면 올라가지 않아요
· 파일 종류: JPG(.jpg, .jpeg). 인스타그램 설명서에 'JPEG만 된다'고 적혀 있어서, 이 글의 코드도 JPG만 올려요. PNG는 그림판 등에서 JPG로 다시 저장하세요. 아이폰 사진(.HEIC)은 안 되니, 사진 앱에서 JPG로 내보내거나 카톡으로 PC에 보내면 대부분 JPG로 바뀌어요.
· 모양(비율): 세로 4:5 ~ 가로 1.91:1 사이. 제일 무난한 건 정사각형(1080×1080)이나 세로형(1080×1350)이에요.
· 폰으로 찍은 세로 사진이나 폰 화면 캡처(9:16)는 너무 길어서 그대로는 안 올라가요. 사진 앱의 '자르기'에서 4:5나 1:1로 잘라서 넣으세요.
· 크기: 한 장에 8MB 이하.
· 순서: 사진은 파일 이름 순서대로 올라가요. 한글 이름은 가나다순이라 '첫번째'보다 '두번째'가 먼저 올 수도 있어요. 1_바다.jpg, 2_카페.jpg처럼 앞에 숫자를 붙이세요. 10장이면 01_, 02_ … 10_처럼 두 자리로요. (클로드가 GitHub에 올릴 때 이름은 01.jpg, 02.jpg로 바꿔 올려요.)
· 여러 장이면 첫 번째 사진 모양에 맞춰 나머지가 잘려요. 모든 사진을 같은 모양으로 맞추면 깔끔해요.
· 한 게시물에 최대 10장, 캡션은 2,200자, 해시태그는 30개까지예요.
⚠️ 꼭 하세요 — 60일마다 인스타 토큰 연장
세팅이 끝나도 숙제가 딱 하나 남아요. 인스타 토큰(열쇠)은 60일이 지나면 못 쓰게 되고, 그러면 자동 업로드가 멈춰요. 인스타가 따로 알려 주지도 않아서 "요즘 왜 안 올라가지?" 하고 나서야 알게 돼요. 연장은 1분이면 끝나니까 날짜만 챙기면 됩니다.

60일마다 인스타 토큰 연장하는 3단계
① 새 토큰 받기
PC 인터넷 창의 주소창에 아래 주소를 붙여 넣어요. 그리고 맨 끝의 '지금토큰'을 지우고, 그 자리에 메모장에 있는 지금 인스타 토큰을 붙여 넣은 뒤 엔터를 눌러요.
▼ 인스타 토큰 연장 주소 (주소창에 붙여 넣기)
https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=지금토큰
② 새 토큰 복사하기
화면에 글자가 한 줄 나와요. 아래 그림의 빨간 상자 부분이 새 토큰이에요.

연장 주소를 넣은 뒤 나오는 화면 (예시 그림)
"access_token":" 바로 뒤부터 다음 따옴표(") 바로 앞까지만 복사해요. 따옴표는 빼야 해요. 뒤에 나오는 expires_in 숫자는 '60일'을 초로 적은 거라 신경 쓰지 않아도 돼요.
③ GitHub 금고에 바꿔 넣기
저장소 → Settings → Secrets and variables → Actions → IG_ACCESS_TOKEN 줄의 연필 모양 → 새 토큰 붙여 넣기 → Update secret. 이제 다시 60일을 쓸 수 있어요. 메모장의 토큰과 날짜도 새로 바꾸고, 폰 달력에 '50일 뒤' 알림도 다시 넣어 두세요.
연장은 토큰을 받고 하루(24시간)가 지나야 돼요. 그리고 이미 60일이 지나 버린 토큰은 연장이 안 돼요. 그럴 땐 당황하지 말고 LEVEL 6으로 돌아가서 '토큰 생성'을 다시 누르면 새 토큰이 나와요. 그걸 ③처럼 금고에 넣으면 끝이에요.
GitHub 토큰은요? 10-2에서 No expiration(기한 없음)으로 만들었다면 연장할 게 없어요. 기한을 정해 만들었다면, 기한이 되기 전에 10-2대로 새로 만들어서 인스타자동 폴더의 github_token.txt 안의 글자만 새 토큰으로 바꾸면 돼요. 기한이 지나면 클로드가 'GitHub 401' 오류로 알려 줘요.
클로드 없이 올리는 법 (GitHub 사이트에서 직접)
클로드를 켤 수 없을 때나 폰으로 급하게 올릴 때는 GitHub 사이트나 GitHub 앱에서 직접 올릴 수도 있어요. 로봇은 똑같이 일해요.
1) 게시물 폴더 만들기 — 저장소 첫 화면에서 Add file → Create new file. 이름 칸에 posts/2026-10-01/caption.txt를 적으면 posts 폴더와 날짜 폴더가 한 번에 생겨요. 큰 칸에 캡션을 적고 Commit changes. 아래 그림의 ① 이름 칸 ② 캡션 칸 ③ Commit 버튼이에요. (여기서 직접 만들 때는 폴더·사진 이름에 한글이나 띄어쓰기를 쓰지 마세요.)

캡션 파일