
Feishu Robot Registry
- 2 installs
- 20 repo stars
- Updated April 11, 2026
- autogame-17/feishu-skills
feishu-robot-registry is a Claude skill that maintains a Robot Contact List in a Feishu docx, registering and listing Feishu bots by name, session key, and app ID.
About
feishu-robot-registry maintains a centralized Robot Contact List for Feishu bots inside a Feishu docx document. It registers robots with a name, session key, app ID, and timestamp, lists all registered robots as JSON, and auto-creates or reuses a registry document. Developers use it when onboarding Feishu bots or tracking robot deployments across a fleet. It requires feishu-common for auth.
- Maintains a Robot Contact List of Feishu bots in a docx document
- Registers robots with name, session key, and app ID plus timestamp
- Auto-creates or reuses the registry doc and lists all robots as JSON
Feishu Robot Registry by the numbers
- 2 all-time installs (skills.sh)
- Ranked #1,842 of 2,719 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
feishu-robot-registry capabilities & compatibility
Free skill; requires a Feishu app credential pair (FEISHU_APP_ID / FEISHU_APP_SECRET) via feishu-common.
- Capabilities
- feishu doc · feishu memory recall
- Works with
- notion
- Use cases
- orchestration
What feishu-robot-registry says it does
Registers new robots (name, session key, app ID) to a Feishu docx document and lists all registered robots.
npx skills add https://github.com/autogame-17/feishu-skills --skill feishu-robot-registryAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 20 |
| Last updated | April 11, 2026 |
| Repository | autogame-17/feishu-skills ↗ |
What it does
Register Feishu bots and maintain a centralized robot directory in a Feishu docx.
Who is it for?
Onboarding Feishu bots and tracking robot deployments in a centralized docx registry.
Skip if: General document editing or messaging; it only manages a robot metadata registry.
When should I use this skill?
Onboarding Feishu bots, tracking robot deployments, or maintaining a centralized robot directory.
What you get
A shared Feishu docx registry holds every robot's name, session key, app ID, and registration time.
- A Feishu docx registry of robots and a JSON listing of registered robots
By the numbers
- 3 actions (register, list, auto-create)
- 3 metadata fields per robot (name, session key, app ID)
Files
feishu-robot-registry
Manages the Robot Contact List in Feishu. Creates or reuses a Feishu docx document to store robot metadata (name, session key, app ID) and supports registration and listing of robots.
What It Does
- Register: Appends a new robot entry to the registry doc with name, session key, app ID, and timestamp
- List: Reads all registered robot entries from the doc and outputs them as JSON
- Auto-create: If no registry exists, creates a new Feishu docx titled "Robot Contact List (机器人通讯录)" or searches for an existing one
Requires feishu-common for auth and FEISHU_APP_ID / FEISHU_APP_SECRET in environment.
Usage
# Register a new robot
node skills/feishu-robot-registry/index.js register --name "MyBot" --session-key "session_xxx" --app-id "cli_xxx"
# List all registered robots
node skills/feishu-robot-registry/index.js list
# Use a specific doc token
node skills/feishu-robot-registry/index.js register --name "MyBot" --session-key "xxx" --app-id "xxx" --doc-token "doccnxxx"Configuration
- registry_config.json: Auto-created in the skill directory; stores
doc_tokenfor the registry document - Environment:
FEISHU_APP_ID,FEISHU_APP_SECRET(via feishu-common)
const { fetchWithAuth, getToken } = require('../feishu-common/index.js');
const { program } = require('commander');
const fs = require('fs');
const path = require('path');
const CONFIG_PATH = path.join(__dirname, 'registry_config.json');
// --- Helper: Get/Create Registry Doc ---
async function getRegistryDoc(accessToken) {
// 1. Check local config
if (fs.existsSync(CONFIG_PATH)) {
try {
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
if (config.doc_token) return config.doc_token;
} catch (e) {}
}
// 2. Search for existing doc (simplified search)
// NOTE: Search API requires specific permissions. If fails, fallback to create.
try {
const searchRes = await fetchWithAuth('https://open.feishu.cn/open-apis/suite/docs-api/search/object', {
method: 'POST',
body: JSON.stringify({
search_key: "Robot Contact List",
count: 1,
type: "docx",
owner_ids: [] // Search global if possible? Usually scoped to user.
})
});
const searchData = await searchRes.json();
if (searchData.data?.docs?.length > 0) {
const docToken = searchData.data.docs[0].token;
saveConfig(docToken);
return docToken;
}
} catch (e) {
// Search failed or no permission, proceed to create
}
// 3. Create new doc
const createRes = await fetchWithAuth('https://open.feishu.cn/open-apis/docx/v1/documents', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title: "Robot Contact List (机器人通讯录)" })
});
const createData = await createRes.json();
if (createData.code !== 0) throw new Error(`Create doc failed: ${createData.msg}`);
const newDocToken = createData.data.document.document_id;
saveConfig(newDocToken);
// Initialize header
await appendBlock(newDocToken, accessToken, [
{ block_type: 3, heading1: { elements: [{ text_run: { content: "Registered Robots" } }] } }, // H1
{ block_type: 31, table: { property: { row_size: 1, column_size: 4 }, children: ["row1"] } } // Table placeholder (complex to create via API)
]);
// Note: Creating tables via API is complex. Using bullet list for simplicity.
return newDocToken;
}
function saveConfig(token) {
fs.writeFileSync(CONFIG_PATH, JSON.stringify({ doc_token: token }, null, 2));
}
// --- Helper: Append Block ---
async function appendBlock(docToken, accessToken, children) {
const res = await fetchWithAuth(`https://open.feishu.cn/open-apis/docx/v1/documents/${docToken}/blocks/${docToken}/children`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ children })
});
return res.json();
}
async function registerRobot(options) {
const accessToken = await getToken();
const docToken = options.docToken || await getRegistryDoc(accessToken);
const timestamp = new Date().toISOString();
const entryText = `🤖 **${options.name}** | Session: \`${options.sessionKey}\` | AppID: \`${options.appId}\` | Updated: ${timestamp}`;
// Append as bullet point
const children = [{
block_type: 12, // Bullet
bullet: {
elements: [
{ text_run: { content: entryText } }
]
}
}];
const res = await appendBlock(docToken, accessToken, children);
if (res.code !== 0) throw new Error(`Append failed: ${res.msg}`);
console.log(JSON.stringify({
status: "success",
doc_token: docToken,
entry: entryText,
url: `https://feishu.cn/docx/${docToken}`
}, null, 2));
}
async function listRobots(options) {
const accessToken = await getToken();
const docToken = options.docToken || (fs.existsSync(CONFIG_PATH) ? JSON.parse(fs.readFileSync(CONFIG_PATH)).doc_token : null);
if (!docToken) throw new Error("No registry doc found. Run register first.");
const res = await fetchWithAuth(`https://open.feishu.cn/open-apis/docx/v1/documents/${docToken}/blocks/${docToken}/children?page_size=500`);
const data = await res.json();
if (data.code !== 0) throw new Error(`List failed: ${data.msg}`);
const entries = [];
if (data.data?.items) {
for (const item of data.data.items) {
if (item.block_type === 12) { // Bullet
const text = item.bullet?.elements?.map(e => e.text_run?.content).join('') || '';
if (text.includes('| Session:')) {
entries.push(text);
}
}
}
}
console.log(JSON.stringify({ entries }, null, 2));
}
program
.command('register')
.option('--name <name>', 'Robot Name')
.option('--content <name>', 'Robot Name (alias)')
.option('--session-key <key>', 'Session Key')
.option('--app-id <id>', 'App ID')
.option('--doc-token <token>', 'Target Doc Token (optional)')
.action(async (options) => {
if (options.content && !options.name) options.name = options.content;
await registerRobot(options);
});
program
.command('list')
.option('--doc-token <token>', 'Target Doc Token (optional)')
.action(listRobots);
program.parse(process.argv);
{
"name": "feishu-robot-registry",
"version": "1.0.0",
"description": "Manage Robot Contact List in Feishu",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"commander": "^9.4.1"
}
}
Robot Registry Skill
Manage the "Robot Contact List" (机器人通讯录) in Feishu. Allows robots to self-register their session info for coordination.
Features
register: Adds current robot to the registry doc.list: Lists all registered robots.
Usage
node skills/feishu-robot-registry/index.js --action register --name "OpenClaw" --session "session_key_..."Related skills
FAQ
Where is the registry stored?
In a Feishu docx titled Robot Contact List; if none exists, the skill creates one and saves the doc_token in registry_config.json.
What metadata is recorded per robot?
Name, session key, app ID, and a timestamp.