naver-blog-publish

star 0

마크다운 파일을 네이버 블로그 SmartEditor ONE에 자동 발행할 때 사용. 트리거 "/naver-publish <md_path>", "/naver-publish", "네이버에 올려". macOS 본진/맥미니, 본인 계정·자동로그인 세션·기본 전체공개 조건에서만 사용.

ssamssae By ssamssae schedule Updated 6/9/2026

name: naver-blog-publish description: 마크다운 파일을 네이버 블로그 SmartEditor ONE에 자동 발행할 때 사용. 트리거 "/naver-publish ", "/naver-publish", "네이버에 올려". macOS 본진/맥미니, 본인 계정·자동로그인 세션·기본 전체공개 조건에서만 사용.

네이버 블로그 자동 발행 v1

마크다운 1개를 강대종 본인 네이버 블로그(ssamssae)에 자동 발행. macOS 노드 (🍎 Mac 본진 / 🏭 맥미니) 한정. 본인 계정 + 본인 자동로그인 세션 + 기본 전체공개. 3조건 중 하나라도 깨지는 요청이 오면 NO GO 회귀.

(2026-05-15: "1일 1~2건" 빈도 룰 강대종 명시 directive 로 드롭. 그 외 3조건은 유지.)

iframe 접근 / 임시저장 팝업 / 제목 API / 본문 paste / 발행 모달 selector 상세는 SMARTEDITOR.md. 검증 PASS 기록 + 미해결/후속 / 설계 변경 이력은 HISTORY.md.

음성 컨텍스트 (T-260615-10): 본문 생성·다듬기 전 ~/claude-skills/voice-playbook.md (강대종 말투 가이드) 를 읽고 톤 적용 — 네이버 독자 대상이라 기술 용어는 한 번 풀어주기.

0. 사전 가드 (skip 금지)

  1. hostname 출력이 USERui-MacBookPro* (🍎 본진) 또는 mac-mini (🏭 맥미니) 인지 확인. WSL/desktop/notebook 에서 호출 시 즉시 중단.
  2. 메모리 project_naver_blog_auto_publish_dropped.md + feedback_no_login_automation_for_terminated_apis.md 3조건:
    • 본인 계정 + 본인 블로그
    • 본인 자동로그인 세션 (자동 로그인 자동화 X)
    • 기본 공개설정 = 전체공개 (all). 2026-05-01 강대종 directive 로 closed → all 변경. Substack/GitHub Pages/daejong-page 와 일관성 + verifiable goal 의 공개 URL fetch 모순 해소.
    • (drop) 1일 1~2건 — 2026-05-15 강대종 directive 로 드롭. 대량 발행 OK.
  3. 입력 인자 파싱:
    • --md <path> (필수)
    • --title <text> (옵션, 없으면 md 의 첫 # h1 줄 사용. 둘 다 없으면 파일명 stem)
    • --category <name> (옵션)
    • --open all|closed|neighbor (옵션, 기본 all)

1. 마크다운 → HTML

python3 ~/.claude/skills/naver-blog-publish/scripts/md_to_html.py "$MD" > /tmp/naver_body.html
cp "$MD" /tmp/naver_body.md

md_to_html.py# h1 라인을 자동 제거 후 HTML 변환 — h1 듀플(제목 셀 + 본문 paste 양쪽 노출) 회피용. 첫 h1 은 제목 셋 fallback 으로만 사용, 본문 paste 에는 안 들어감.

표(table) 가 들어가는 글이면 reference_substack_publish_pipeline.md 의 표→리스트 변환 함수 먼저 적용한 뒤 HTML 변환. nl2br extension 절대 쓰지 말 것.

2. Playwright MCP 세션 점검

mcp__plugin_playwright_playwright__browser_tabs(action=list) 로 탭 목록 조회.

() => {
  return { url: location.href, hasNickname: !!document.querySelector('.MyView-module__profile_box___QKPGA, [class*="profile_box"]') };
}

https://www.naver.com 탭에서 MyView-module__profile_box 등으로 닉네임이 나타나면 로그인 OK. 안 나오면 텔레그램으로 강대종에게 "1회 네이버 로그인 부탁" 한 통 + 작업 중단.

3. 글쓰기 페이지 + 임시저장 팝업

새 탭 https://blog.naver.com/GoBlogWrite.naver 진입 → iframe #mainFrame 안에서 임시저장 팝업 점검 + dismiss.

상세 selector + 두 축 enumerate (layer/modal + button 텍스트) = SMARTEDITOR.md §임시저장 팝업.

4. 제목 입력

⚠️ 뉴스레터 ep 발행 시 제목 컨벤션 강제 (2026-06-09, issues/2026-06-09-ep32-dup-naver-publish.md): --md 가 뉴스레터 ep(src/content/newsletter/epN.md)거나 발행 맥락이 뉴스레터면, --title 은 반드시 python3 ~/.claude/skills/newsletter-publish/scripts/canonical_title.py <ep_md> 출력("바이브코딩 뉴스레터 Ep.N — …")으로. md 첫 h1·frontmatter 원제목을 직접 쓰면 Ep.N prefix 가 빠진다(맥미니 ep32 사고 = 채널 스킬 직접 호출로 오케스트레이터의 prefix 단계 우회). 뉴스레터 외부발행은 newsletter-publish 오케스트레이터 경유가 디폴트.

iframe 안 SmartEditor._editors.blogpc001._documentService.setDocumentTitle(title) 한 호출. 가상 contenteditable 이라 표준 paste/click 안 통함.

상세 코드 + deprecated 폴백 + editor key 발견 패턴 = SMARTEDITOR.md §제목 입력.

5. 본문 입력 (NSPasteboard + Mac 시스템 keystroke)

순서: (a) pb_set_html.sh 로 NSPasteboard 에 HTML+plain 동시 set → (b) snapshot 으로 본문 placeholder paragraph ref 캡처 → (c) browser_click (OS-level 진짜 클릭, DOM .click() 아님) → (d) osascript ... keystroke "v" using command down (OS-level Cmd+V).

⚠️ 핵심: Playwright browser_press_key('ControlOrMeta+v') 는 SmartEditor 가상 입력 시스템을 우회. OS-level keystroke 만 paste 전달. + browser_click 빠뜨리면 paste 0자 회귀 (2026-05-23 Ep12 사고).

상세 코드 + 검증 evaluate + 폴백 = SMARTEDITOR.md §본문 입력.

⚠️ paste 실패 시 하드 가드 (무한 재시도·즉흥 paste 금지):

  1. frontmost 선행 확인 — OS-level Cmd+V 직전 반드시 Chromium 을 frontmost 로 올리고 검증: activate(osascript -e 'tell application "Google Chrome" to activate', 실제 Playwright 앱명에 맞춤) + frontmost 확인(osascript -e 'tell application "System Events" to name of first process whose frontmost is true'). frontmost 가 Chromium 이 아니면(시리/다른 앱이 포커스 탈취 시 — 2026-06-07 사고 원인) Cmd+V 가 엉뚱한 창에 가 paste 0자가 된다. 아니면 1회만 재activate.
  2. 정해진 방법으로만, 최대 2회 — (a)pb_set→(b)snapshot→(c)browser_click(OS-level)→(d)Cmd+V(key code 9 using {command down}, SMARTEDITOR.md §OS-level Cmd+V) 순서로만. 글자수 검증(SMARTEDITOR.md §검증)이 0자면 frontmost 다시 잡고 딱 1회만 더. 합 2회.
  3. 2회 실패 = 즉시 abort + 보고 — 더 시도하지 말고 텔레그램으로 "네이버 본문 paste 실패(frontmost 탈취 추정), 수동 확인 필요" 보고 후 중단. 절대 금지: ClipboardEvent/DataTransfer 합성, clipboard API dispatch, 기타 즉흥 paste 방법을 무한 시도(2026-06-07 /worklog→네이버 발행이 이 즉흥 재시도로 55분·104k 토큰 루프, 본진 frozen·아니키 메시지 큐 적체 사고).

주의: osascript activate 가 강대종 Mac 포커스를 빼앗는다. 새 자동 발행 사이클마다 한 번씩만. 강대종이 다른 작업 중일 때는 사전 양해 필요.

6. 발행 모달

iframe 안 [data-click-area="tpb.publish"] 클릭 → 모달의 공개설정/카테고리 확인 (기본 all, 인자 명시 시만 변경) → [data-testid="seOnePublishBtn"] 최종 발행 클릭 → 5초 대기 → https://blog.naver.com/ssamssae/<postNo> redirect.

상세 selector + 공개설정 라디오 변경 + 카테고리 dropdown = SMARTEDITOR.md §발행 모달.

harness 권한: v1 검증 시 발행 버튼 evaluate-click 이 harness 에 거부될 수 있음 (정상적인 안전 가드). 강대종이 .claude/settings.json 에 permission rule 추가하거나, 첫 1회는 강대종이 직접 모달까지 수동 클릭해 selector 확정 후 SKILL.md update.

7. 결과 URL 캡쳐 + 검증 (verifiable goal)

발행 후 https://blog.naver.com/ssamssae/<postNo> 패턴 capture.

() => ({ url: location.href, mainFrameUrl: document.querySelector('iframe#mainFrame')?.src });

기본 --open all 이면 인증 없이 공개 URL fetch:

  1. https://blog.naver.com/ssamssae/<postNo> curl/WebFetch (인증 X)
  2. article DOM 의 제목/본문 첫 30자 파싱 + 매치 검사
  3. 제목 정확 일치 + 본문 첫 30자 일치 → PASS

--open closed 명시된 경우만 fetch 가 막히므로 Playwright 같은 세션 안에서 진입해 DOM 매치로 검증.

8. 텔레그램 보고

PASS 시 강대종 (chat_id=538806975) 에게 1통:

✅ 네이버 블로그 자동 발행 v1 PASS
발행 URL: <url>
호출: /naver-publish <md_path>
공개설정: all (전체공개)
호스트: $(hostname) · HH:MM KST

차단/실패 시 1줄 사유 + 다음 단계 후보 surface 없이 대기.

금지/주의 (hard rules)

  • Playwright 시스템 Chrome --remote-debugging-port attach 금지 (Chrome 136+ default user-data-dir 거부). MCP 내장 Chromium 만 사용.
  • 자동 로그인 자동화 금지. 강대종 본인 자동로그인 세션을 그대로 활용.
  • 3조건 (본인계정/본인세션/기본 전체공개 all) 중 1개라도 깨지는 요청이 오면 즉시 NO GO 회귀. 2026-05-01 강대종 directive 로 #4 = closed → all 변경.
  • 캡차/2FA 발견 시 우회 시도 X. 강대종 결정 대기.
  • 첫 풀그린 검증 글은 강대종이 보고 받은 직후 공개/비공개/삭제 결정.
  • 다른 탭 (ASC, etc.) 건드리지 말 것 — 새 탭 1개에서만 작업.
Install via CLI
npx skills add https://github.com/ssamssae/claude-skills --skill naver-blog-publish
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator