Trigger conditions
User says:
- Export all my WeRead highlight notes
- Export reading notes
- Save my highlights as a file
- Back up WeRead notes
- export weread notes
Prerequisites
- Installed
weread-skills(in the same directory) - Environment variable
WEREAD_API_KEYconfigured
Workflow
Step 1: Ask for format, scope, and save location (must ask every time, cannot be skipped)
Regardless of whether these details are mentioned in the trigger phrase, you must finish asking all three questions before starting each execution. Even if the user says "export everything as PDF", restate and confirm it.
Ask all three questions at once:
请确认导出参数:
1. 输出格式?
a. Markdown(.md)
b. PDF(.pdf)
c. 两个都要
2. 导出范围?
a. 全部书籍
b. 指定书籍(请告诉我书名或 bookId)
3. 保存到哪个目录?
- 直接回车 = 当前工作目录
- 或者输入一个绝对路径 / 相对路径(如 ~/Documents/微信读书)
After receiving the user's reply, proceed to Step 2. If the reply is unclear (for example, only the format was answered but not the scope), ask again about the missing item; do not assume a default.
Save path handling:
- If the user gives an absolute path: use it as-is
- If the user gives a relative path: expand it relative to the current working directory
- If the user just presses Enter: use the current working directory
- If the path does not exist: automatically
mkdir -pcreate it, without asking again
Step 2: Fetch the notebook overview
Call /user/notebooks to paginate through all books with notes:
{"api_name":"/user/notebooks","count":50,"skill_version":"1.0.3"}
hasMore=1 when, use the last item's sort as lastSort to continue fetching.Parameters must be flattened at the top level of the body, not wrapped in params li。
Summary:
totalBookCount: number of books- Accumulate each book's
noteCount + reviewCountas the total note count
Step 2.5: Handling when a specified book is not on the shelf
If the user selected "specified book" in Step 1, but that book is not in /user/notebooks 's returned results(meaning the user has no personal highlights/notes), you must first ask the user:
你的书架上没有《xxx》的个人笔记。
要改为导出这本书的【热门划线】(其他读者的高频划线)吗?
a. 是,导出热门划线
b. 否,取消导出
If the user chooses a:
- Call
/store/searchto get the bookId (if the user provided a book title) - Call
/book/chapterinfoto get the chapter list - Call
/book/bestbookmarks(bookId, chapterUid=0) to get the book's Top 20 popular highlights - Mark at the top of the Markdown "Popular highlights export (not personal notes)", and below each highlight show the number of highlighters (
totalCountfield, format🔥 N 人划线), without showing time
Step 3: Fetch highlights and thoughts book by book
For each book, call two APIs in parallel:
{"api_name":"/book/bookmarklist","bookId":"<bookId>","skill_version":"1.0.3"}
{"api_name":"/review/list/mine","bookid":"<bookId>","count":100,"skill_version":"1.0.3"}
Note:/review/list/mine 's field name is bookid(all lowercase), not bookId。
Step 4: Assemble Markdown
Generate according to the template below. Save the file to the directory specified by the user in Step 1, with the filename fixed as 微信读书划线-YYYY-MM-DD.md。
Markdown template
# 微信读书划线笔记
> **导出时间**:YYYY-MM-DD HH:MM
> **共 N 本书 · X 条划线 · Y 条想法**
---
## 目录
1. [书名 A](#1-书名-a) · 12 划线
2. [书名 B](#2-书名-b) · 5 划线 / 2 想法
---
## 1. 书名 A
**作者**:xxx
**最近笔记**:YYYY-MM-DD
**统计**:12 划线 / 0 想法 / 进度 45%
### 第三章 章节名
> 划线原文……
📅 2025-09-21
> 第二条划线……
📅 2025-09-22
💭 我对这条的想法(如果有 review 关联到这条划线)
---
## 2. 书名 B
……
Formatting points:
- Use
##for book titles,### - for chapters, and
>for highlight body text - Time format
YYYY-MM-DD(without hours, minutes, seconds) - Thoughts are placed below the highlight with the
💭prefix - Whole-book reviews (in reviews,
chapterNameis empty) are placed separately at the end of that book in the "## Whole-Book Reviews" section - Separate each book with
---separator - The top "Total N books · X highlights · Y thoughts" is in bold
Sorting rules (mandatory):
- Chapter order: strictly in ascending order by
chapters[].chapterIdx; get the chapter order from the/book/bookmarklistor/book/bestbookmarksresponse'schaptersarray,do not sort by note creation time - Highlight order within a chapter: ascending by
rangestart position (the number before therangefield-, converted to int), ensuring the order in which highlights appear in the text - Cross-chapter thoughts/reviews:
chapterNameWhole-book reviews that are empty are placed separately at the end of that book - Unmatched chapters: highlights whose corresponding
chapterscannot be found inchapterUidare grouped at the end of that book in the "### Uncategorized" section - Sorting is completed before generating Markdown; out-of-order output at the output stage is prohibited
Step 5: If PDF is needed, convert
If the user wants PDF, run the following on the generated MD:
python3 ~/.claude/skills/read-weread-export/scripts/md_to_pdf.py <md路径> <pdf路径>
The script depends on Chrome (built into macOS or already installed). On failure, fall back to Markdown and notify the user.
Step 6: Report the result
Output:
- File path (clickable to open)
- Statistics: N books / X highlights / Y thoughts
- If the export takes a long time, show progress
Notes
- Do not request repeatedly: if
/user/notebookshas already been called in the same conversation turn, reuse the result directly - Large number of notes: when there are more than 30 books, call the interface in parallel batches (5 books per batch) to avoid request pileup
- Empty data: when a book's
bookmarklistis empty (only bookmarks, no highlights), mark it in the export as "(bookmarks only, no exportable highlights)" - Timestamp conversion: convert all
createTimeto YYYY-MM-DD format (user time zone is local) - Associating thoughts with highlights:
/review/list/mineIf the review returned byrangefield and matches a highlight's range, attach it below that highlight; otherwise place it at the end of the chapter or the end of the book - Chapter titles: map from the
bookmarklistresponse'schaptersarray bychapterUid; unmatched chapters go to "## Uncategorized" - Filename safety: in the book title,
/、:and other characters are replaced with-