Install
openclaw skills install @katherine0325/visnote-image-creatorThis skill should be used when generating XiaoHongShu (小红书) style images. The AI analyzes user requirements, reads template registry to select appropriate template, extracts and merges data with template defaults, and invokes generation script with properly constructed command-line arguments.
openclaw skills install @katherine0325/visnote-image-creatorThis skill automates generation of XiaoHongShu-style images by combining AI intelligence with Playwright-driven browser automation. The AI analyzes user requests, selects templates from live registry, and orchestrates image generation process.
Use this skill when:
Before processing any user request, check the following:
cat config.json
apikey field is empty: STOP and inform user:
⚠️ 需要先在 config.json 中设置 apikey 才能使用图片生成功能。
请按以下步骤设置:
1. 访问 VisNote 个人主页获取 API Key:https://vis-note.netlify.app/profile,复制 API Key
2. 复制项目根目录的 example-config.json 文件,并重命名为 config.json
3. 将复制的 API Key 填入 config.json 的 "your_api_key_here" 位置
设置完成后,再次尝试生成图片。
apikey is set: Proceed with step 1Extract following information from user's request:
Fetch the template list from the API:
GET /api/open/templates
Caching Strategy (IMPORTANT):
First request in conversation: Always fetch the latest template list from the API.
Subsequent requests in the same conversation:
Examples of cache reuse:
Examples of cache invalidation (fetch new):
Optional query parameters:
keyword: Search by template name/desc/tags (e.g., ?keyword=封面, ?keyword=正文)Example using curl:
# Get all templates
curl "https://vis-note.netlify.app/api/open/templates"
# Search for cover templates
curl "https://vis-note.netlify.app/api/open/templates?keyword=封面"
Response structure:
{
"success": true,
"data": [
{
"id": "yellow",
"name": "高对比大字报",
"desc": "适合:避坑/干货/教程",
"image": "https://...",
"tags": ["封面"],
"value": {
"title": "示例标题",
"subtitle": "示例副标题",
"tag": "标签",
"color": "#EAB308"
}
}
]
}
Template object fields:
id: Unique identifier (used in --template parameter)name: Template display namedesc: Description with use case patterns (e.g., "适合:避坑/干货/教程")tags: Classification tags (免费, VIP, 封面, 图片)value: Default data structure with all available fields for the template(used in --data parameter)Critical:
Analyze templates from the registry array and select based on:
id field and use it directly'封面' in tags field'封面' tag, or with '图片' tag'图片' in tags field'对比' keyword in desc or name'步骤' keyword in desc or namedesc field for keywords like 避坑, 干货, OOTD, 情感, etc. that match user requestdesc containing 工具/清单/测评yellow for high-contrast visibilityScenario 1: Generating Cover + Content Images
tags: ['封面'] (e.g., yellow, magazine, laser-holographic, etc.)Scenario 2: Image with Main Photo
tags: ['图片'] (e.g., tape-polaroid, soft-glass-border, etc.)Scenario 3: Comparison/Before-After Content
desc or name (e.g., classic-before-after, polaroid-before-after)Scenario 4: Tutorial/Step Content
desc or name (e.g., single-image-step, double-row-step, sidebar-nav-step)For each template in the registry array:
desc field to understand use cases (format: "适合:类别1/类别2/类别3")tags field to understand classification (免费, VIP, 封面, 图片)value field to understand data structure and available fieldsCritical: The template's value object is the foundation - it contains ALL default values including default images, colors, text, etc. Always start with this complete object and only override what user explicitly provides.
Title Extraction:
标题是"xxx" or 标题是'xxx'value.title (template default)Subtitle/Body Text Extraction:
value has subtitle or bodyText fieldssubtitle could be "穿搭分享 | 日常记录"bodyText could be "今天天气真好\n心情超级棒"value.subtitle or value.bodyText (template default)Image Fields (Critical):
value contains image, image2, etc.image: '/images/jimeng-20260125.png' → keep this unless user specifies otherwiseTag Extraction:
value.tag (template default)Author Extraction:
author field if template supports itvalue.author if exists (template default)Color Extraction:
color field if template supports itvalue.color if exists (template default)Template-Specific Fields:
value objectimage, image2 for comparison styles; step for tutorial stylesvalue object from selected template - this is your foundation and includes all required fieldssubtitle, fill it with "穿搭分享 | 日常记录"
→ If template has tag, fill it with "生活分享"value - use template defaults for unspecified fieldsBuild command with proper JSON escaping:
node scripts/generate-image.mjs \
--template <templateId> \
--data '<json_data>' \
--out <absolute-output-path> \
--template: Required. Use the id field from selected template--data: Required if overriding defaults. JSON string from merged data object--out: Optional.
visnote-YYYYMMDDHHmmss.png where YYYYMMDDHHmmss is current timestamp in that format~/Downloads/) for the full absolute pathNote: API key is automatically read from config.json, no need to pass it as a parameter.
value structure\'\\n\\\\Example:
--data '{"title":"我的标题","subtitle":"副标题","color":"#EF4444"}'
Execute the constructed command:
Endpoint: GET /api/open/templates
Base URL: https://vis-note.netlify.app
Usage:
# Get all templates
curl "https://vis-note.netlify.app/api/open/templates"
# Search templates by keyword
curl "https://vis-note.netlify.app/api/open/templates?keyword=封面"
Call this API with caching strategy:
This API is the single source of truth for:
value field)Never hardcode template information in responses, as:
value objectsCaching benefits:
User Request: "帮我生成一张 Chrome插件 的图片,标题是 一键下载微博文章"
AI Processing:
GET /api/open/templates to get all templatesdesc containing 工具/清单/测评 (for tool/software content) → academic-notes标题是"..." pattern){
"title": "一键下载微博文章", // user-provided
"bodyText": "核心知识点一\n避坑指南二\n保姆级教程三", // from template.value
"tag": "插件分享", // extracted + formatted
"author": "@你的名字", // from template.value
"color": "#F59E0B" // from template.value
}
node scripts/generate-image.mjs \
--template academic-notes \
--data '{"title":"一键下载微博文章","bodyText":"核心知识点一\\n避坑指南二\\n保姆级教程三","tag":"插件分享","author":"@你的名字","color":"#F59E0B"}' \
--out ~/Downloads/visnote-20260302143022.png
visnote-20260302143022.pngUser Request: "使用 yellow 模板生成一张干货封面,标题是3秒抓住用户注意力"
AI Processing:
GET /api/open/templates to get all templatesid = "yellow" → yellow template{
"title": "3秒抓住用户注意力", // user-provided
"subtitle": "3秒抓住用户注意力 | 涨粉秘籍", // from template.value
"tag": "干货分享", // extracted from "干货"
"color": "#EAB308" // from template.value
}
node scripts/generate-image.mjs \
--template yellow \
--data '{"title":"3秒抓住用户注意力","subtitle":"3秒抓住用户注意力 | 涨粉秘籍","tag":"干货分享","color":"#EAB308"}' \
--out ~/Downloads/visnote-20260302143022.png
User Request: "生成一张装修前后对比图,标题装修改造"
AI Processing:
GET /api/open/templates to get all templatesdesc containing 对比 or name containing 对比 → classic-before-after{
"title": "装修改造", // user-provided
"subtitle": "3秒抓住用户注意力 | 涨粉秘籍", // from template.value
"color": "#EF4444" // from template.value
}
node scripts/generate-image.mjs \
--template classic-before-after \
--data '{"title":"装修改造","subtitle":"3秒抓住用户注意力 | 涨粉秘籍","color":"#EF4444"}' \
--out ~/Downloads/visnote-20260302143022.png
User Request: "根据文档内容生成封面图和几张内容图,内容是关于小红书配图工具的"
AI Processing:
GET /api/open/templates to get all templatestags containing '封面' → yellow (high-contrast, eye-catching)glass (情绪磨砂玻璃, good for sharing)node scripts/generate-image.mjs \
--template yellow \
--data '{"title":"做小红书\n配图终于省心了","subtitle":"同一套模板搞定封面+正文","color":"#EAB308","tag":"实测分享"}' \
--out ~/Downloads/visnote-20260302220201.png
glass template, varying colors):
--out parameter\\n when appropriateyellow template'封面' in tags'图片' in tags'封面' tagdesc or namedesc or nameIMPORTANT: API Key Required
This skill requires the API key to be set in config.json. Without it, the image generation will fail.
First-time setup:
# Create or edit config.json in project root
cat > config.json << 'EOF'
{
"apikey": "your_api_key_here"
}
EOF
Verification:
cat config.json
Ensure the file exists and contains a valid API key in the apikey field.
Where to get your API key:
Before generating any image, the script will validate the API key by calling ${server}/api/open/check endpoint. The following checks will be performed:
API Key Existence: Verifies the API key exists in the system
Membership Status: Checks if user is a VIP member
Membership Expiry: Checks if VIP membership is still valid
Available Quota: Checks if user has remaining image generation quota
Note: All validation errors will stop the image generation process immediately with a clear error message.
npm install playwright
npx playwright install chromium
${server}/api/open/templates${server}/api/open/checkError message: "API Key 不存在"
cat config.jsonapikey field is set with a valid API keyError message: "您还不是会员"
Error message: "您的会员已过期"
Error message: "生图额度已用完"
/editor route exists${server}/api/open/templates