Token导航 LogoToken导航TokenDH.com
研究检索敏感数据clawhub未标认证来源可访问clear审计通过

write-opennote写开放笔记

Agent Skill

write-opennote 用于查找、检索和筛选相关信息,适合在 OpenClaw 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

3,220

周安装

129

GitHub Stars

公开资料未说明

下载量

1,042
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:write-opennote(写开放笔记)
来源仓库:https://github.com/liam-duan/write-opennote
安装命令:
openclaw skills install write-opennote
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install write-opennote

简介

通过 OpenNote 公共 API 编写、更新与检索笔记,支持标签管理与图像上传。

  • 适用于知识管理工具集成,实现跨平台笔记同步与结构化信息整理。
  • 输出富文本格式笔记并支持全文搜索,便于快速定位历史内容与关联条目。
  • 需申请 API 访问令牌并遵守速率限制,注意笔记内容的加密存储与隐私保护。
  • 建议建立分类体系与命名规范,提升检索效率与使用体验一致性。

SKILL.md

name
write-opennote
description
Write, update, and read OpenNote notes through the public API. Use when the user wants to publish notes, upload note images, manage labels, or look up previously written notes.
metadata
openclaw
requires
env
bins
primaryEnv
OPENNOTE_API_TOKEN

Write Note via OpenNote Public API

Write a note to OpenNote using the public API at https://api.opennote.cc/api/v1.

Getting Started

What you need

  1. An OpenNote account — download the app from the App Store
  2. A Pro subscription — API access is a Pro feature
  3. A Personal Access Token (PAT) — generated from the app

Generating an API token

  1. Open the OpenNote app
  2. Go to ProfileAPI Tokens
  3. Tap Create Token
  4. Choose the scopes you need:

- diaries:write — create and update notes - images:write — upload images to notes

  1. Set an expiration (default: 90 days, max: 365 days, or never)
  2. Copy the token immediately — it starts with milo_pat_v1_ and is only shown once

Setting up the environment variable

Set OPENNOTE_API_TOKEN in your OpenClaw environment:

Option A — OpenClaw config (recommended):

In your OpenClaw settings, add the environment variable:

OPENNOTE_API_TOKEN=milo_pat_v1_your_token_here

Option B — Shell profile (if running locally):

export OPENNOTE_API_TOKEN="milo_pat_v1_your_token_here"

Add this to your ~/.zshrc or ~/.bashrc to persist it across sessions.

Security:

  • Never commit your token to version control
  • The token grants write access to your notes — treat it like a password
  • If compromised, revoke it immediately from ProfileAPI Tokens in the app

Token lifecycle

  • Tokens expire based on the duration you set (default 90 days)
  • You can have up to 5 active tokens per account
  • Revoke unused tokens from the app at any time
  • When a token expires or is revoked, generate a new one and update OPENNOTE_API_TOKEN
  • If you get a 401 INVALID_API_TOKEN error, your token has expired or been revoked

Prerequisites

The token is read from the OPENNOTE_API_TOKEN environment variable. It must have the diaries:write scope. If images will be uploaded, images:write is also required.

Local Cache Files

This skill maintains two local files in the working directory under .opennote/:

  • Labels cache: .opennote/opennote-labels-cache.json — cached user labels
  • Note history: .opennote/opennote-history.json — log of all notes written/edited via this skill

Always read these files at the start of every invocation. If they are missing, treat them as empty. If the user asks about previously written notes, consult the history file.

Instructions

Step 1: Load labels (fetch or use cache)

Read .opennote/opennote-labels-cache.json. If it exists and was fetched less than 24 hours ago, use the cached labels.

Expected cache format:

{
  "fetchedAt": 1741111111111,
  "labels": [
    { "categoryID": 1, "categoryName": "Personal", "categoryColor": 4294198070 },
    { "categoryID": 2, "categoryName": "Work", "categoryColor": 4283215696 }
  ]
}

If the cache is missing, empty, or stale (older than 24 hours), fetch labels from the API:

curl -s "https://api.opennote.cc/api/v1/labels" \
  -H "Authorization: Bearer $OPENNOTE_API_TOKEN"

Response:

{
  "labels": [
    { "categoryID": 1, "categoryName": "Personal", "categoryColor": 4294198070, "visibility": true, "coverImageName": null, "lastModified": 1741111111111, "fontFamily": null, "backgroundPreset": null }
  ]
}

After fetching, write the result to .opennote/opennote-labels-cache.json with the current timestamp as fetchedAt.

Step 2: Choose a label/category

  • If the user specified a label by name or ID, use that categoryID.
  • If the user did NOT specify a label, pick a random label from the cached label list.
  • If no labels are cached at all, use category: 0 (no label).

When picking a random label, tell the user which label was selected.

Step 3: Gather note content from the user

Ask the user what they want to write about. Collect:

  • The note text content (required)
  • Optional: a title
  • Optional: whether they want stickers added
  • Optional: whether they want images (user must provide image files)

Step 4: Generate timestamps and fileName

const now = Date.now(); // Unix milliseconds
const fileName = `${now}.json`;

Step 5: Build the richContent (Quill Delta JSON string)

Build a Quill Delta array of ops, then JSON.stringify() it into the richContent field.

Supported Quill Delta operations

Plain text:

{ "insert": "Hello world" }

Newline (required - every Delta must end with at least one):

{ "insert": "\
" }

Inline styles (on text insert):

  • bold (boolean)
  • italic (boolean)
  • underline (boolean)
  • strike (boolean)
  • color (hex string like "#2a7fff") — use the palette below for best results
  • size (number, typically 2-99; app default is 17)
{ "insert": "Important", "attributes": { "bold": true, "color": "#ff0000", "size": 20 } }

Available color palette (36 colors):

Always store the light-mode hex — the app remaps it automatically when rendering in dark mode.

NameLight-mode hex
Black#000000
Charcoal#545454
Dark Grey#616161
Warm Slate#455a64
Crimson#b71c1c
Deep Red#c0392b
Brick#bf360c
Dark Amber#a04000
Mustard#9a6e00
Dark Olive#558b2f
Forest Green#2e7d32
Deep Gold#8b6914
Dark Teal#00695c
Dark Cyan#00838f
Royal Blue#1565c0
Blue#007aff
Indigo#5856d6
Deep Purple#6a1b9a
Magenta#e91e63
Pink#ff2d55
Berry#880e4f
Plum#6a0572
Dark Violet#4a148c
Brown#8d6e63
Red#ff3b30
Dark Rose#ad1457
Terracotta#8b3a1f
Sea Green#007a63
Midnight#1a237e
Deep Sage#2e5902
Ochre#7a5c00
Steel Grey#37474f
Wine#8b0000
Mahogany#6d2f1f
Deep Sea#005b72
Dark Coffee#4e342e

Block/line styles (attached to the newline op after the line):

  • align: "left", "center", "right"
  • indent: integer
  • list: "ordered", "bullet", "checked", "unchecked"
  • code-block: true
  • blockquote: true
{ "insert": "A bullet point" },
{ "insert": "\
", "attributes": { "list": "bullet" } }

Image embed:

{ "insert": { "image": "{\"src\":\"my_photo.jpg\",\"w\":1920,\"h\":1080}" } }

If dimensions are unknown:

{ "insert": { "image": "my_photo.jpg" } }

Collage embed (multi-image layout):

{
  "insert": {
    "collage": "{\"layout\":\"twoHorizontal\",\"images\":[\"img1.jpg\",\"img2.jpg\"]}"
  }
}

Available collage layouts: twoHorizontal (2), bigLeft2Right (3), bigRight2Left (3), threeRow (3), bigLeft2RectRight (3), bigTop2Bottom (3), bigLeftTopRect2Bottom (4), grid2x2 (4)

Divider embed:

{ "insert": { "divider": "split" } }

Example richContent value

The API field richContent must be a JSON string (not an object):

"[{\"insert\":\"My Title\\
\",\"attributes\":{\"bold\":true,\"size\":24}},{\"insert\":\"Today was a great day.\\
\"},{\"insert\":{\"image\":\"photo.jpg\"}},{\"insert\":\"\\
\"}]"

Step 6: Build the content field (plain text)

content is a plain-text summary used for home screen preview and search. Strip all formatting — just include the text. Do NOT put JSON or markdown here.

Step 7: Build stickerData (optional)

stickerData is a JSON string (not an object) containing an array of sticker overlay objects. Stickers float on top of the note page and are NOT part of richContent.

Each sticker object:

{
  "id": "unique_hex_id",
  "assetPath": "assets/stickers/bunny.svg",
  "dx": 150.0,
  "dy": 200.0,
  "normalizedDx": 0.39,
  "normalizedDy": 0.25,
  "scale": 1.0,
  "rotation": 0.0
}

Field rules:

  • id: unique string, format <hex_timestamp>_<6char_hex_random>
  • assetPath: must be an exact match from the bundled sticker list below
  • dx, dy: pixel offsets from top-left of note canvas (typical canvas ~390px wide)
  • normalizedDx, normalizedDy: proportional position (0.0–1.0 for dx; dy can exceed 1.0 for long content)
  • scale: 0.3 to 4.0 (1.0 = default 70px base size)
  • rotation: radians

Example stickerData field value:

"[{\"id\":\"18f0c9d2_a1b2c3\",\"assetPath\":\"assets/stickers/bunny.svg\",\"dx\":150.0,\"dy\":200.0,\"normalizedDx\":0.39,\"normalizedDy\":0.25,\"scale\":1.0,\"rotation\":0.0}]"

Available sticker asset paths

Kawaii:

assets/stickers/backpack.svg       assets/stickers/bird.svg
assets/stickers/book.svg           assets/stickers/bunny.svg
assets/stickers/burger.svg         assets/stickers/cake_slice.svg
assets/stickers/cat.svg            assets/stickers/cheese.svg
assets/stickers/chicken.svg        assets/stickers/clapboard.svg
assets/stickers/crown.svg          assets/stickers/flower_2.svg
assets/stickers/frog.svg           assets/stickers/garland.svg
assets/stickers/gramophone.svg     assets/stickers/hat.svg
assets/stickers/heart_2.svg        assets/stickers/kiwi.svg
assets/stickers/kitten.svg         assets/stickers/little_girl.svg
assets/stickers/little_girl_2.svg  assets/stickers/meals.svg
assets/stickers/muffin.svg         assets/stickers/piggy_bank.svg
assets/stickers/pizza.svg          assets/stickers/plant.svg
assets/stickers/pop_corn.svg       assets/stickers/rabbit.svg
assets/stickers/rabbit_2.svg       assets/stickers/saturn.svg
assets/stickers/shooting_star.svg  assets/stickers/skirt.svg
assets/stickers/soda_can.svg       assets/stickers/strawberry.svg
assets/stickers/symbol.svg         assets/stickers/tea_pot.svg
assets/stickers/ufo.svg            assets/stickers/wallet.svg
assets/stickers/watermelon.svg     assets/stickers/watermelon_2.svg

Animals: assets/stickers/animals/001-crocodile.svg through 040-hippopotamus.svg (040 total)

Nature: assets/stickers/nature/001-sunflower.svg through 024-tree.svg (024 total)

Characters: assets/stickers/characters/girl_001-girl.svg through girl_020-girl.svg, hippie_001-hippie.svg through hippie_020-dj.svg

Food: assets/stickers/food/misc_001-meat.svg through misc_020-dolphin.svg, k760_001-cat.svg through k760_020-ice_cream.svg, k791_001-cat.svg through k791_020-book.svg

Cute Life: assets/stickers/cute_life/k678_001-badge.svg through k678_020-vinyl_record.svg, k612_001-teddy_bear.svg through k612_020-yogurt.svg, k155_001-egg_and_bacon.svg through k155_020-rainbow.svg

Everyday: assets/stickers/everyday/k448_001-cake.svg through k448_020-violin.svg, k450_001-backpack.svg through k450_020-turtle.svg

Step 8: Upload images (if any)

If the note includes images, upload each one first:

curl -s -X POST "https://api.opennote.cc/api/v1/images" \
  -H "Authorization: Bearer $OPENNOTE_API_TOKEN" \
  -F "image=@/path/to/photo.jpg"

Response:

{ "imageName": "photo.jpg", "sizeInMB": 0.42 }

Use the returned imageName in imageList, richContent image embeds, and optionally diaryCoverImageName.

Image constraints:

  • Supported types: jpg, jpeg, png, gif, webp, heic, heif
  • Max size: 15 MB per image
  • User storage quota applies

Step 9: Assemble and send the API request

curl -s -X POST "https://api.opennote.cc/api/v1/diaries" \
  -H "Authorization: Bearer $OPENNOTE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "<timestamp>.json",
    "time": <timestamp>,
    "content": "<plain text summary>",
    "richContent": "<JSON string of Quill Delta ops>",
    "stickerData": "<JSON string of sticker array or null>",
    "diaryCoverImageName": null,
    "category": <categoryID>,
    "title": "<optional title>",
    "imageList": [],
    "isDeleted": false,
    "lastModified": <timestamp>,
    "hideTitle": false
  }'

If the API returns 409 ALREADY_EXISTS, retry with PUT:

curl -s -X PUT "https://api.opennote.cc/api/v1/diaries/<fileName>" \
  -H "Authorization: Bearer $OPENNOTE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content": "...", "richContent": "...", "lastModified": <now> }'

Step 10: Record to note history

After a successful create or update, append an entry to .opennote/opennote-history.json.

Read the existing file first (or start with an empty array [] if it doesn't exist), then append and write back.

Each history entry format:

{
  "fileName": "1741111111111.json",
  "action": "created",
  "timestamp": 1741111111111,
  "title": "Morning Walk",
  "contentPreview": "Woke up early and went for a walk in the park...",
  "categoryID": 2,
  "categoryName": "Personal",
  "hasStickers": true,
  "hasImages": false,
  "imageList": []
}

Rules for the history:

  • action: either "created" or "updated"
  • contentPreview: first 150 characters of the plain text content
  • categoryName: look up from cached labels, or "No Label" if category is 0
  • hasStickers: true if stickerData was non-null
  • hasImages: true if imageList is non-empty
  • For updates, add a new entry with action: "updated" (do not overwrite previous entries)

Step 11: Confirm to the user

Tell the user:

  • The note was created/updated successfully
  • The fileName
  • Which label was used (and whether it was randomly selected)
  • A brief summary of the content

Reading Notes from the API

When the user asks to read, search, or use an existing note as a template, use the read endpoints (requires diaries:read scope on the token).

Note: The diaries:read scope may not yet be available when creating tokens from the app. If you get a 403 INSUFFICIENT_SCOPE error on read endpoints, the token doesn't have this scope. Writing notes and fetching labels will still work.

List notes

curl -s "https://api.opennote.cc/api/v1/diaries?category=CATEGORY_ID&search=KEYWORD&limit=50&offset=0" \
  -H "Authorization: Bearer $OPENNOTE_API_TOKEN"

Query parameters (all optional):

  • category — filter by categoryID (integer)
  • search — search in content and title (partial match)
  • limit — results per page, 1–200, default 50
  • offset — pagination offset, default 0

Response:

{
  "diaries": [ { "fileName": "...", "time": ..., "content": "...", "richContent": "...", ... } ],
  "total": 42,
  "limit": 50,
  "offset": 0
}

Get a single note

curl -s "https://api.opennote.cc/api/v1/diaries/FILENAME.json" \
  -H "Authorization: Bearer $OPENNOTE_API_TOKEN"

Looking Up Previous Notes

When the user asks about notes they've previously written (e.g., "what did I write last time?", "find my note about X"), read .opennote/opennote-history.json. You can match by:

  • title (partial match)
  • contentPreview (keyword search)
  • categoryName (label name)
  • timestamp (date range)
  • fileName (exact match)

Report matching entries with their title, content preview, date, and label.

Validation Rules

Before sending, validate:

  1. richContent must be either JSON null or a JSON string that parses into an array where every element has an insert key.
  2. Never put plain text, markdown, "NULL", "null", or empty string "" into richContent.
  3. content must be plain text (for preview/search), not JSON.
  4. imageList must contain filename-only entries and include all image filenames from richContent embeds.
  5. Use Unix milliseconds for time and lastModified.
  6. stickerData must be either omitted, null, or a JSON string parsing to an array of valid sticker objects.
  7. Each sticker must use an exact assetPath from the bundled sticker list above.
  8. Sticker scale should be between 0.3 and 4.0.

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

89.6%
按下载量换算934

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills