n8n을 활용한 Notion-to-blog 파이프라인 생성하기
notion에 있는 글을 블로그로 업데이트하기 위한 자동화 방법을 고민하던 중 n8n이라는 오픈소스 툴을 발견하게 되었습니다. 해당 툴을 기반으로 블로그 포스트를 Ghost self-hosting 블로그로 업데이트 하기 위한 방법을 정리하였습니다.
개요
notion에 있는 글을 블로그로 업데이트하기 위한 자동화 방법을 고민하던 중 n8n이라는 오픈소스 툴을 발견하게 되었습니다. 해당 툴을 기반으로 블로그 포스트를 Ghost self-hosting 블로그로 업데이트 하기 위한 방법을 정리하였습니다.
파이프라인
- 노션과 통합하여 페이지 정보를 가져옵니다(id, title…)
- 페이지 아이디를 통해 Notion page 상세 데이터를 Markdown으로 가져옵니다.
- https://github.com/souvikinator/notion-to-md 가져온 Notion Properties 페이지를 Markdown으로 변환합니다.
- Notion Image의 경우 pre-signed url로 만료되기 때문에, 따로 Bucket을 생성하여 CloudFront를 연결하였습니다.
- 변환된 Markdown을 Ghost에 업로드하기 위해 HTML로 변환합니다.(Markdown to HTML)
- 블로그 포스트 업로드 완료

파이프라인 구성 방식은 다음과 같습니다.
Notion 데이터 가져오기
API 토큰을 생성하고 연결을 클릭하여 API Token이 Notion에서 활용될 수 있도록 설정합니다.
Notion API Token을 활용하기 위한 문서는 아래를 참고하였습니다.

notion에서 연결을 완료헀다면 데이터베이스에서 데이터를 가져올 수 있습니다. n8n에서 notion credential를 등록합니다.
credentials까지 설정 완료됐다면 n8n에 notion node를 활용하여 getAll: databasePage
를 수행합니다.

Notion에서 Markdown으로 변환하기
Notion에 있는 글을 Ghost 블로그에 업로드하기 위해선 HTML 형식이 필요합니다.
하지만 노션은 직접적으로 HTML 형식으로 출력되지 않고 자체적인 block 단위로 페이지를 리턴해주기 때문에 추가적인 변환이 필요했습니다.
HTML로 변환할 수 있는 툴들은 Github에서 찾을 순 있었지만 Deprecated된 프로젝트들이 많았습니다. 따라서 html로 직접 변환하기보단 n8n 자체에서 markdown-to-html 노드를 지원하기 때문에 notion-to-md를 활용하여 2번 변환하는 것으로 결정하였습니다.
추가 문제로 notion에서는 api를 활용하여 이미지 블록을 출력할 때 pre-signed url로 출력하여 일정 시간 이후로 만료되게 설정되어있기 때문에 이런 이슈를 해결하기 위해서도 notion-to-md가 적합하였습니다.
setCustomTransformer
코드를 통해 제 S3로 업로드하고, CloudFront를 활용하여 CDN을 구성하여 개선하였습니다. 해당 CloudFront의 링크를 최종적으로 html 태그로 리턴하였습니다.
n2m.setCustomTransformer("image", async (block) => {
const { image } = block;
try {
// 1. 이미지 다운로드
const response = await axios.get(image.file.url, {
responseType: 'arraybuffer'
});
const imageType = response.headers['content-type'];
// // 2. S3에 업로드할 파일 이름 생성
const fileName = `images/${block.id}.png`;
// 3. S3 업로드 명령 생성
const command = new PutObjectCommand({
Bucket: process.env.AWS_BUCKET_NAME,
Key: fileName,
Body: response.data,
ContentType: imageType,
ContentDisposition: 'inline'
});
// 4. S3에 업로드 실행
await s3Client.send(command);
return `<img src="${process.env.AWS_CLOUDFRONT_URL}/${fileName}" alt="Notion Image" />`;
} catch (error) {
console.error('이미지 처리 중 에러:', error);
}
});

Ghost upload
Notion → Markdown → HTML까지 구성이 완료되었으므로 이제 Ghost로 업로드하는 노드가 필요합니다.
n8n에서는 Create Post라는 노드를 지원하고 있으므로 각 파라미터를 채워 업로드하면 완료입니다.
결론
n8n을 통해 notion-to-ghost 파이프라인을 구성하였습니다.
필요에 따라 노드를 추가하였고 장기적으로 블로그를 운영하기 위해 다양한 구성을 추가하려고 합니다.
