substack

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

substack — read & publish on Substack via your own cookies

substack — 通过自有Cookie在Substack上读写内容

Drives the user's real Substack account through the same internal web API the site uses (Substack has no official public write API), authenticated by the login cookie they captured with the ACE extension. No browser, no third-party deps — just
urllib
. The publish flow mirrors the community
python-substack
library: create draft → prepublish → publish.
The connector injects the cookie jar as an env var:
  • SUBSTACK_COOKIES
    — a JSON array of cookies (
    substack.sid
    ,
    substack.lli
    , …). Secret — never echo or print it. Substack authenticates writes with the session cookie alone (no CSRF token header needed).
通过Substack官网使用的内部Web API操作用户的真实Substack账户(Substack暂无官方公开写入API),通过用户使用ACE扩展捕获的登录Cookie进行身份验证。无需浏览器,无第三方依赖——仅使用
urllib
。发布流程复刻了社区
python-substack
库的逻辑:创建草稿 → 预发布 → 发布
连接器将Cookie Jar作为环境变量注入:
  • SUBSTACK_COOKIES
    — Cookie的JSON数组(
    substack.sid
    substack.lli
    等)。保密信息——绝不要回显或打印它。Substack仅通过会话Cookie验证写入操作(无需CSRF令牌头)。

CLI

CLI

The skill ships
scripts/substack.py
— self-contained, stdlib only.
sh
SUB=$SKILL_DIR/scripts/substack.py
python3 $SUB whoami                       # who is logged in + primary publication
python3 $SUB articles --limit 20          # my published posts + stats
本技能附带了
scripts/substack.py
——独立脚本,仅依赖标准库。
sh
SUB=$SKILL_DIR/scripts/substack.py
python3 $SUB whoami                       # 查看登录用户信息 + 主出版物
python3 $SUB articles --limit 20          # 查看我的已发布帖子 + 统计数据

Verify the connection first

先验证连接

sh
python3 $SUB whoami
sh
python3 $SUB whoami

→ {"user_id": ..., "name": "...", "handle": "...", "publication": "...", "publication_url": "https://<sub>.substack.com"}

→ {"user_id": ..., "name": "...", "handle": "...", "publication": "...", "publication_url": "https://<sub>.substack.com"}


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 Substack's ProseMirror blocks:
#
..
######
→heading,
```
→code block,
>
→blockquote,
-
/
*
/
1.
→lists,
---
→horizontal rule, everything else →paragraphs. Inline bold, italic,
code
, strike, and
[links](url)
render as real Substack formatting; bare
https://…
URLs are auto-linked.
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
undefined
publish
会写入用户的真实账户。内容采用Markdown格式,会转换为Substack的ProseMirror块:
#
..
######
→标题,
```
→代码块,
>
→块引用,
-
/
*
/
1.
→列表,
---
→水平线,其余内容→段落。行内的粗体斜体
代码
删除线
[链接](url)
会渲染为Substack原生格式;纯文本
https://…
链接会自动转换为可点击链接。
如果末尾没有
--confirm
,则仅为试运行。
--confirm
仅在作为最后一个参数时生效。始终先展示试运行结果,获取用户明确的“确认”后,再重新运行命令。
sh
undefined

dry-run (shows the plan, writes nothing)

试运行(展示计划,不写入任何内容)

python3 $SUB publish --title "Title" --content-file post.md
python3 $SUB publish --title "Title" --content-file post.md

private draft (visible only in the user's dashboard)

私有草稿(仅用户仪表盘可见)

python3 $SUB publish --title "Title" --content-file post.md --draft-only --confirm
python3 $SUB publish --title "Title" --content-file post.md --draft-only --confirm

go LIVE on the web (does NOT email subscribers)

发布至公开网页(不会向订阅者发送邮件)

python3 $SUB publish --title "Title" --content-file post.md --confirm
python3 $SUB publish --title "Title" --content-file post.md --confirm

go LIVE and email subscribers (use only when the user explicitly asks)

发布至公开网页并向订阅者发送邮件(仅当用户明确要求时使用)

python3 $SUB publish --title "Title" --content-file post.md --send-email --confirm

- `--draft-only` stops at a draft — **default to this** unless the user asked to
  go live. Returns an `edit_url` to review in the Substack editor.
- Publishing **does NOT email subscribers** unless `--send-email` is passed.
  Emailing a newsletter is irreversible and hits every subscriber's inbox —
  never add `--send-email` without an explicit request.
- `--subtitle` sets the post subtitle; `--audience` is one of
  `everyone` (default, free/public), `only_paid`, `founding`, `only_free`.
python3 $SUB publish --title "Title" --content-file post.md --send-email --confirm

- `--draft-only`会停留在草稿阶段——**默认使用此选项**,除非用户要求发布至公开网页。返回`edit_url`可在Substack编辑器中查看草稿。
- 发布操作**不会向订阅者发送邮件**,除非传入`--send-email`参数。发送通讯是不可逆的操作,会发送到所有订阅者的收件箱——未经用户明确请求,绝不要添加`--send-email`参数。
- `--subtitle`用于设置帖子副标题;`--audience`可选值为`everyone`(默认,免费/公开)、`only_paid`、`founding`、`only_free`。

Gotchas

注意事项

  • This is the user's real Substack account. Confirm before any publish, and keep
    --draft-only
    as the safe default.
  • --send-email
    blasts the whole subscriber list
    and cannot be undone — opt in only on explicit request.
  • Substack sits behind Cloudflare; an occasional 403/429 on a read is transient — the CLI auto-retries reads once. A persistent 401/403 means the cookie is genuinely expired (reconnect); the CLI never retries a write.
  • Never print
    SUBSTACK_COOKIES
    — it is full account access.
  • ToS: acts only on the user's own account with their own captured cookie.
  • 这是用户的真实Substack账户。在执行任何发布操作前请确认,并且将
    --draft-only
    作为安全默认选项。
  • --send-email
    会向所有订阅者发送邮件
    ,且无法撤销——仅在用户明确请求时使用。
  • Substack部署在Cloudflare之后;偶尔出现的403/429读取错误是暂时的——CLI会自动重试一次读取操作。如果持续出现401/403错误,说明Cookie确实已过期(需重新连接);CLI绝不会重试写入操作。
  • 绝不要打印
    SUBSTACK_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="substack", 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="substack", title="<title>", url="<the REAL returned URL>", status="delivered")
使用真实返回的URL——绝不要伪造。每个发布项目仅调用一次,且仅在确认交付成功后调用;如果发布失败,请跳过调用(或使用
status="failed"
)。详情请见
_shared/artifacts.md