Buffer 연간 구독을 결제하려고 가격 페이지를 열었다가 닫아버렸습니다.
유튜브, 인스타, 틱톡, 쓰레드, 블루스카이 — 카드뉴스 하나를 5개 채널에 올리는 데 클릭을 몇 번씩 반복해야 한다는 게 너무 비효율적으로 느껴졌는데, 그걸 해결해준다는 툴이 연 40만원이더라고요. 블로그 교류 툴, 대시보드까지 합치면 100만원이 훌쩍 넘습니다.
그냥 클로드한테 만들어달라고 했습니다.






나는 1인 마케터야. 카드뉴스(이미지)를 만들면 유튜브, 인스타그램, 쓰레드, 블루스카이에 버튼 하나로 올라가는 로컬 서버를 Node.js로 만들어줘.
[동작 방식]
- 콘텐츠 폴더에 publish.json 파일을 두면 서버가 읽어서 각 채널에 올림
- localhost 웹 대시보드에서 슬러그(콘텐츠 이름)별로 채널 업로드 버튼 클릭
- 업로드 성공 여부를 state.json에 저장 → 중복 업로드 자동 방지
[지원할 채널]
- YouTube: Data API v3, PNG들을 MP4로 자동 변환 후 업로드 (기본 비공개)
- Instagram: Graph API — 릴스(영상)와 캐러셀(이미지 묶음) 둘 다
- Threads: Threads API
- Bluesky: AT Protocol
[publish.json 형식]
{
"youtube": { "title": "...", "description": "...", "tags": [] },
"instagram": { "reel": { "caption": "..." }, "carousel": { "caption": "..." } },
"threads": { "caption": "..." },
"bluesky": { "text": "..." }
}
[폴더 구조]
콘텐츠/{슬러그}/
├── cardnews-01.png (카드뉴스 PNG)
└── publish.json
OAuth 토큰은 tokens.json에 보관.
App ID·Secret은 .env로 관리.
서버는 localhost:3791에서 실행.
실제로 쓴 프롬프트를 공개합니다
기술적인 설명보다 프롬프트가 더 도움이 될 것 같아서 실제로 썼던 것을 그대로 가져왔습니다.
이게 전부입니다. 거창한 기술 명세서 같은 건 없었어요. 원하는 걸 자연어로 설명하면 클로드가 Node.js 서버 코드를 써주고, 오류가 나면 같이 디버깅하면서 완성했습니다.
이런 소식, 남들보다 먼저 받으실 분?
직접 돌려보고 되는 것만 골라 매주 보내드립니다. 광고성 하이프는 거릅니다.
한 줄 요청이 완성품이 되기까지 — 실제 대화 흐름
"한 줄 프롬프트로 만든다"는 게 마법처럼 들릴 수 있는데, 실제로는 몇 번의 주거니받거니가 있었습니다. 아래가 채널 게시 서버를 만들던 날의 실제 흐름입니다.
💡 오류 메시지를 그대로 붙여넣는 게 핵심입니다. "이거 안 돼요"가 아니라 오류 텍스트 전체를 복붙하면 클로드가 정확히 어디서 막혔는지 알고 해결책을 줍니다.
지금 쓰고 있는 것들
① 5개 채널 동시 배포
유튜브, 인스타그램, 틱톡, 쓰레드, 블루스카이에 카드뉴스를 올릴 때, 채널별로 각각 로그인해서 업로드하던 걸 이제는 하지 않습니다. publish.json 파일 하나에 채널별 제목·설명·태그를 정리해두고, 대시보드에서 버튼 하나로 전부 올립니다.
각 플랫폼의 API를 연결하는 데 시간이 좀 걸리긴 했지만, 한 번 세팅해두면 매번 반복 작업이 없어지니까 그 시간을 금방 회수합니다.
② 블로그 이웃 댓글 반자동
네이버 블로그 이웃 방문·댓글이 마케팅에서 중요하다는 건 알았는데, 매번 직접 쓰다 보면 금방 지치더라고요.
"반자동 방문 시작"을 누르면 이렇게 흘러갑니다:
- 블로그 글을 열고 2~3분 랜덤으로 체류합니다. 블로그는 체류 시간도 신호로 읽기 때문에, 들어가서 바로 나오는 게 아니라 실제 독자처럼 머무는 시간을 씁니다.
- AI가 해당 글 내용을 읽고 맥락에 맞는 댓글 초안을 작성합니다. 글 제목만 보고 쓰는 게 아니라 본문을 실제로 읽어서 내용에 반응하는 댓글이 나옵니다.
- 화면 우측에 진행 팝업이 뜨고, 초안을 확인하고 [등록]만 클릭하면 됩니다. 마음에 안 들면 [건너뛰기], 멈추고 싶으면 [중지].
완전 자동이 아닌 이유는 의도적입니다. 댓글 하나하나를 내가 눈으로 확인하고 올리는 것과 아닌 것은 품질 차이가 납니다. 체류 시간은 알아서 채워주니까, 실제로 내가 하는 일은 초안 확인하고 클릭하는 것뿐 — 걸리는 시간이 건당 10초 안쪽입니다.
③ 통합 현황 대시보드
앱 설치 수, 평점, 리뷰, 블로그 글 수, 채널 게시 현황이 한 화면에 모여 있습니다. 플레이스토어 수치는 자동으로 긁어와서 갱신해줍니다. 아침에 한 번 열어보는 것만으로 마케팅 현황을 파악할 수 있어요.
대화에서 나온 아이디어가 사라지지 않는 구조
지표보다 더 실용적인 부분이 따로 있습니다. 클로드와 대화하다 발견한 것들, 아직 실행하지 못한 것들, 내린 결정들이 세 버킷으로 분류돼 대시보드에 항상 올라와 있습니다. "저번에 뭘 발견했었지?" 하고 대화를 거슬러 올라갈 필요가 없어요.
- 댓글 키워드 → Litt.ly 자동DM으로 블로그 유입 +500%
- 인스타 OAuth 막혔던 진짜 원인: 앱 시크릿 짝 불일치
- 터널 없이
code만 주소창에 복붙해도 인증 완료 - Firebase 릴레이 배포 → 터널 영구 제거
- AdSense 재검토 요청 (콘솔에서 제출 클릭)
- FieldMark 플레이스토어 심사 제출
- 네이버 블로그 최근 발행분 수동 미러링
- 신규 블로그는 라이트 테마만 — 네이버 미러링 호환
- 어필리에이트 링크엔 공정위 고지 의무화
- 채널 배포는 직접 개발 (Metricool 제거)
세션이 마무리되면 클로드가 dashboard-data.js를 자동으로 갱신합니다. 다음 세션을 열면 어디까지 했는지, 뭘 결정했는지를 바로 이어받아 처음부터 다시 설명하지 않아도 됩니다. 미뤄둔 아이디어도 대시보드를 열면 그 자리에 있습니다.
publish.json — 복붙해서 바로 쓰는 채널 배포 파일
채널 게시 서버는 콘텐츠 폴더에 publish.json 파일 하나가 있으면 작동합니다. 아래 형식을 그대로 복붙해서 내 내용으로 채우면 됩니다. 이 파일만 있으면 대시보드에서 버튼 하나로 5개 채널에 올라갑니다.
{
"youtube": {
"title": "영상 제목 — 훅이 담긴 한 문장으로",
"description": "설명란 첫 3줄이 핵심.\n유튜브는 '더보기' 전까지만 보임.\n\n링크·CTA를 앞쪽에.\n\n#해시태그 #이렇게",
"tags": ["키워드1", "키워드2", "키워드3"]
},
"instagram": {
"reel": { "caption": "릴스 캡션. 첫 줄이 훅.\n\n#해시태그" },
"carousel": { "caption": "캐러셀 캡션. 릴스와 같아도 됨.\n\n#해시태그" }
},
"threads": {
"caption": "Threads 본문. 500자 이하.\n링크 포함 시 노출에 유리.\n\n#해시태그"
},
"bluesky": {
"text": "Bluesky 본문. 해시태그 2~3개가 적당.\n\n#해시태그"
}
}
TikTok은 별도 항목이 없어도 됩니다. 서버가 영상을 초안함에 자동으로 올려주면, 앱에서 캡션만 입력해서 게시하는 방식입니다.
실제 작동하는 코드 구조
핵심은 ACTIONS 객체입니다. 대시보드에서 버튼을 누르면 action 이름으로 이 객체를 찾아 실행합니다. 채널 하나를 추가하고 싶으면 여기에 항목 하나만 넣으면 됩니다.
const ACTIONS = {
youtube: (slug) => uploadYoutube(slug),
"ig-reel": (slug) => publishReel(slug),
"ig-carousel": (slug) => publishCarousel(slug),
threads: (slug) => publishThreads(slug),
bluesky: (slug) => publishBluesky(slug),
tiktok: (slug) => tiktokInbox(slug), // 초안함 → 앱에서 게시
};
// 대시보드 버튼 클릭 → /api/action POST → ACTIONS[action](slug) 실행
if (req.method === "POST" && url.pathname === "/api/action") {
const { slug, action } = await readBody(req);
const result = await ACTIONS[action](slug);
return json(res, 200, { ok: true, result });
}
YouTube 업로드 엔진의 핵심 부분은 이렇게 생겼습니다. publish.json에서 메타데이터를 읽어 YouTube Data API v3로 영상을 올립니다. 실수 방지를 위해 항상 비공개로 먼저 올리고 Studio에서 확인 후 공개합니다.
export async function uploadYoutube(slug) {
const publish = getPublishJson(slug); // publish.json 읽기
const videoPath = await ensureVideo(slug); // 없으면 PNG → MP4 자동 생성
const youtube = google.youtube({ version: "v3", auth: getYoutubeClient() });
const res = await youtube.videos.insert({
part: ["snippet", "status"],
requestBody: {
snippet: {
title: publish.youtube.title,
description: publish.youtube.description,
tags: publish.youtube.tags,
},
status: { privacyStatus: "private" }, // 비공개로 올린 뒤 확인 후 공개
},
media: { body: fs.createReadStream(videoPath) },
});
saveState(slug, "youtube", { status: "done", videoId: res.data.id });
return { videoId: res.data.id };
}
돈으로 사면 얼마일까
블로그 교류 툴
대시보드 솔루션
합산 기준
나만의 커스텀 기능
내 워크플로우에 딱 맞게
언제든 수정 가능
물론 완전히 0원은 아닙니다. Claude 구독료는 냅니다. 그래도 시중 툴들을 다 구독하는 것보다 훨씬 저렴하고, 무엇보다 내 상황에 딱 맞게 만들 수 있다는 게 큽니다.
💡 핵심은 이겁니다. 클로드 같은 AI 코딩 도구가 생기면서, 코딩을 몰라도 "내가 원하는 것"을 말로 설명하면 도구를 만들 수 있는 시대가 됐어요. 마케팅 툴도 예외가 아닙니다.
직접 만들어보고 싶다면
카드뉴스 5번 슬라이드에 실제로 쓴 프롬프트를 적어뒀습니다. 저장해두고 그대로 클로드에 붙여넣어 보세요. 처음엔 완성도가 낮을 수 있는데, 오류가 나면 오류 메시지를 그대로 클로드에 보내면 대부분 해결해줍니다.
시작은 가장 쓸 만한 것 하나만 만들어보는 것도 좋습니다. 채널 배포가 귀찮다면 채널 게시 서버부터, 블로그 교류가 시간을 많이 잡아먹는다면 댓글 반자동부터요.
⚠️ 한 가지 주의사항: API 연결 단계에서 각 플랫폼의 개발자 계정 등록이 필요한 경우가 있습니다. 유튜브, 인스타 등은 OAuth 설정이 필요해서 처음엔 시간이 걸릴 수 있어요. 하지만 한 번만 하면 이후엔 계속 씁니다.
카드뉴스 저장해두시고, 다음 마케팅 작업에서 한 번 시도해보세요. 질문 있으시면 댓글로 남겨주시면 답변 드리겠습니다.
실측 위주 AI 뉴스레터 — 직접 돌려보고 되는 것만 골라 매주 보내드립니다.