Notion to Weixin
Config (Optional)
Set a default author in ~/.agents/config.yaml:
notion_to_weixin:
author: "Alice Wang"
You can also set a global default:
author: "Alice Wang"
Workflow (Sequential)
- Resolve Notion page ID from the given title.
- Export the page to Markdown.
- Ensure
authorexists in Markdown front matter (and inject a byline if needed). - Process images (upload to Weixin and replace URLs in Markdown).
- Prepare
thumb_media_id:- If the Notion page has a cover, upload it as a Weixin
thumbmaterial and use that ID. - If no cover, use the last image material ID.
- If the Notion page has a cover, upload it as a Weixin
- Generate
digestwith AI summarization (if user did not provide one). - Create a new Weixin draft using Markdown input (
--format markdown) and always pass--css-path.
Inputs (Ask the user if missing)
notion_title: exact Notion page title to publish.author: optional author name (used for Markdown front matter and node-wxcli--author). If missing, read from~/.agents/config.yaml.css_path: required when using--format markdown; if missing, default toassets/default.css.thumb_media_id: only required if cover and image fallback both fail.digest: optional user-provided summary; if missing, generate via AI from the final Markdown.
Prerequisites
notion-cliinstalled and authenticated (NOTION_TOKEN ornotion auth set).node-wxcliinstalled and authenticated (node-wxcli auth setornode-wxcli auth login).curlandjqavailable.
Step 1: Resolve Page ID by Title
- Copy
references/notion-search.jsonto a temp file and replace__TITLE__. - Run
notion search --body @query.json. - Choose the exact-title match. If multiple matches remain, pick the most recently edited or ask the user to confirm.
- If no match is found, ask for a Notion page ID or URL and extract the ID.
Step 2: Export Page to Markdown
- Use
notion pages export <page_id> --assets=download -o <workdir>/page.mdwhen the page contains images. - Use a workdir like
/tmp/notion-to-weixin/<slug-or-timestamp>.
Step 3: Default Author Handling
- If
authoris not provided, read it from~/.agents/config.yaml. - Ensure
authorexists in Markdown front matter (and add a byline if you want it visible in content).
Step 4: Process Images (Recommended)
If the Notion page contains images, upload them to Weixin and replace Markdown image URLs so they remain valid for draft rendering.
- Find image links in
<workdir>/page.md. Notion exports local images under the assets folder. - For each local image file, upload it and capture the
url:
node-wxcli material upload --type image --file <workdir>/assets/<image-file> --json | jq -r '.url'
- Replace the Markdown image URL with the returned
url:

If you skip this step, images that reference local files or expiring Notion URLs may not render in Weixin.
Step 5: Prepare thumb_media_id
5.1 If Notion page has a cover
- Fetch page metadata (use notion-cli):
notion pages get <page_id> > <workdir>/page.json
- Extract cover type + cover URL:
cover_type=$(jq -r '.cover.type // ""' <workdir>/page.json)
cover_url=$(jq -r '.cover | if .==null then "" elif .type=="external" then .external.url else .file.url end' <workdir>/page.json)
- If cover type is
file, download via notion-cli; ifexternal, use curl:
if [ "$cover_type" = "file" ]; then
jq -c '.cover' <workdir>/page.json | notion files read --body @- --output <workdir>/cover.jpg
else
curl -L "$cover_url" -o <workdir>/cover.jpg
fi
thumb_media_id=$(node-wxcli material upload --type thumb --file <workdir>/cover.jpg --json | jq -r '.media_id')
Note: Notion file URLs expire quickly. If download fails, re-fetch page metadata and retry.
5.2 If no cover exists
- Get image material count:
image_count=$(node-wxcli material count --json | jq -r '.image_count')
- If
image_count > 0, fetch the last image and use itsmedia_id:
offset=$((image_count - 1))
thumb_media_id=$(node-wxcli material list --type image --offset "$offset" --count 1 --json | jq -r '.item[0].media_id')
- If no images exist, ask the user to provide a
thumb_media_idor upload a thumb manually.
Step 6: Build digest with AI summarization
If digest is not provided, summarize the final Markdown content with AI and generate a concise Chinese digest:
- 1-2 sentences
- Prefer 60-120 Chinese characters
- Plain text only (no Markdown / emoji / line breaks)
- Focus on the article purpose and key outcomes
Step 7: Create Weixin Draft (Markdown input)
When using Markdown format, always pass --css-path. If css_path is missing, set:
css_path=${css_path:-assets/default.css}
node-wxcli draft add \
--title "<notion_title>" \
--author "<author>" \
--digest "<digest>" \
--format markdown \
--content - \
--css-path <css_path> \
--need-open-comment=1 \
--only-fans-can-comment=0 \
--thumb-media-id "$thumb_media_id" < <workdir>/page.md
- If you need machine-readable output, add
--jsonand capture the returnedmedia_id.
Resources
references/notion-search.json: JSON template for Notion title search.references/cli-commands.md: Canonical CLI command examples fornotion-cliandnode-wxcli.assets/default.css: Default CSS theme for--format markdown(--css-path).
Notes:
- Use
--page-idif the title search is ambiguous. - Use
--thumb-media-idonly if cover and image fallback are unavailable.