SuperAPI AI Directory

lov-publish-wechat-article

Writing & research

View repository

Updated 10-16 00:01

About this skill

Publish a WeChat Official Account article

Model "prepare content", "write to remote draft", "submit for publication", and "platform publication complete" as distinct states. All WeChat Official Account API requests are by default sent through api.lovstudio.ai 's unified gateway, with the backend using a fixed egress to communicate with WeChat; the local machine does not need to be added to the WeChat IP allowlist.

Triggers

Activate when

  • The user requests to import, sync, or save Markdown, HTML, or plain text to the WeChat Official Account draft box.
  • The user requests to set the original declaration, recommendation text, author, read original, or brand cover for an Official Account draft, and verify the saved result.
  • The user requests to submit an existing media_id for official publication, or to query the publication status of an existing publish_id .
  • The user requests to read the current draft, replace the cover, insert or modify a clearly defined section, and confirm the saved result.
  • English triggers include “Publish this article to WeChat”, “Save this as a WeChat Official Account draft”, “Read this existing draft”, and “Verify that this edit persisted”.

Do not activate when

  • The user only requests designing a cover, the first image of the body, or a unified brand component; use the corresponding article brand or cover Skill.
  • The user only requests generating local article content and does not request writing to the WeChat Official Account; use the article creation or formatting Skill.
  • The user only requests analyzing local Markdown but does not request reading the Official Account's remote state; use the article creation or audit capability.

Input contract

Collect and confirm:

  • Body: one Markdown, HTML, or plain text file. When the user provides the body only in the session, first save it as a temporary .md or .txt file for this task. Regular draft creation must first call lovpen-cli, and receive the WeChat copy-state HTML it writes out via --format wechat ; do not receive the --format standalone output and then rebuild the layout.compact-markdown is reserved only for explicitly diagnosing the old pipeline.
  • Content quality handoff: the publisher consumes canonical Markdown that has already completed content proofreading, and is not responsible for changing academic-style sections into internet-savvy titles. When an article contains research, reviews, benchmarks, rankings, total scores, or radar charts, the precheck must see "Test Method", "Prompt", "Evaluation Metrics", "Scoring Method", "Scoring Example", and "Reproduction Method" before the results, and must see "Limitations" after the results; thePrompt section must disclose at least one actually executed text. If missing, fail closed before any remote write.
  • Table of contents and small text: canonical Markdown provides stable H2/H3 and does not hard-code a presentational TOC; Lovpen generates the table of contents and reading time in the WeChat HTML based on the final sections, avoiding drift between the two sets of titles in the body and the table of contents. Interspersed materials, sources, and extended links use understated small text in place; multiple items are split line by line or point by point, not squeezed into one paragraph, and not piled up at the bottom. For the complete convention, see Lovpen editing and rendering handoff。
  • First image of the body: for regular publication, the first block of content in the Markdown must be an independent 4:3 horizontal first image, located before the lead-in, and must be a different file from the share cover.3:4 Vertical images, missing images, remote placeholder images, or directly reusing the finished share cover must not pass the precheck.
  • Body image captions: before Lovpen rendering, determine image by image whether readers need supplementary evidence, attribution, or explanation. Images that need captions must call lov-image-decorator, use an explicit Caption to generate a derived file and a JSON receipt that do not overwrite the original image, then change the image references in the article copy to the derived file; images that do not need a Caption remain as-is, without using Powered by ... fallback padding.
  • Publishing component: read the current official account brand Profile each time. Permanent blocks.endcap must include the approved bio, links, and enabled personal card;blocks.campaigns events that are still open, not full, and not expired must be placed before the endcap. For detailed status and fields, see Profile-driven publishing component。
  • Title: an explicit title takes precedence; Markdown can infer it from the first level-one heading. The final title must not exceed 32 characters.
  • Cover: regular draft creation must first call lov-wechat-branding-cover-composition, upload the JPG pointed to by cover-composition.json in its shareCoverUpload , and pass in this receipt at the same time. The publisher will verify the schema, the official Logo SHA-256,publisherLogoPresent and the uploaded file path; a Logo-free art background, an old cover, or other product assets must not be treated as the uploaded file.
  • Originality declaration: for new articles independently created by the current publishing account, the default is true; when there is reposting, compilation, co-authorship, or unclear rights, do not guess and check it.
  • Article recommendation: by default, write a short recommendation of 8–24 Chinese characters, giving readers a memorable point first; do not repeat the title, do not write "this article will", and do not use the summary as the recommendation.
  • Other optional fields: author (within 16 characters), summary (within 120 characters), Read Original URL, comment settings. When the user says "other defaults", keep the platform's current defaults and do not proactively flip unspecified switches.
  • Target account and action: save as draft only, publish publicly immediately, or query an existing publish_id。

Only hand the reader-facing body text to the platform. Supplementary background, character relationships, concerns, and other privateContext stay local.

Run the precheck first:

python3 <skill-dir>/scripts/preflight_article.py ARTICLE \
  --cover COVER \
  --cover-composition-receipt COVER_DIR/cover-composition.json \
  --lovpen-wechat-html ARTICLE.lovpen.wechat.html \
  --brand-profile BRAND_PROFILE \
  --title "TITLE" \
  --transport gateway \
  --json

--allow-unverified-body-hero is only for explicitly diagnosing the old pipeline and must not be used for normal delivery.

When omitting optional parameters, do not pass empty strings. When the script exits non-zero, first fix errors;warnings needs to be handled when selecting the transport. When the body contains local or remote images, read references/transport-routing.md。

Status semantics

Always use the following statuses, and do not blur them with the word "publish":

prepared
  -> draft_reading -> draft_read
  -> draft_editing -> draft_saved
  -> draft_creating
  -> draft_created
  -> draft_enriching
  -> draft_ready
  -> publish_submitted
  -> publishing
  -> published | publish_failed
  • draft_read: a comparable snapshot of the existing draft has been obtained, and no write was performed.
  • draft_saved: the authorized modification of the existing draft has been saved, reloaded, and the before/after diff verification passed.
  • draft_created:draft/add has returned media_id; the article is still in the official account draft box.
  • draft_enriching: saving and reading back, through the logged-in editor's web private API, the originality declaration not covered by the public OpenAPI, or filling in other explicit fields.
  • draft_ready: the draft has been saved and reloaded, and the originality declaration, recommendation, final cover, and other user-specified fields have all been read back.
  • publish_submitted:freepublish/submit has returned publish_id; the task has just been accepted.
  • publishing:freepublish/get returns status 1, status 0 but no article identifier yet, or the task is still in progress when the waiting window ends.
  • published: the status query returns 0, and article_id or the article URL is read back.
  • publish_failed: the status query returns 2, 3, 4, 5, or 6; retain the status code, failed article number, and official details.

For the complete receipt fields, see references/result-contract.md。

Workflow

1. Identify user intent

  • "Sync, import, save to draft box, generate draft" stops at draft_created。
  • "Official release, public release, publish immediately" continues to submit and poll until a terminal state.
  • When the user only provides publish_id , query the status directly without rebuilding the draft.
  • When the user requests to read or modify the currently existing article, use this Skill's existing-draft flow; do not rebuild the article package, and do not create a duplicate draft.
  • When creating a new draft, first read the brand Profile, write the permanent endcap and the currently active campaign into the canonical Markdown; then call lov-wechat-branding-cover-composition to generate the final cover and receipt, per the image Caption preparation contract call lov-image-decorator to process body images that need captions; finally call lovpen-cli to generate the WeChat copy-ready HTML, then return to this flow. Caption decoration applies only to images that explicitly need captions, and does not mechanically apply a uniform bottom bar to all images.

2. Read or locally edit an existing draft

Fully read existing draft operations and article state contract:

  1. Use media_id、appmsgid or the unique locator on the current edit page to locate the target, and read the before snapshot.
  2. The read task stops at draft_read, and must not perform a save just because of "checking it out".
  3. For a modification task, first declare the fields allowed to change and the fields that must remain unchanged, then perform the minimal modification.
  4. Save and reload the same draft, and record the after snapshot.
  5. Use scripts/verify_article_state.py to verify the differences; only after it passes, report draft_saved。

If an existing draft needs a full rewrite or branding, first have lov-article-creator generate a local prepared version, then return to this flow to perform an explicit replacement. Deleting, overwriting the entire article, or changing permissions still requires a precise target and explicit authorization.

3. Select the draft transport

Select in the following order; for the detailed contract see references/transport-routing.md:

  1. By default, use the LovStudio unified gateway: body images, covers, draft creation, draft readback, official release, and status queries are all handled by the backend calling WeChat.
  2. When originality needs to be declared, use the logged-in editor session to call mp.weixin.qq.com/cgi-bin/operate_appmsg; when visible formatting is needed or other fields need to be handled, use the logged-in browser.
  3. Use OneShot direct connection or other direct transports only when explicitly diagnosing the legacy path; do not use it as the default publishing path.

The AppSecret and gateway API Key must be resolved by the locator of lov-env-management . Do not copy the keys into the article directory, command parameters, environment files, logs, screenshots, or receipts.

4. Create and verify the draft

Unified gateway path:

  1. First check the content handoff of the canonical Markdown: the research-review method chain is complete, the first body block is an independent 4:3 horizontal lead image, H2/H3 are stable and there is no hardcoded presentation-oriented TOC; then use --brand-profile to check the permanent endcap, the personal card, and campaigns that are still open and not full. If any item is missing, duplicated, or misplaced, fail closed before writing to the remote end.
  2. Check the Caption preparation results: all selected images have lov-image-decorator receipts, the article references the derived files, unselected images have not been rewritten, and the Caption does not duplicate adjacent body text or captions.
  3. Use preflight_article.py --transport gateway to check the title, body, Lovpen WeChat copy-ready HTML, brand cover composition receipt, images, and extension fields.
  4. Use publish_via_gateway.py to pass in the AppID, brand Profile, and two managed key locators; do not pass key plaintext.
  5. The script uploads the body images one by one via material/uploadimg , then calls draft/add。
  6. The script checks 20,000 characters of the rendered visible body and 1,000,000 bytes as UTF-8 HTML; the raw HTML character count must not be treated as the 20,000-character limit.
  7. The script immediately calls draft/getto verify the remote title, image count, cover assets, and body length. On the Lovpen path, it must also compare the remote body node by node: WeChat removing the external-link <a> wrapper and the position attribute is allowed, but the remaining tag order, class, CSS properties, and visible text must be preserved.
  8. Only after read-back passes is mediaIdrecorded, with the status written as draft_created。

First render via the real WeChat copy chain of lovpen-cli :

python3 <lovpen-skill-dir>/scripts/run_lovpen_cli.py \
  --project-root LOVPEN_PROJECT_ROOT \
  -- --json render ARTICLE.md \
  --output ARTICLE.lovpen.wechat.html \
  --format wechat \
  --template-kit typora-newsprint

Only when the JSON receipt shows renderer_mode=wechat-browser-copy、clipboard_source pointing to extractWechatClipboardHTML, and the artifact root node is section.lovpen-rendererwith body styles inlined, is it handed to the publishing script. The Shadow DOM of native mp-common-videosnap may retain component isolation <style>; elsewhere in the article body, <style>:

python3 <skill-dir>/scripts/publish_via_gateway.py ARTICLE.md \
  --lovpen-wechat-html ARTICLE.lovpen.wechat.html \
  --app-id APP_ID \
  --wechat-secret-locator WECHAT_SECRET_LOCATOR \
  --gateway-key-locator GATEWAY_KEY_LOCATOR \
  --brand-profile BRAND_PROFILE \
  --cover COVER_DIR/share-cover-wide-logo.jpg \
  --cover-composition-receipt COVER_DIR/cover-composition.json

The script does not parse and rebuild the body, nor does it strip class、style、span or tables; it only replaces the local JPG/PNG src in the raw HTML string with upload placeholders, then replaces those with WeChat HTTPS addresses. Before and after upload, it must verify that inline styles, classes, spans, tables, and img counts are exactly the same, and compare the full-text SHA-256 after ignoring the image src .--lovpen-html is kept as a compatibility alias, but the input contract likewise only accepts --format wechat artifacts.--allow-compact-markdown and --allow-unverified-cover are only used to explicitly diagnose the legacy chain and must not be used for normal delivery. The receipt also records the Lovpen artifact and the branded cover composition evidence.

When a long article has multiple stable H2s or H2/H3s, manually read back the Lovpen HTML before delivery: the table of contents sits between the lede and the first chapter, includes a restrained estimated reading time, and its entries match the final chapters with no second Markdown table of contents; small-print notes appear in place in the corresponding body text, with multiple items on separate lines. The font size, color, and spacing of the table of contents and the notes must not overpower the body text.

A browser or explicit direct transport must also return the remote media_id or provide draft-box reload evidence. A single button click, progress completion, or local HTML generation is not evidence of a remote draft.

5. Fill in and read back the editor fields

When a task requires an originality declaration or other fields not currently supported by the public OpenAPI,draft_created is not a deliverable end state.digest is the summary/recommendation field that the public draft API can write and that can be read back in the backend; do not rewrite the already-verified digest。

  1. Use this Skill's existing-draft internal flow, open the draft corresponding to the just-created media_id and obtain the editor page appmsgid. Before writing, record the title, recommendation, originality status, cover, and other visible toggles; unspecified fields go into the keep-unchanged set.
  2. Do not stuff undisclosed fields such as api.weixin.qq.com/cgi-bin/draft/add or draft/update into copyright_type、original_article_type ; the API may return success but silently discard them.
  3. When the user has explicitly confirmed the content rights, call the web private API script. In the logged-in page context, the script reads the body and cover, writes numbered fields to operate_appmsg , and does not write cookies or tokens into parameters, logs, or receipts:
python3 <skill-dir>/scripts/enrich_via_wechat_web_api.py \
  --appmsg-id APPMSG_ID \
  --title "TITLE" \
  --author "AUTHOR" \
  --digest "RECOMMENDATION" \
  --source-url "SOURCE_URL" \
  --original-category "艺术文化" \
  --confirm-original-rights \
  --receipt RECEIPT.json
  1. --confirm-original-rights It is a required rights declaration gate; you must not guess on the user's behalf. Private interfaces carry no stability commitment; when the page structure or fields drift, stop immediately and do not degrade to "request succeeded means done".
  2. After saving, re-fetch the same edit page and you must observe copyright_type=1 with the requested original_article_type; at the same time, read back the recommendation text, cover asset, and non-target fields.
  3. Only after everything matches, record draft_ready。ret=0 but when the original status is unobservable, keep draft_enriching, and verificationPending=true。

For the detailed hybrid path, see references/editor-enrichment.md。

6. Formally publish an existing draft

When the user has explicitly requested public publication, use the just-verified media_id. If the task requires editor fields, you must first reach draft_ready:

python3 <skill-dir>/scripts/publish_existing_draft.py submit \
  --media-id MEDIA_ID \
  --app-id APP_ID \
  --wechat-secret-locator WECHAT_SECRET_LOCATOR \
  --gateway-key-locator GATEWAY_KEY_LOCATOR \
  --wait-seconds 300 \
  --receipt RECEIPT.json

Scripts are executed through the unified gateway by default, and both keys are parsed from lov-env-management .--transport direct It is retained for diagnostics only; scripts do not output AppSecret, gateway Key, or access token.

If it is still publishing after waiting ends, keep publish_id, then query:

python3 <skill-dir>/scripts/publish_existing_draft.py status \
  --publish-id PUBLISH_ID \
  --app-id APP_ID \
  --wechat-secret-locator WECHAT_SECRET_LOCATOR \
  --gateway-key-locator GATEWAY_KEY_LOCATOR \
  --receipt RECEIPT.json

If the transport already has its own verified formal publication and status readback, you may reuse its implementation, but still report according to this Skill's status and receipt contract.

7. Handle recoverable errors

  • 40164: In the default path, only check whether the backend's fixed egress is still on the official account whitelist; adding the local IP is not required. Record the backend deployment and WeChat return details, then fix the gateway configuration.
  • 40013: Recheck the AppID starting with wx .
  • 40001 / 40125: Re-obtain or reset the AppSecret.
  • 48001: Check the account verification status and draft/publish interface permissions.
  • Body images filtered: save the images as local JPG/PNG, rewrite the URLs via media/uploadimg , then rebuild the draft.
  • Draft creation fails midway: check whether permanent assets have already been uploaded; before retrying, avoid piling up cover assets repeatedly without basis.

Error replies must retain the stage, error code, interface details, request ID, time, and shortest recovery action, and provide copyable content.

Pre-completion checks

  1. Precheck has no errors; the title, Lovpen WeChat copy-state HTML, brand cover composition receipt, and body come from this input.
  2. The target official account has been verified, and the AppSecret has not entered project files or output.
  3. The transport selected for body images can truly upload and rewrite URLs.
  4. media_id is reported only as a remote draft;publish_id is reported only as a submitted task.
  5. Only when the freepublish/get status is 0 and the article identifier is read back, report public publication as complete.
  6. The receipt includes the input summary, actions, remote identifiers, status, time, and copyable error details.
  7. The Lovpen path also records the pre-submission lovpenFidelityVerified=true and the remote remoteFidelityVerified=true; the latter must list the tags/attributes actually cleaned by WeChat, and prove that the remaining tags, class, CSS, and text are unchanged. Standalone HTML is explicitly rejected rather than silently downgraded.
  8. The share cover of the branded article is read back as the final composite with publication.logo ; the first block of the body is an independent 4:3 horizontal lead image, which is not the same file as the share cover, and the platform title is not written again in the body.
  9. The methods, actual prompts, metrics, scoring rules, scoring examples, reproduction methods, and limitations of research evaluation articles have passed precheck in the canonical Markdown; the publisher did not package content issues as layout issues or mask them with remote success.
  10. When an originality statement is required, the receipt transport is wechat-web-private-api、originalVerified=true、editorFieldsVerified=true, and the read-back after saving and reloading has been stored for copyright_type=1 and the target category; obtaining only operate_appmsg ret=0 does not count as complete. Recommendation text, cover image, and other specified fields must likewise be read back consistently, and unspecified settings remain at platform defaults.
  11. All body images that require a reader-visible Caption have had derived files generated by lov-image-decorator and receipts read back; Captions only serve the tasks of evidence explanation, necessary attribution, or interpretation, do not repeat alt text, body text, or internal production notes, and do not imply unauthorized brand endorsement.
  12. publicationComponentsVerified=true; the permanent brand footer and personal card have appeared, currently open, not full, and not expired campaigns are located before them, and full or ended campaigns have not been mistakenly included.
  13. lovpenEditorialRenderingVerified=true; the long-form table of contents is generated by the final HTML based on H2/H3 and is located before the first chapter , and the canonical Markdown has no duplicate TOC; small-print materials are in place, low-key, with multiple items on separate lines, and are not piled up at the end of the document.

Official endpoints, field limits, and status codes are in references/official-api.md。

References