A unified Bee Website Builder Open API skill that helps an agent choose the correct Bee data operation from a user's desired business result. Use it when the...
---
name: bee-skill
description: A unified Bee Website Builder Open API skill that helps an agent choose the correct Bee data operation from a user's desired business result. Use it when the user wants to read, create, update, delete, or analyze blogs, blog groups, products, product groups, inquiries, visitors, or keyword rankings on the Bee platform.
homepage: https://open.tradew.com
metadata:
{
"openclaw":
{
"emoji": "🐝",
"requires": { "env": ["BEE_API_KEY"] },
"primaryEnv": "BEE_API_KEY"
}
}
---
# bee-skill
> Version: 2.11.25
## Overview
This skill merges multiple Bee Website Builder Open API capabilities into a single publishable skill.
All future Bee capabilities added in this repository must be exposed through `bee-skill` rather than published as separate primary skills.
This skill should be selected by the user's expected result, not only by API name.
When the user speaks in natural language such as "find the product", "show products under this category", "read one exact blog", "look at recent inquiries", "see which keywords are ranking in the top 100", or "delete these products", map that request to the matching `action` below and choose the narrowest valid filter.
Supported actions:
- `languages_get`
- `blog_create`
- `blog_update`
- `blog_read`
- `blog_delete`
- `bloggroup_create`
- `bloggroup_update`
- `bloggroup_read`
- `bloggroup_delete`
- `productsgroup_create`
- `productsgroup_update`
- `productsgroup_delete`
- `productsgroup_read`
- `products_read`
- `products_create`
- `products_update`
- `products_delete`
- `inquiry_read`
- `visitor_recent`
- `keywords_rank`
## HTML Fragment Rules
Before generating any HTML fragment for:
- `blog.description`
- `products.description`
- `productsgroup.section.top`
- `productsgroup.section.bottom`
first call `https://platfrom.tradew.com/openapis/rule` with:
- the same `api_key`
- the exact selected `language`
- the exact matching `scene`
`https://platfrom.tradew.com/openapis/rule` call requirements:
- method: `POST`
- header `Authorization: Bearer <API_KEY>` is required
- header `Content-Type: application/json` is required
- `language` is required
- `scene` is required
- use the exact `language` value already selected for the create or update action
- do not guess, translate, normalize, or replace the `language` value
- do not invent, shorten, translate, or rename any `scene` value
- use only the fixed scene mapping below. Do not call the current frontend website domain for this rule API.
Minimal request body:
```json
{
"language": "en",
"scene": "products.description"
}
```
Example request pattern:
```text
POST https://platfrom.tradew.com/openapis/rule
Authorization: Bearer <API_KEY>
Content-Type: application/json
{"language":"en","scene":"products.description"}
```
Required execution order:
1. Select the exact site `language` first.
2. Select the exact fixed `scene` that matches the target HTML field.
3. Call `https://platfrom.tradew.com/openapis/rule`.
4. Generate the HTML fragment only after the rule API returns successfully.
Failure rule:
- If the rule API call fails, do not continue by guessing colors, fonts, links, layout, or other fragment rules.
- Stop and report the rule-call failure instead of generating a fragment from assumptions.
Scene mapping:
- `blog.description` -> `scene=blog.description`
- `products.description` -> `scene=products.description`
- `productsgroup.section.top` -> `scene=productsgroup.section.top`
- `productsgroup.section.bottom` -> `scene=productsgroup.section.bottom`
The generated fragment must follow the returned rule payload, especially:
- use the exact selected language only
- follow the full returned rule payload, not only part of it
- do not guess, replace, shorten, rename, or partially ignore returned rule fields
- do not hardcode assumptions in this skill about future rule details; `https://platfrom.tradew.com/openapis/rule` is the source of truth
## Quick Routing Guide
Choose the action by the user's actual goal and the result they expect to see.
### Result-First Routing
- If the user wants to know "what exists", prefer a `*_read` action.
- If the user wants to "add new content", prefer a `*_create` action.
- If the user wants to "change existing content", prefer a `*_update` action.
- If the user wants to "remove existing content", prefer a `*_delete` action.
- If the user asks for analytics, visit history, inquiry records, or keyword performance, prefer the specialized read action instead of any content action.
### How Users Usually Ask
- "帮我看一下", "查一下", "列出来", "看看有没有", "找这个", "读一下"
Route these to the matching `*_read` action.
- "新增", "创建", "发布", "添加"
Route these to the matching `*_create` action.
- "修改", "编辑", "更新", "调整"
Route these to the matching `*_update` action.
- "删除", "移到回收站", "移除"
Route these to the matching `*_delete` action.
- "最近访客", "访客 IP", "关键词排名", "询盘记录"
Route these to `visitor_recent`, `keywords_rank`, or `inquiry_read` instead of blog or product actions.
### Language Selection
- Use `languages_get` when the user asks:
- "What languages are enabled?"
- "Show available site languages"
- "Which language code should I use?"
### Blog Operations
- Use `blog_read` when the user asks:
- "Read blogs"
- "List blog articles"
- "Find one exact blog"
- "Show blogs under this blog group"
- "帮我查这篇博客"
- "看某个分类下面的博客"
- Use `blog_create` when the user asks:
- "Create a blog"
- "Publish an article"
- "Add a new blog post"
- Use `blog_update` when the user asks:
- "Update blog 123"
- "Edit blog content"
- "Move a blog to another group"
- Use `blog_delete` when the user asks:
- "Delete blog 123"
- "Move these blogs to recycle bin"
### Blog Group Operations
- Use `bloggroup_read` when the user asks:
- "List blog groups"
- "Read one exact blog group"
- "Show blog categories"
- "博客分类有哪些"
- "查一下这个博客分组"
- Use `bloggroup_create` when the user asks:
- "Create a blog group"
- "Add a blog category"
- Use `bloggroup_update` when the user asks:
- "Update blog group 456"
- "Rename a blog category"
- Use `bloggroup_delete` when the user asks:
- "Delete these blog groups"
### Product Operations
- Use `products_read` when the user asks:
- "Read products"
- "List product data"
- "Find one exact product"
- "Show products under this group"
- "帮我找这个产品"
- "看这个分组下有哪些产品"
- "读取产品详情"
- Use `products_create` when the user asks:
- "Create a product"
- "Publish a new product"
- "Add a product listing"
- Use `products_update` when the user asks:
- "Update product 123"
- "Modify product content"
- "Move a product to another group"
- Use `products_delete` when the user asks:
- "Delete product 123"
- "Move these products to recycle bin"
### Product Group Operations
- Use `productsgroup_read` when the user asks:
- "List product groups"
- "Read top-level product groups"
- "Read child groups under this parent"
- "Find one exact product group"
- "产品分类有哪些"
- "这个父分类下面有哪些子分类"
- Use `productsgroup_create` when the user asks:
- "Create a product group"
- "Add a product category"
- Use `productsgroup_update` when the user asks:
- "Update product group 456"
- "Edit product category info"
- Use `productsgroup_delete` when the user asks:
- "Delete these product groups"
### Inquiry, Visitor, and Ranking Operations
- Use `inquiry_read` when the user asks:
- "Read inquiries"
- "List leads"
- "Show recent inquiry records"
- "最近有哪些询盘"
- "帮我看最近客户留言"
- Use `visitor_recent` when the user asks:
- "Check recent visitors"
- "Find visitor by IP"
- "Show latest visitor behavior"
- "看最近访客"
- "查这个 IP 的访问情况"
- Use `keywords_rank` when the user asks:
- "Check keyword ranking"
- "Find one exact keyword ranking"
- "Show keywords ranked within top 100"
- "看关键词表现"
- "查前 100 名的关键词"
## Selection Principles
- Prefer `*_read` when the user asks to read, list, find, search, query, check, or analyze existing records.
- Prefer `*_create` when the user asks to add, create, publish, or insert new content.
- Prefer `*_update` when the user asks to modify existing blog, blog-group, product, or product-group content.
- Prefer `*_delete` when the user asks to delete, remove, or move content to the recycle bin.
- If the user mentions one exact ID, prefer the corresponding exact-ID read filter instead of a broader group filter.
- If the user mentions "under this group", "in this category", or "belonging to this group", prefer the corresponding group filter.
- If the request needs a language and the user has not provided one exact enabled code yet, call `languages_get` first.
- If the user gives both an exact ID and a group condition, prefer the exact ID if the API requires a mutually exclusive choice.
- If the user wants "details", "that one", or "the exact record", prefer the exact-ID filter over list-style filters.
- If the user wants "all", "recent", or "latest list", avoid adding unnecessary exact-ID filters.
- If the user asks for a business result but does not name the object type clearly, infer the object from nouns:
`product` -> `products_*`, `product group/category` -> `productsgroup_*`, `blog/article` -> `blog_*`, `blog group/category` -> `bloggroup_*`.
## Routing by Expected Result
Use this section when a request is phrased around a business outcome instead of an API term.
- "I want to know what product data exists"
Use `products_read`.
- "I want one exact product"
Use `products_read` with `products_id`.
- "I want products inside one category"
Use `products_read` with `productsgroup_id`.
- "I want all top-level product categories"
Use `productsgroup_read` with no filter or `parent_productsgroup_id=0`.
- "I want subcategories under one parent category"
Use `productsgroup_read` with `parent_productsgroup_id`.
- "I want one exact product category"
Use `productsgroup_read` with `productsgroup_id`.
- "I want blog articles"
Use `blog_read`.
- "I want one exact blog"
Use `blog_read` with `blog_id`.
- "I want blogs inside one blog group"
Use `blog_read` with `bloggroup_id`.
- "I want all blog groups or one exact blog group"
Use `bloggroup_read`, optionally with `bloggroup_id`.
- "I want inquiry records from recent days"
Use `inquiry_read`, optionally with `recent_days`.
- "I want recent visitor data"
Use `visitor_recent`.
- "I want visitor data for one IP"
Use `visitor_recent` with `ip`.
- "I want keyword ranking for one keyword"
Use `keywords_rank` with `keywords`.
- "I want keywords ranking within the top N"
Use `keywords_rank` with `rank`.
## Filter Selection Rules
When multiple filters exist, choose the one that most directly matches the user's wording.
- `products_read`
If the user names one exact product, use `products_id`.
If the user asks for products under one group, use `productsgroup_id`.
Do not send both together.
- `productsgroup_read`
If the user asks for one exact group, use `productsgroup_id`.
If the user asks for children under a parent, use `parent_productsgroup_id`.
If the user asks for top-level groups, omit both or use `parent_productsgroup_id=0`.
- `blog_read`
If the user names one exact blog, use `blog_id`.
If the user asks for blogs under one group, use `bloggroup_id`.
Do not send both together.
- `bloggroup_read`
If the user asks for one exact blog group, use `bloggroup_id`.
Otherwise omit it to read the list.
- `visitor_recent`
If the user gives one IP, use `ip`.
Otherwise omit it to read recent visitors across all IPs.
- `keywords_rank`
If the user gives one exact keyword text, use `keywords`.
If the user asks for "top N", use `rank`.
Do not send both together.
## Required Parameters
### `api_key` (string)
API authentication key used for caller identity verification and interface access control.
- Get it from: https://open.tradew.com
- Recommended configuration: inject it through `skills.entries.env.BEE_API_KEY`
- Do not paste the key into prompts or chat text when environment configuration is available
- Prefer a least-privilege Bee API key scoped only to the operations you intend to allow
### `action` (string)
Selects which capability to execute.
Practical routing rule:
- "read/list/find/check/analyze" -> usually choose a `*_read` action
- "create/add/publish" -> usually choose a `*_create` action
- "update/edit/modify/change" -> usually choose a `*_update` action
- "delete/remove/recycle bin" -> usually choose a `*_delete` action
## Common Parameters
### `language` (string)
Used by most content operations.
- This must be the exact site language code returned by `languages_get`, such as `en` or `fr`
- Do not guess, translate, normalize, or invent the value
- First call `languages_get`, show the language list to the user, then copy one exact `language` value the user confirms
### `bloggroup_id` (integer)
Used by `blog_read` and `bloggroup_read`.
- Omit this field to read blogs from all groups.
- If you need blog-group filtering, use a positive blog group ID selected from `bloggroup_read` under the same language.
- For `blog_read`, do not send this field together with `blog_id`. The rule is: omit both to read all blogs, or provide exactly one of them.
- For `bloggroup_read`, omit this field to read all blog groups.
- For `bloggroup_read`, if you need one specific blog group, send one positive existing `bloggroup_id`.
### `blog_id` (integer)
Used by `blog_read`.
- Omit this field to avoid exact-blog filtering.
- If you need one specific blog, send one positive existing `blog_id`.
- For `blog_read`, do not send this field together with `bloggroup_id`. The rule is: omit both to read all blogs, or provide exactly one of them.
### `ip` (string)
Used by `visitor_recent`.
- Omit this field to read recent visitors for all IPs.
- If you need one specific visitor IP, send one exact IPv4 or IPv6 address.
### `keywords` (string)
Used by `keywords_rank`.
- Omit this field to read all keyword ranking records.
- If you need one specific keyword ranking record, send one exact non-empty keyword string.
- For `keywords_rank`, do not send this field together with `rank`. The rule is: omit both to read all records, or provide exactly one of them.
### `rank` (integer)
Used by `keywords_rank`.
- Omit this field to read all keyword ranking records.
- If you need keywords ranked within the top N positions, send one integer from `1` to `999`.
- `rank=100` means return keywords ranked within positions `1` through `100`, not only keywords whose rank equals `100`.
- For `keywords_rank`, do not send this field together with `keywords`. The rule is: omit both to read all records, or provide exactly one of them.
### `parent_productsgroup_id` (integer)
Used by `productsgroup_read`.
- Omit this field or set `0` to read top-level groups.
- If provided as a positive integer (`> 0`), the API returns the direct child groups under that parent group.
- This is a parent group selector, not a leaf-group validator.
- Do not send this field together with `productsgroup_id` for `productsgroup_read`. The rule is: omit both to read top-level groups, or provide exactly one of them.
### `productsgroup_id` (integer)
Used by `products_read` and `productsgroup_read`.
- For `products_read`, omit this field to read products from all groups. If you need group filtering, use a positive leaf group ID selected from `productsgroup_read` where `is_leaf === true`.
- For `products_read`, do not send this field together with `products_id`. The rule is: omit both to read all products, or provide exactly one of them.
- For `productsgroup_read`, omit this field to avoid exact-group filtering. If provided, use one positive existing `productsgroup_id`.
- For `productsgroup_read`, do not send this field together with `parent_productsgroup_id`. The rule is: omit both to read top-level groups, or provide exactly one of them.
### `products_id` (integer)
Used by `products_read`.
- Omit this field to avoid exact-product filtering.
- If you need one specific product, send one positive existing `products_id`.
- For `products_read`, do not send this field together with `productsgroup_id`. The rule is: omit both to read all products, or provide exactly one of them.
### `pagination` (object)
Used by `blog_read`, `bloggroup_read`, `products_read`, `inquiry_read`, `visitor_recent`, and `keywords_rank`.
```json
{
"current_page": 1,
"page_size": 10
}
```
### `products` (object)
Used by `products_create` and `products_update`.
This object contains the product payload.
- For `products_create`, send a complete new product payload
- For `products_update`, `products_id` is required and every other field is optional
- For `products_update`, omit any field that should stay unchanged
- Do not send guessed IDs or guessed field values
For `products.productsgroup_id`:
- In `products_create`, this field is required and must be a positive leaf group ID selected from `productsgroup_read` where `is_leaf === true`.
- In `products_update`, omit this field to keep the current group unchanged. If provided, it must follow the same leaf-group rule.
Field rules:
- `products.products_id`: required only for `products_update`. This is the real existing product ID to edit.
- `products.product_name`: product title. Omit it in `products_update` if the name should not change.
- `products.model`: product model. Omit it in `products_update` if the model should not change.
- `products.upload_images`: for `products_create`, provide 1 to 5 images; the first image becomes the main image. For `products_update`, omit this field if images should not change.
- `products.attributes`: optional visible attribute pairs such as material, size, or color. Omit in `products_update` if unchanged.
- `products.tags`: search keywords. For `products_create`, provide at least 1 tag and at most 6. For `products_update`, omit if unchanged.
- `products.brief_description`: short plain-text summary. Omit in `products_update` if unchanged.
- `products.description`: detailed HTML description. Only inline styles are allowed, such as `<p style="color:red">...`. Do not use markdown, `<style>` blocks, linked CSS, class-based styling, or any `<h1>` tag. Use `<h2>` to `<h6>` or normal block elements instead. Omit in `products_update` if unchanged.
- `products.seo.keywords`: one comma-separated string, not an array.
### `blog` (object)
Used by `blog_create` and `blog_update`.
- `blog.blog_id`: required for `blog_update`. This is the existing blog ID to edit.
- `blog.bloggroup_id`: required blog group ID for `blog_create`. In `blog_update`, omit it if the blog should stay in the current group.
- `blog.publisher`: optional publisher name, up to 100 characters. Omit it in `blog_update` if unchanged.
- `blog.publication_date`: optional display date in `yyyy/M/d` format, for example `2026/4/24`. Omit it in `blog_update` if unchanged.
- `blog.title`: required blog title for `blog_create`, up to 500 characters. Omit it in `blog_update` if unchanged.
- `blog.cover_image`: optional cover image object with `name` and `base64`. Omit it in `blog_update` if the cover image should stay unchanged.
- `blog.tags`: required keyword list with 1 to 6 items for `blog_create`. Omit in `blog_update` if unchanged.
- `blog.summary`: required plain-text summary for `blog_create`, up to 500 characters. Omit in `blog_update` if unchanged.
- `blog.description`: required HTML content for `blog_create`, up to 100,000 characters. Do not include any `<h1>` tag; use `<h2>` to `<h6>` or normal block elements instead. Omit in `blog_update` if unchanged.
- `blog.seo`: optional SEO object with `title`, `description`, and `keywords`. Omit it in `blog_update` if SEO should stay unchanged.
### `productsgroup` (object)
Used by `productsgroup_create` and `productsgroup_update`.
- `productsgroup.parent_productsgroup_id`: optional parent group ID. Omit it or set `0` for a top-level group.
- `productsgroup.productsgroup_id`: required for `productsgroup_update`. This is the existing product group ID to edit.
- `productsgroup.group_name`: required product group name, up to 200 characters.
- `productsgroup.tags`: required keyword list with 1 to 6 items. Each tag must contain 3 to 50 characters.
- `productsgroup.brief_description`: optional short plain-text description, up to 4,000 characters.
- `productsgroup.section`: optional custom HTML decoration object for the product group detail page body.
- `productsgroup.section.top`: optional product group page header decoration fragment. HTML fragment only. Use inline styles only, do not include any `<h1>` tag, and prefer `<h2>` to `<h6>`. Maximum length: 100,000 characters. In `productsgroup_update`, omit this field or pass an empty string to keep the current top fragment unchanged.
- `productsgroup.section.bottom`: optional product group page footer decoration fragment. HTML fragment only. Use inline styles only, do not include any `<h1>` tag, and prefer `<h2>` to `<h6>`. Maximum length: 100,000 characters. In `productsgroup_update`, omit this field or pass an empty string to keep the current bottom fragment unchanged.
- `productsgroup.seo`: optional for `productsgroup_update`. Omit it if SEO should stay unchanged.
### `bloggroup` (object)
Used by `bloggroup_create` and `bloggroup_update`.
- `bloggroup.bloggroup_id`: required for `bloggroup_update`. This is the existing blog group ID to edit.
- `bloggroup.group_name`: required blog group name for `bloggroup_create`, up to 100 characters. Omit it in `bloggroup_update` if unchanged.
- `bloggroup.tags`: required keyword list with 1 to 6 items for `bloggroup_create`. Omit it in `bloggroup_update` if unchanged.
- `bloggroup.brief_description`: optional short plain-text description, up to 300 characters. Omit it in `bloggroup_update` if unchanged.
- `bloggroup.seo`: optional SEO object with `title`, `description`, and `keywords`. Omit it in `bloggroup_update` if SEO should stay unchanged.
### `id_list` (array)
Used by `blog_delete`, `bloggroup_delete`, `productsgroup_delete`, and `products_delete`.
### `confirmation` (object)
Required by `blog_create`, `blog_update`, `blog_delete`, `bloggroup_create`, `bloggroup_update`, `bloggroup_delete`, `productsgroup_create`, `productsgroup_update`, `productsgroup_delete`, `products_create`, `products_update`, and `products_delete`.
Before any create, update, or delete action, show the user the language and the exact payload or product IDs to be changed, then set:
```json
{
"approved": true,
"summary": "Confirmed by user: update product 123 in language en with the shown payload."
}
```
For every `*_update` action, this skill also enforces a pre-update backup capture and file persistence step.
- The current record must be read successfully before the update request is sent.
- The backup must be written to a local JSON file under `MNskill/backups/<action>/`.
- If backup capture fails, or if the backup file cannot be written, the update must not run.
- If the update succeeds, the response includes `backup.storage.file_path`, `backup.raw_read_response`, `backup.snapshot`, and a best-effort `backup.restore_payload`.
- If the user later says the edit result is wrong, reuse that `backup.restore_payload` with the same `*_update` action to restore the previous state.
- Uploaded images are only partially restorable because the read APIs do not return the original image base64 content.
## Action Guide
### `languages_get`
Returns the list of enabled site languages.
Common user intents:
- "Show enabled languages"
- "What language codes can I use?"
### `blog_create`
Creates and publishes a new blog under the selected language and blog group.
This action must not run unless the user has explicitly confirmed the language and exact blog payload to be created.
Common user intents:
- "Create a blog"
- "Publish an article"
### `blog_update`
Updates an existing blog under the selected language.
This action must not run unless the user has explicitly confirmed the language, target blog ID, and exact payload to be changed.
Update rules:
- `blog.blog_id` is required
- Any field other than `blog_id` should be omitted unless the user explicitly wants to change it
- Omitting a field means keep the existing value
- Do not move the blog group unless the user explicitly asks for that change
- Capture a pre-update backup snapshot first; if backup capture fails, abort the update
- Return `backup.restore_payload` on success so the same blog can be restored later if needed
Common user intents:
- "Update blog 123"
- "Edit blog information"
### `blog_read`
Returns published blog data with optional pagination, blog-group filtering, or exact blog filtering.
Common user intents:
- "Read blogs"
- "List blog articles"
- "Find blog 123"
### `blog_delete`
Moves one or more blogs to the recycle bin.
This action must not run unless the user has explicitly confirmed the language and exact blog IDs to be moved.
Common user intents:
- "Delete these blogs"
- "Move blog 123 to recycle bin"
### `bloggroup_create`
Creates and publishes a new blog group under the selected language.
This action must not run unless the user has explicitly confirmed the language and exact blog group payload to be created.
Common user intents:
- "Create a blog group"
- "Add a blog category"
### `bloggroup_update`
Updates an existing blog group under the selected language.
This action must not run unless the user has explicitly confirmed the language, target blog group ID, and exact payload to be changed.
Update rules:
- `bloggroup.bloggroup_id` is required
- Any field other than `bloggroup_id` should be omitted unless the user explicitly wants to change it
- Omitting a field means keep the existing value
- Capture a pre-update backup snapshot first; if backup capture fails, abort the update
- Return `backup.restore_payload` on success so the same blog group can be restored later if needed
Common user intents:
- "Update blog group 456"
- "Edit blog category"
### `bloggroup_read`
Returns blog group data for a selected language with optional exact group filtering, field selection, and pagination.
Common user intents:
- "List blog groups"
- "Read one exact blog group"
### `bloggroup_delete`
Deletes one or more blog groups for a selected language and returns separate success and failure ID lists.
This action must not run unless the user has explicitly confirmed the language and exact blog group IDs to delete.
Common user intents:
- "Delete these blog groups"
### `productsgroup_create`
Creates and publishes a new product group under the selected language.
This action must not run unless the user has explicitly confirmed the language and exact product group payload to be created.
Common user intents:
- "Create a product group"
- "Add a product category"
### `productsgroup_update`
Updates an existing product group under the selected language.
This action must not run unless the user has explicitly confirmed the language, target product group ID, and exact payload to be changed.
Update rules:
- `productsgroup.productsgroup_id` is required
- Any field other than `productsgroup_id` should be omitted unless the user explicitly wants to change it
- Omitting a field means keep the existing value
- If `productsgroup.section` is sent, `top` and `bottom` can be updated independently: omit one fragment or send an empty string to keep it unchanged
- Capture a pre-update backup snapshot first; if backup capture fails, abort the update
- Return `backup.restore_payload` on success so the same product group can be restored later if needed
Common user intents:
- "Update product group 456"
- "Edit product category"
### `productsgroup_delete`
Deletes one or more product groups for a selected language and returns separate success and failure ID lists.
This action must not run unless the user has explicitly confirmed the language and exact product group IDs to delete.
Common user intents:
- "Delete these product groups"
### `productsgroup_read`
Returns published product groups for a selected language.
Filter rules:
- Omit `parent_productsgroup_id` or set it to `0` to read top-level groups.
- Send `parent_productsgroup_id` to read the direct child groups under one parent group.
- Send `productsgroup_id` to read one exact product group.
- `parent_productsgroup_id` and `productsgroup_id` are mutually exclusive and must not be sent together.
- Use `fields=["section"]` or include `section` in the field list when the caller needs the custom top/bottom HTML fragments.
Common user intents:
- "List product groups"
- "Read top-level groups"
- "Read child groups under this parent"
- "Find product group 789"
### `products_read`
Returns published product data with optional pagination, product group filtering, or exact product filtering.
Filter rules:
- You may omit both `products_id` and `productsgroup_id` to read all products.
- You may send `products_id` to read one exact product.
- You may send `productsgroup_id` to read products under one leaf group.
- `products_id` and `productsgroup_id` are mutually exclusive and must not be sent together.
Common user intents:
- "Read products"
- "List products in this group"
- "Find product 123"
### `products_create`
Creates a new product under the selected language and product group.
This action must not run unless the user has explicitly confirmed the language and exact product payload to be created.
Minimum practical payload:
- `language`
- `products.productsgroup_id`
- `products.product_name`
- `products.upload_images`
- `products.tags`
- `products.brief_description`
- `products.description`
- `confirmation.approved=true`
- `confirmation.summary`
Common user intents:
- "Create a product"
- "Publish a new product"
### `products_update`
Updates an existing product under the selected language.
This action must not run unless the user has explicitly confirmed the language, target product ID, and exact payload to be changed.
Update rules:
- `products.products_id` is required
- Any field other than `products_id` should be omitted unless the user explicitly wants to change it
- Omitting a field means keep the existing value
- Do not move the product group unless the user explicitly asks for that change
- Capture a pre-update backup snapshot first; if backup capture fails, abort the update
- Return `backup.restore_payload` on success so the same product can be restored later if needed
Common user intents:
- "Update product 123"
- "Edit product information"
### `products_delete`
Moves one or more products to the recycle bin.
This action must not run unless the user has explicitly confirmed the language and exact product IDs to be moved to the recycle bin.
Common user intents:
- "Delete these products"
- "Move product 123 to recycle bin"
### `inquiry_read`
Returns inquiry records with optional language, recent-day filtering, and pagination.
Common user intents:
- "Read inquiries"
- "Show recent leads"
- "List inquiry records"
### `visitor_recent`
Returns recent visitor analytics with optional exact IP filtering and pagination.
Common user intents:
- "Check recent visitors"
- "Find visitor by IP"
- "Show latest visitor behavior"
### `keywords_rank`
Returns keyword ranking records with optional exact keyword filtering, optional top-N rank filtering, pagination, latest rank values, and rank history.
Common user intents:
- "Check keyword ranking"
- "Find one keyword ranking"
- "Show keywords ranked within top 100"
## Extension Rule
When adding a new Bee capability in the future:
1. Add or update the underlying implementation module.
2. Register the new action in the root `index.js` action router.
3. Add the new action to the root `skill.json` input schema.
4. Document the new action here in the root `SKILL.md`.
Changes are not complete unless the unified `bee-skill` entrypoint supports the new capability end to end.
## Example
```json
{
"api_key": "your-api-key",
"action": "products_read",
"language": "en",
"products_id": 12345,
"pagination": {
"current_page": 1,
"page_size": 10
}
}
```
## Decision Examples
```text
User: "帮我查一下产品分类"
Choose: productsgroup_read
Reason: the user wants product category data, not product data
```
```text
User: "看一下这个分类下面有哪些产品"
Choose: products_read + productsgroup_id
Reason: the user wants product records under one group
```
```text
User: "帮我找产品 12345"
Choose: products_read + products_id
Reason: the user wants one exact product
```
```text
User: "看最近访客,顺便过滤这个 IP"
Choose: visitor_recent + ip
Reason: this is visitor analytics, not inquiry or product content
```
```text
User: "查前 100 名关键词"
Choose: keywords_rank + rank=100
Reason: the user wants a top-N ranking slice, not one exact keyword
```
don't have the plugin yet? install it then click "run inline in claude" again.