# 블로그 가져오기

다른 곳에 써 둔 글을 **내 도메인의 정적 페이지**로 옮깁니다. 글 하나가 `/blog/{slug}/` 페이지가 되고, 목록 페이지 `/blog/` 가 함께 만들어집니다.

옮기고 나면 그 글은 내 사이트의 일부입니다 — 원본 서비스가 문을 닫아도, 요금제가 바뀌어도 남습니다. 페이지는 서버에서 완성된 HTML 로 나가므로 검색엔진과 AI 검색이 본문을 그대로 읽습니다.

**추가 비용은 없습니다.** 호스팅에 포함된 기능입니다.

---

## 먼저 알아 둘 것

**주소를 넣는 칸이 없습니다.** 새로온은 남의 블로그를 대신 긁지 않습니다. 글은 **여러분이 가져와서** 넘깁니다.

**워드프레스라면 내보내기 파일을 그대로 주면 됩니다.** 관리자 > 도구 > 내보내기 > "모든 콘텐츠" 로 받은 `.xml` (WXR) 을 CLI 에 그대로 넘기세요. 변환 단계가 없습니다.

**본인 글만 옮기세요.** 직접 쓴 글, 또는 권리를 가진 글이어야 합니다.

**유료·회원 전용 글은 빼세요.** 옮긴 페이지는 공개됩니다.

**원본은 아직 지우지 마세요.** 본문 안의 이미지는 새로온이 받아서 사이트로 옮겨 담지만, 원본이 살아 있는 동안 옮기는 것이 안전합니다.

---

## 넘기는 형식

두 가지를 받습니다. **확장자가 아니라 파일 내용으로 판정**하므로 이름은 아무래도 좋습니다.

### 1. 워드프레스 내보내기 (`.xml`, WXR)

받은 파일을 그대로 주면 됩니다. 새로온이 알아서 걸러 냅니다:

| | |
|---|---|
| 가져오는 것 | **공개된 글**(post · publish) |
| 빼는 것 | 페이지 · 첨부 · 메뉴 항목 · 초안 · 예약 발행 |
| 🔴 버리는 것 | **댓글 전체** — 작성자 이메일·IP 가 들어 있어 저장하지 않습니다 |

무엇을 왜 뺐는지는 결과에 건수로 나옵니다.

### 2. 글 목록 JSON (`.json`)

직접 만들거나 AI 에게 시켜서 만든 목록입니다. 최상위가 배열이거나 `{ "posts": [...] }` 이면 됩니다.
키는 `publishedAt` · `published_at` 처럼 **camelCase·snake_case 둘 다** 받습니다.

```json
[
  {
    "sourceUrl": "https://old.example.com/2025/03/hello-world",
    "title": "첫 글",
    "contentHtml": "<p>안녕하세요. 첫 글입니다.</p><img src=\"https://old.example.com/a.jpg\">",
    "publishedAt": "2025-03-01T00:00:00Z",
    "author": "김동건",
    "sourcePlatform": "tistory"
  }
]
```

| 필드 | 필수 | 설명 |
|---|---|---|
| `sourceUrl` | ✅ | 원문 주소. 페이지 주소(슬러그)와 "원문 보기" 링크의 근거이고, 다시 옮길 때 중복을 막는 열쇠입니다 |
| `title` | ✅ | 제목. `<h1>` · `<title>` · og:title 이 됩니다 |
| `contentHtml` | ✅ | 본문 HTML. **손대지 말고 원문 그대로** 넣으세요 (아래 참고) |
| `description` | | 요약. 없으면 본문 앞부분에서 자동으로 뽑습니다 |
| `publishedAt` | | ISO-8601 발행일 |
| `author` | | 작성자 |
| `sourcePlatform` | | 출처 표시용 자유 문자열(`tistory`, `wordpress` 등) |

`snake_case`(`source_url`, `content_html` …) 로 써도 받습니다.

### 본문을 미리 정리하지 마세요

`contentHtml` 은 서버가 **허용 목록 방식**으로 정리합니다. 문단·제목·목록·표·인용·코드·이미지·링크·유튜브/비메오 삽입만 남고, 스크립트·이벤트 핸들러·인라인 스타일·추적 픽셀·정체불명 삽입은 전부 제거됩니다.

미리 지우려다 본문을 깎아 먹는 쪽이 훨씬 흔합니다. 원문을 그대로 주세요.

> RSS 의 `description` 처럼 `&lt;p&gt;` 형태로 **이스케이프된** 본문이라면 그것만은 먼저 풀어서 넘기세요. 그대로 두면 태그가 글자로 남습니다.

---

## 옮기기

### CLI

```bash
# 워드프레스 내보내기 파일을 그대로
npx @saeroon/cli blog import wordpress.xml --site <siteId>

# 직접 만든 글 목록
npx @saeroon/cli blog import posts.json --site <siteId>
```

글이 많으면 **나눠서 올립니다**(한 번에 50건). CLI 가 알아서 반복하므로 기다리기만 하면 됩니다 —
워드프레스 내보내기 하나가 보통 그 상한을 넘습니다.

### AI 에게 시키기 (MCP)

MCP 를 연결했다면 `saeroon_import_blog_posts` 툴을 씁니다. AI 가 내보내기 파일을 읽어 형식을 맞추고 그대로 호출합니다.

### REST

```
# 이미 파싱한 글 목록 (JSON)
POST /api/v1/hosting/developer/sites/{siteId}/blog/import
X-API-Key: sk_live_...

# 내보내기 파일 그대로 (multipart — CLI 가 쓰는 통로)
POST /api/v1/hosting/developer/sites/{siteId}/blog/import-file
X-API-Key: sk_live_...
  file=@wordpress.xml  offset=0
```

모두 같은 일을 합니다. 한 호출이 **50건**까지 처리합니다 — 이미지 내려받기까지 한 응답 안에서 끝내기 때문입니다.
파일 업로드 통로는 응답의 `remaining` 이 0이 될 때까지 `offset` 을 밀어 다시 부르면 되고, **CLI 는 그 반복을 알아서 합니다**.

이미 옮긴 글을 **다시 보내면 그 페이지를 새 내용으로 갈아끼웁니다 — 주소는 그대로입니다.** 원문을 고쳤을 때나 중간에 실패해 다시 돌릴 때 안전합니다. (판정 기준은 `sourceUrl` 이고, 추적용 쿼리 파라미터는 무시합니다. 서로 **다른** 두 글이 같은 슬러그가 되는 경우에만 뒤엣것에 번호가 붙습니다.)

---

## 🔴 결과에서 반드시 볼 것: `manifestMerged`

응답의 `manifestMerged` 가 `true` 인지 확인하세요.

새로온은 사이트가 어떤 파일들로 이루어졌는지를 목록으로 관리합니다. 옮긴 페이지가 **그 목록에 들어가야** 사이트의 정식 구성원이 됩니다. 목록에 못 들어간 페이지도 당장은 정상적으로 열리기 때문에 화면만 봐서는 아무 문제가 없어 보이지만, 나중에 정리 작업이 돌 때 "아무도 모르는 파일" 로 판단되어 지워집니다.

- CLI 는 이 경우 **실패(exit 1)** 로 끝내고 이유를 알려 줍니다
- MCP 는 `status` 를 `imported_without_manifest` 로 돌려줍니다

**가장 흔한 원인**: 그 사이트를 **한 번도 배포한 적이 없어서** 합칠 목록 자체가 없는 경우입니다. `npx @saeroon/cli deploy <folder>` 를 한 번 돌린 뒤 다시 가져오세요.

---

## 만들어지는 페이지

- 주소는 원문 주소의 마지막 조각에서 따옵니다. 못 쓰면 제목에서 만듭니다. **다른 글**이 이미 쓰는 주소면 뒤에 번호가 붙고 경고가 남습니다(같은 글을 다시 옮기는 경우는 제 주소를 지킵니다)
- `<link rel="canonical">` 이 **내 사이트**를 가리킵니다 — 검색엔진이 이쪽을 원본으로 봅니다
- 본문 끝에 원문 링크가 남습니다
- 본문 이미지는 내 사이트로 옮겨 담기므로 원본이 사라져도 계속 보입니다
- 페이지는 외부 폰트·스크립트를 하나도 부르지 않습니다

응답에는 정리된 양(`sanitizedElementsRemoved` / `sanitizedAttributesRemoved`)과 옮긴 이미지 수도 들어 있어, 무엇이 걸러졌는지 확인할 수 있습니다.

---

## 자주 묻는 것

**같은 글을 다시 옮기면?** 그 페이지를 새 내용으로 **갈아끼웁니다 — 주소는 그대로입니다.** 원문을 고쳤을 때나 중간에 실패해 다시 돌릴 때 안전합니다. (서로 **다른** 두 글이 같은 주소가 되는 경우에만 뒤엣것에 번호가 붙습니다.)

**정적 사이트가 아니면?** 정적 사이트에만 가져올 수 있습니다.

**네이버 블로그는?** 가져오기 대상이 아닙니다. 네이버는 공식 내보내기가 PDF 뿐이고 다시 불러올 수 없다고 명시하고 있어, 옮기는 통로를 제공하지 않습니다.
