
이전 글에서 Claude Code 서브에이전트로 블로그 글 발행을 자동화했다. 근데 글을 발행한 다음이 문제였다. LinkedIn 열어서 요약 쓰고, X에서 280자 맞춰 트윗 쓰고, Threads랑 Instagram에도 올리고. 글 하나 쓸 때마다 네 번 반복이다.
이걸 자동화하고 싶었다. PayloadCMS에서 글을 발행하면 n8n이 웹훅을 받아서 Claude API로 플랫폼별 요약을 만들고, Postiz를 통해 네 곳에 동시에 올리는 파이프라인을 만들었다.
파이프라인은 6개 노드짜리 n8n 워크플로우 하나로 돌아간다.
PayloadCMS의 afterChange 훅이 글 발행을 감지하면 n8n 웹훅으로 POST 요청을 보낸다. n8n은 블로그 콘텐츠를 조회하고 Claude API를 호출해서 LinkedIn, X, Threads, Instagram 각각에 맞는 요약문을 생성한다. 마지막으로 Postiz API를 통해 네 플랫폼에 동시 배포한다.
n8n에서 Claude API를 연동하는 방법은 두 가지가 있다. 커뮤니티 노드를 쓰거나, HTTP Request 노드로 직접 호출하거나. 나는 후자를 골랐다. 프롬프트와 파라미터를 세밀하게 제어하고 싶어서.
프롬프트는 단순하게 짰다. 블로그 본문을 넘기면서 플랫폼별 글자 수 제한과 톤을 지정하고, JSON으로만 응답하라고 했다.
Based on the following blog post, generate optimized social media
summaries for 4 platforms.
1. LinkedIn (max 1300 chars): Professional tone, key insights
2. X/Twitter (max 280 chars): Concise and punchy
3. Threads (max 500 chars): Conversational, engaging hook
4. Instagram (max 2200 chars): Storytelling, hashtags at end
Return JSON only: {"linkedin","x","threads","instagram"}한 가지 주의할 점이 있다. Claude가 JSON을 반환할 때 가끔 markdown code fence로 감싸서 보내준다. 그래서 파싱 전에 fence를 벗기는 로직을 추가했다.
// Claude API 응답에서 JSON 추출
let textContent = response.content
.filter(b => b.type === 'text')
.map(b => b.text).join('');
// markdown code fence 제거
textContent = textContent
.replace(/```json\n?/g, '')
.replace(/```\n?/g, '').trim();
const summaries = JSON.parse(textContent);솔직히 이 글의 본체는 여기다. Postiz의 Public API 문서가 불완전해서 같은 날 커밋을 세 번이나 고쳤다.
첫 번째 삽질은 엔드포인트였다. /api/posts로 보냈더니 404. 실제 경로는 /public/v1/posts였다.
두 번째는 인증 형식. Bearer {key} 형식으로 보냈더니 401. Postiz는 API 키를 raw로 보내야 했다. Authorization 헤더에 키 값만 넣으면 된다.
세 번째는 request body 구조. 단순히 content 필드에 텍스트를 넣는 게 아니라, value 배열 안에 content와 image를 넣고, settings에 __type으로 플랫폼을 지정하는 구조였다.
{
"type": "now",
"posts": [
{
"integration": { "id": "linkedin-integration-id" },
"value": [{ "content": "요약문", "image": [] }],
"settings": { "__type": "linkedin" }
}
]
}n8n에서 Anthropic API 키를 쓰려면 크리덴셜 시스템을 이용하는 게 정석이다. $credentials.anthropicApi.apiKey 같은 식으로 접근하면 되는데, HTTP Request 노드의 헤더에서는 이 참조가 제대로 동작하지 않았다. 결국 $env.ANTHROPIC_API_KEY로 환경변수를 직접 참조하는 방식으로 바꿨다. 배포 환경에서 관리하기도 더 편하다.
CMS 훅으로 이벤트를 잡고, AI로 콘텐츠를 변환하고, 외부 API로 배포하는 패턴은 꽤 범용적이다. 블로그 말고도 제품 업데이트 공지나 뉴스레터 같은 곳에 비슷하게 적용할 수 있을 것 같다.
다만 외부 API 연동에서 삽질은 피할 수 없다. 특히 Postiz처럼 문서가 불완전한 서비스는 시행착오가 필수다. 이번에도 하루 만에 커밋 4개를 찍었으니까. 그래도 한번 파이프라인을 만들어두면 글 발행 버튼 하나로 네 곳에 동시 공유가 되니 충분히 값어치가 있다.