Skip to main content

BlogLoom Publisher Skill — CSDN Channel Capabilities and Publishing Flow

Audience: developers and AI agents who need to understand, maintain or extend the BlogLoom publishing skill. Channel implementation: skills/blogloom-publisher-skill/scripts/channels/csdn/ Channel SOP: references/channels/csdn/sop.md Common contract: references/00-tool-contract.md

1. Channel overview

CSDN is the skill’s first integrated channel. Primary operations go through Playwright (visible browser, real clicks/typing/pasting), while CDP is only used for low-level enhancement (reusing login state, Input.insertText as a rich-text fallback, reading HttpOnly cookies to detect login). It defaults to headed mode, visible throughout.

2. Action matrix

test publish verifies “the publishing flow works and leaves no residual content”. CSDN supports rollback after publishing, hence PUBLISHED_AND_DELETED.

3. Unified invocation

Unified output (stdout):
Logs go to stderr (prefixed [publisher]), which makes parsing by agents easy.

4. SOP field mapping (Markdown → CSDN)


5. Scenario flows in detail

5.1 csdn checkLogin — detect login state

Steps
  1. Open the home page https://www.csdn.net/;
  2. Read the .toolbar-btn-loginfun text: if it says “登录” (login), the user is not logged in;
  3. If the “创作” (create) entry is present and not in a login state, or the cookies contain UserToken + UserInfo → logged in;
  4. Also return whether a slider .verify-move-block exists (data.hasSlider).
Return

5.2 csdn login — QR login

Steps
  1. Open https://passport.csdn.net/login (headed mode);
  2. The user scans the QR code / types credentials (including any slider verification, which the script does not bypass);
  3. Poll the login cookies every 2s; success when UserToken / UserInfo appear (10 minutes max by default);
  4. Login state is saved in a dedicated profile: ~/.blogloom-publisher/chrome-profile-csdn.

5.3 csdn publishDraft — save draft

Steps
  1. Enter the editor: click “创作” .toolbar-btn-write-new on the home page (fall back to opening editor.csdn.net/md/ directly);
  2. Fill the title: click the display state .article-bar__title-display (“【无标题】”) to reveal the hidden input.article-bar__title, clear it, type the title, then read back to verify;
  3. Write the body:
    • Click .editor__inner.markdown-highlighting (<pre contenteditable>);
    • Select all and delete the default welcome content;
    • Paste using the paste → cdp → keyboard strategy (clipboard paste first, CDP Input.insertText as a fallback);
    • When the body contains images, estimate a wait based on image count (2s base, +3s per 5 images) to ensure async upload completes;
  4. Click “保存草稿” button.btn-save at the top → status=DRAFT_SAVED.
Tags/summary/category are not configured during the draft stage (they can be added later in the editor or when publishing).

5.4 csdn publish — publish

On top of the draft flow, click “发布文章” button.btn-publish to open the .modal__publish-article dialog, and configure each item: --dry-run: completes all filling and dialog configuration but does not click final publish, returning status=DRY_RUN and publishConfig. Actual publish: click .modal__button-bar button (publish) at the bottom of the dialog, take the link from the success dialog a.success-modal-btn[href*="/article/details/"] (strip query params), and return status=PUBLISHED with url.

5.4.1 Channel-level publishing config (conf/csdn.conf)

The article’s title/tags/category/summary/columns/cover come from the blog’s top SOP metadata; the following channel-level options come from conf/csdn.conf, read by default at runtime:
Priority: CLI args > metadata > conf default. See scripts/lib/channel-conf.js for the loader.

5.5 csdn delete — delete a post

Steps
  1. Go to the content management page https://mp.csdn.net/mp_blog/manage/article;
  2. Locate the post row .article-list-item-mp by --id (a[href*="/article/details/<id>"]) or --title;
  3. Hover the row → the ”…” on the right .el_mcm-dropdown .el-dropdown-link;
  4. Click “删除” in the dropdown .el_mcm-dropdown-menu__item;
  5. Click “确定” in the confirmation dialog .btn-msg-confirm;
  6. Verify the row has disappeared from the list → DELETED, otherwise DELETE_UNVERIFIED.
Key point: you must click “确定” in the confirmation dialog, or nothing is actually deleted.

5.6 csdn test publish — publish → delete flow self-test

Combines publish + delete: after a successful publish, delete immediately by URL/id, returning PUBLISHED_AND_DELETED to verify the publishing flow works and leaves no residual content.

6. Selector reference (channels/csdn/selectors.js)

When the site changes, only edit this file; business-flow code stays untouched.

7. Error codes and branches

Exit codes: 0 success (including DRY_RUN) / 1 execution error / 2 checkLogin not logged in or login timed out.

8. Verification and maintenance

  • --dry-run returns contentStrategy (the effective write strategy), contentLength and publishConfig, useful to confirm each field was written;
  • test publish verifies the full flow and leaves no residual content;
  • Unit tests cover: checkLogin / enterEditor / setTitle / setContent / preparePublish / publish / saveDraft / deleteBlog.

Next steps