medium

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

medium — read & publish on Medium via your own cookies

medium — 通过自有Cookie在Medium上读写

Drives the user's real Medium account through the same internal web API the site uses (Medium retired its public write API in 2023), authenticated by the login cookie they captured with the ACE extension. No browser, no third-party deps — just
urllib
.
The connector injects the cookie jar as an env var:
  • MEDIUM_COOKIES
    — a JSON array of cookies (
    sid
    ,
    uid
    ,
    xsrf
    ). Secret — never echo or print it. The CLI echoes the
    xsrf
    cookie as the
    x-xsrf-token
    header on writes for you. If the captured jar has no
    xsrf
    cookie (common), the CLI mints one automatically before writing, so publishes no longer fail with "Missing xsrf token".
通过Medium官网使用的内部Web API操作用户的真实Medium账户(Medium已于2023年停用其公开写入API),通过用户使用ACE扩展捕获的登录Cookie进行身份验证。无需浏览器,无需第三方依赖——仅使用
urllib
该连接器将Cookie Jar作为环境变量注入:
  • MEDIUM_COOKIES
    — Cookie的JSON数组(
    sid
    uid
    xsrf
    )。保密内容——绝不要回显或打印。 CLI会在写入操作时自动将
    xsrf
    Cookie作为
    x-xsrf-token
    头回显。如果捕获的Jar中没有
    xsrf
    Cookie(常见情况),CLI会在写入前自动生成一个,因此发布操作不会再因“缺少xsrf令牌”而失败。

CLI

CLI

The skill ships
scripts/medium.py
— self-contained, stdlib only.
sh
MED=$SKILL_DIR/scripts/medium.py
python3 $MED whoami                       # who is logged in
python3 $MED articles --limit 20          # my posts + clap/response stats
python3 $MED article <post-id>            # one post's details
此技能附带了
scripts/medium.py
——独立脚本,仅依赖标准库。
sh
MED=$SKILL_DIR/scripts/medium.py
python3 $MED whoami                       # 查看当前登录用户
python3 $MED articles --limit 20          # 查看我的帖子及鼓掌/回复统计
python3 $MED article <post-id>            # 查看单个帖子的详细信息

Verify the connection first

先验证连接

sh
python3 $MED whoami
sh
python3 $MED whoami

→ {"user_id": "...", "name": "...", "username": "..."}

→ {"user_id": "...", "name": "...", "username": "..."}


On an auth error the cookie is expired — have the user reconnect at
<https://auth.acedata.cloud/user/connections>. Do **not** loop-retry.

如果出现身份验证错误,说明Cookie已过期——请用户重新连接至<https://auth.acedata.cloud/user/connections>。**不要循环重试。**

Publishing — GATED (dry-run unless trailing
--confirm
)

发布操作——受限制(除非末尾添加
--confirm
,否则为试运行)

publish
writes to the user's real account. Content is Markdown (converted to Medium paragraph blocks:
#
/
##
→heading,
###
→sub-heading,
>
→quote,
```
→code,
-
/
*
→bullet list,
1.
→numbered list, tables→aligned code block). Inline bold, italic,
code
, and
[links](url)
render as real Medium formatting (clickable links included). Bare
https://…
URLs in text are auto-linked too (URLs inside code spans are left untouched). Without a trailing
--confirm
it dry-runs.
--confirm
is honored only as the last argument. Always show the dry-run, get an explicit "yes", then re-run.
sh
python3 $MED publish --title "Title" --content-file a.md                       # dry-run
python3 $MED publish --title "Title" --content-file a.md --draft-only --confirm   # private draft
python3 $MED publish --title "Title" --content-file a.md --confirm                # PUBLIC story
Publishing is Medium's multi-step editor flow (new-story → write deltas → publish).
--draft-only
stops at the draft (visible only at the user's
/me/stories/drafts
). Default to
--draft-only
unless the user asked to go live.
publish
会写入用户的真实账户。内容采用Markdown格式(会转换为Medium段落块:
#
/
##
→标题,
###
→副标题,
>
→引用,
```
→代码块,
-
/
*
→项目符号列表,
1.
→编号列表,表格→对齐代码块)。行内的粗体斜体
代码
[链接](url)
会渲染为真实的Medium格式(包含可点击链接)。文本中的独立
https://…
URL会自动转换为链接(代码跨度内的URL保持不变)。如果末尾没有
--confirm
,则为试运行。
--confirm
仅在作为最后一个参数时生效。始终先展示试运行结果,获取用户明确的“是”后,再重新运行。
sh
python3 $MED publish --title "Title" --content-file a.md                       # 试运行
python3 $MED publish --title "Title" --content-file a.md --draft-only --confirm   # 发布为私有草稿
python3 $MED publish --title "Title" --content-file a.md --confirm                # 发布为公开故事
发布操作遵循Medium的多步骤编辑器流程(新建故事→写入增量内容→发布)。
--draft-only
会停留在草稿阶段(仅在用户的
/me/stories/drafts
页面可见)。除非用户要求公开发布,否则默认使用
--draft-only

Images

图片处理

publish
automatically uploads each external markdown image (
![](url)
) to Medium and inserts it as a real image block — Medium has no markdown-image syntax, so this is the only way images render. Pass
--no-rehost-images
to degrade images to link-only paragraphs. An image that fails to upload falls back to a link paragraph (never blocks the post).
publish
会自动将每个外部Markdown图片(
![](url)
)上传至Medium,并将其插入为真实的图片块——Medium没有Markdown图片语法,因此这是图片能正常渲染的唯一方式。传递
--no-rehost-images
参数可将图片降级为仅含链接的段落。上传失败的图片会回退为链接段落(绝不会阻止帖子发布)。

Gotchas

注意事项

  • This is the user's real Medium account. Confirm before any publish.
  • Markdown→Medium conversion covers headings, quotes, fenced code, bullet/ numbered lists, images, and inline markups (bold/italic/code/links). Medium's editor has no table element: a narrow markdown table renders as an aligned monospace code block, while a wide one (long cells / URLs, which would wrap into an unreadable grid) is rendered as per-row records — the first column bolded as a lead-in, the remaining columns as
    header: value
    bullets.
  • Medium sits behind Cloudflare; an occasional 403/429 is transient — the CLI auto-retries once after a short pause. A persistent 403 means the cookie is genuinely expired (reconnect).
  • Never print
    MEDIUM_COOKIES
    — it is full account access.
  • ToS: acts only on the user's own account with their own captured cookie.
  • 操作的是用户的真实Medium账户。 在任何发布操作前请确认。
  • Markdown转Medium格式支持标题、引用、围栏代码块、项目符号/编号列表、图片以及行内标记(粗体/斜体/代码/链接)。Medium编辑器没有表格元素:窄Markdown表格会渲染为对齐的等宽代码块,而宽表格(长单元格/URL,会换行成难以阅读的网格)会渲染为每行记录——第一列加粗作为引导,其余列显示为
    header: value
    项目符号。
  • Medium位于Cloudflare之后;偶尔出现的403/429错误是暂时的——CLI会在短暂暂停后自动重试一次。持续出现403错误意味着Cookie确实已过期(需重新连接)。
  • 绝不要打印
    MEDIUM_COOKIES
    ——它拥有账户的完全访问权限。
  • 服务条款:仅在用户自有账户上操作,使用用户自行捕获的Cookie。

Record the output

记录输出结果

After you successfully publish and obtain the live result URL, call the built-in
publish_artifact
tool ONCE so the user can track this deliverable in My Outputs:
publish_artifact(kind="article", channel="medium", title="<title>", url="<the REAL returned URL>", status="delivered")
Use the real returned URL — never fabricate one. Call it once per published item, only after delivery is confirmed; skip it (or use
status="failed"
) if publishing failed. See
_shared/artifacts.md
.
成功发布并获取到实时结果URL后,调用内置的
publish_artifact
工具一次,以便用户能在“我的输出”中跟踪此交付成果:
publish_artifact(kind="article", channel="medium", title="<title>", url="<the REAL returned URL>", status="delivered")
使用真实返回的URL——绝不要伪造。每个发布项仅调用一次,仅在确认交付成功后调用;如果发布失败,请跳过(或使用
status="failed"
)。详见
_shared/artifacts.md