用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/publieople/hermes-config-kit --skill notionnext-blog命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Manage AstrBot knowledge bases — create, upload, retrieve, delete via WebUI or REST API. Use when adding documents to an AstrBot bot's RAG knowledge base, troubleshooting embedding issues, or automating KB updates.
Integrate Hermes Agent with external desktop applications, IDEs, and AI tools — mapping their integration interfaces (custom API endpoints, MCP support, terminal hooks) to Hermes' built-in capabilities (API Server, MCP Server Mode, CLI spawning). Use when asked to "connect Hermes to X" or "make Hermes work with Y" for any third-party app.
国内量化交易系统搭建 — 行情终端 vs 量化系统辨析、券商通道瓶颈、开源框架选型、老式行情软件逆向分析
基于 SOC 职业分类
正在显示 SKILL.md
| name | notionnext-blog |
| description | 发布文章到 Publieople's Blog(NotionNext 驱动的博客)——搜索数据库、理解 schema、创建文章、验证上线。 |
| category | productivity |
references/notion-blocks.md — 完整 block 构造模板(高级 block、表格、媒体、错误码、限流)references/fork-sync-and-vercel.md — fork ↔ upstream 同步失败 + Vercel build/deploy 失败排查模式(含你 fork 这次恢复的实战参考)Notion API key 在 ~/.config/notion/api_key,格式 ntn_...。
02e0b2a07b164c37abb9cfc3db88c605097e5f674880459d8e1b4407758dc4fb(blog.config.js)| 属性 | 类型 | 可选值 |
|---|---|---|
title | title | — |
status | select | Published, Invisible, Draft |
type | select | Post, Page, Notice, Menu, SubMenu, Config |
category | select | 技术分享, 心情随笔, 差生文具多, 知识分享, 资源整理, 项目经历, 折腾记录, 活动体验 |
slug | rich_text | URL 路径(如 tiez-webdav-debugging) |
tags | multi_select | 自由标签 |
summary | rich_text | 文章摘要(用于 meta description) |
date | date | 发布日期 |
password | rich_text | 文章密码(可选) |
icon | rich_text | 自定义图标 URL(可选) |
import subprocess
key = subprocess.run(["cat", "/home/po/.config/notion/api_key"], capture_output=True, text=True).stdout.strip()
不要用 shell curl——API key 在终端中会被掩码为 *** 导致 auth 失败。
import json, urllib.request
DB = "02e0b2a07b164c37abb9cfc3db88c605"
markdown = """# 文章标题
文章内容(Notion-flavored Markdown)。
"""
payload = {
"parent": {"database_id": DB},
"properties": {
"title": {"title": [{"text": {"content": "文章标题"}}]},
"type": {"select": {"name": "Post"}},
"status": {"select": {"name": "Published"}},
"category": {"select": {"name": "折腾记录"}},
"date": {"date": {"start": "2026-06-08"}},
"slug": {"rich_text": [{"text": {"content": "url-slug"}}]},
"tags": {"multi_select": [{"name": "Tag1"}, {"name": "Tag2"}]},
"summary": {"rich_text": [{"text": {"content": "文章摘要"}}]}
},
"markdown": markdown
}
req = urllib.request.Request(
"https://api.notion.com/v1/pages",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {key}",
: ,
:
},
method=
)
urllib.request.urlopen(req) resp:
result = json.loads(resp.read())
page_id = result[]
()
NotionNext 默认 revalidate 60 秒。验证:
curl -sI "https://blog.for-people.cn/article/{slug}" | grep HTTP
# HTTP/2 200 → 上线成功
来自用户资料:
<callout> 把结论放在开头<callout>、<details>、代码块等 Notion-flavored MarkdownNotionNext 渲染按 DB 顺序,所以"补充某章节内容"必须插在指定 block 后面,不能 append 到页尾。
API 支持 position 参数,放到 body 顶层(不是 children 里):
# 找到目标 H2 的 block id,作为 anchor
H2_ID = "5a066ad7-c9c4-8304-aaff-81441e0e7744" # 例:「版本控制」H2
payload = {
"children": [/* 任意数量的 block,单次上限 100 */],
"position": {"type": "after_block", "after_block": {"id": H2_ID}}
}
req = urllib.request.Request(
f"https://api.notion.com/v1/blocks/{PAGE_ID}/children",
data=json.dumps(payload).encode(),
headers={"Authorization": f"Bearer {key}", "Notion-Version": "2022-06-28", "Content-Type": "application/json"},
method="PATCH", # 注意是 PATCH 不是 POST
)
插入位置失败会报 400,但错误信息不告诉你具体哪个 block 错了。先用一个标记 callout 验证位置语义,再批量:
📌 [probe] 探针 → fetch 页面 block 列表,确认探针确实出现在目标 H2 之后/v1/blocks/{probe_id})跳过这一步直接批量 = 大概率插错位置,删起来很烦。
numbered_list_item / bulleted_list_item 算 1 个 leaf,但有的端点会算成多个 children)Ponytail: 5 个 helper 覆盖 90% 场景,不要造更复杂的。
def p(text): return {"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content":text}}]}}
def h2(text): return {"object":"block","type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":text}}]}}
def h3(text): return {"object":"block","type":"heading_3","heading_3":{"rich_text":[{"type":"text","text":{"content":text}}]}}
def bullet(text): return {"object":"block","type":"bulleted_list_item","bulleted_list_item":{"rich_text":[{"type":"text","text":{:text}}]}}
(): {:,:,:{:[{:,:{:text}}]}}
(): {:,:,:{:[{:,:{:text}}],:lang}}
(): {:,:,:{:{:,:emoji},:[{:,:{:text}}]}}
(): {:,:,:{}}
完整 list / 表格 / toggle / image / bookmark 等高级 block 见 references/notion-blocks.md。
language 字段是枚举,传错立刻 400 Bad Request 且错误信息不指出字段名。 常用值:
plain text / bash / shell / powershell / python / javascript / typescript / json / yaml / html / css / markdown / sql / go / rust / java / c / c++ / c# / ruby / php / mermaid ...
没有 "text" 这个值 —— 纯文本框图用 "plain text"。
req = urllib.request.Request(
f"https://api.notion.com/v1/blocks/{block_id}",
headers={"Authorization": f"Bearer {key}", "Notion-Version": "2022-06-28"},
method="DELETE",
)
返回 200 即成功。Notion API 不支持"移动 block",只能 delete + re-append。
comment is not a property that exists数据库中属性名是 comment (尾部有空格),但 API 要求精确匹配。忽略此属性即可,不影响发布。
unauthorized)终端 curl 命令中 $NOTION_KEY 被系统掩码为 ***,导致 auth header 变成字面量 Bearer ***。必须用 Python 脚本读文件取 key。
Could not find database)两种可能:
... → Connections → 添加 Hermes发布文章之外的"博客不工作"问题主要走这两条路径。详细步骤见 references/fork-sync-and-vercel.md。
gh run list --workflow="Upstream Sync" 看最近 10 次结论。conclusion: failure 是信号。gh run view <id> --log-failed | grep -E "CONFLICT|fatal|error processing shallow" 读根因。tangly1024 → notionnext-org 或类似)→ 修 .github/workflows/sync.yaml 的 upstream_sync_repofatal: error processing shallow: 4 → aormsby sync action 的 shallow_since 找不到合并基线,等同分叉前兆gh workflow run "Upstream Sync" 验证一次,只看结论:success → 修好了;failure → log 看新的 reason。curl -sI https://blog.for-people.cn | head -3。200 + Vercel header → production 没事;只关心最近一次失败的 build。vercel login(device code)→ curl -H "Authorization: Bearer $TOKEN" "https://api.vercel.com/v6/deployments?projectId=$PRJ" 拉最近 15 次 list。errorCode: module_not_found 经常是 misnamed。真因要看 events:
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api.vercel.com/v1/deployments/$DID/events" \
| python3 -c "import sys, json; print('\n'.join(e.get('text','') for e in json.load(sys.stdin) if e.get('type')=='stderr'))"
processPostData schema 严格化:TypeError: t.block[l].value.content is not iterable → 某篇 Notion 文章数据不全。会在 yaml 看到多个 [article/<slug>] [resolvePostProps] processPostData failed。gh api .../deployments/$DID/statuses 拿到结论状态。用户有时会盲复制我前一条消息里的 gh 命令 — 在多阶段任务里这经常导致在不合理时机触发 workflow(例:关闭一个 fork main 的 PR 前就先 gh workflow run)。规则:在多阶段任务里,每个 gh 命令前都必须先句子明示"前提是 X 已完成,否则 Y",且要强调当前阶段没用上。例:别顺手说"你也可以试试 gh workflow run verify", — 如果用户真去跑了,就要在下一回合补救而不是解释。
如果 fork 跟 upstream 累积几百个 conflict / 几百个 add/add,直接 git merge upstream/main 会爆炸。最小侵入恢复:
git checkout --orphan reset-fork upstream/main — 工作树 = 上游 HEAD,父历史脱离 fork 完全分叉状态。origin/main(git show origin/main:<path>)拷回 fork-only 个性化文件(典型: blog.config.js、conf/*、public/css/custom.css、public/favicon.ico、.github/workflows/sync.yaml 里的 fork 特定改)。git commit -m "chore(rebase): reapply fork-specific overlays on <upstream version>"。PATCH /repos/{owner}/{repo} 把 default_branch 改成目标 branch(例如 reset-fork)DELETE /repos/{owner}/{repo}/git/refs/heads/<old-main>POST /repos/{owner}/{repo}/git/refs 重建 <new-main> 指到新 commitPATCH /repos/{owner}/{repo} 把 default_branch 改回 maingh workflow run "Upstream Sync" 验证 sync 健康。如果结论 "No new commits to sync. Finishing sync action gracefully." — 修复成功。yarn build 试图验证 Vercel — 让 Vercel 自己 webhook 触发;如果 fork main 出现"删了重建",Vercel 可能错过新 ref,手动 trigger 一次(选项见 references)或等下一个 push。Could not find database)两种可能:
... → Connections → 添加 Hermes