feat(feishu): replace built-in SDK with community plugin

Replace the built-in Feishu SDK with the community-maintained
clawdbot-feishu plugin by @m1heng.

Changes:
- Remove src/feishu/ directory (19 files)
- Remove src/channels/plugins/outbound/feishu.ts
- Remove src/channels/plugins/normalize/feishu.ts
- Remove src/config/types.feishu.ts
- Remove feishu exports from plugin-sdk/index.ts
- Remove FeishuConfig from types.channels.ts

New features in community plugin:
- Document tools (read/create/edit Feishu docs)
- Wiki tools (navigate/manage knowledge base)
- Drive tools (folder/file management)
- Bitable tools (read/write table records)
- Permission tools (collaborator management)
- Emoji reactions support
- Typing indicators
- Rich media support (bidirectional image/file transfer)
- @mention handling
- Skills for feishu-doc, feishu-wiki, feishu-drive, feishu-perm

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Yifeng Wang
2026-02-05 18:26:05 +08:00
committed by cpojer
parent 02842bef91
commit 2267d58afc
66 changed files with 5702 additions and 4486 deletions

View File

@@ -0,0 +1,73 @@
import type { ClawdbotConfig } from "openclaw/plugin-sdk";
import type { FeishuConfig } from "./types.js";
import { createFeishuClient } from "./client.js";
// Feishu emoji types for typing indicator
// See: https://open.feishu.cn/document/server-docs/im-v1/message-reaction/emojis-introduce
// Full list: https://github.com/go-lark/lark/blob/main/emoji.go
const TYPING_EMOJI = "Typing"; // Typing indicator emoji
export type TypingIndicatorState = {
messageId: string;
reactionId: string | null;
};
/**
* Add a typing indicator (reaction) to a message
*/
export async function addTypingIndicator(params: {
cfg: ClawdbotConfig;
messageId: string;
}): Promise<TypingIndicatorState> {
const { cfg, messageId } = params;
const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
if (!feishuCfg) {
return { messageId, reactionId: null };
}
const client = createFeishuClient(feishuCfg);
try {
const response = await client.im.messageReaction.create({
path: { message_id: messageId },
data: {
reaction_type: { emoji_type: TYPING_EMOJI },
},
});
const reactionId = (response as any)?.data?.reaction_id ?? null;
return { messageId, reactionId };
} catch (err) {
// Silently fail - typing indicator is not critical
console.log(`[feishu] failed to add typing indicator: ${err}`);
return { messageId, reactionId: null };
}
}
/**
* Remove a typing indicator (reaction) from a message
*/
export async function removeTypingIndicator(params: {
cfg: ClawdbotConfig;
state: TypingIndicatorState;
}): Promise<void> {
const { cfg, state } = params;
if (!state.reactionId) return;
const feishuCfg = cfg.channels?.feishu as FeishuConfig | undefined;
if (!feishuCfg) return;
const client = createFeishuClient(feishuCfg);
try {
await client.im.messageReaction.delete({
path: {
message_id: state.messageId,
reaction_id: state.reactionId,
},
});
} catch (err) {
// Silently fail - cleanup is not critical
console.log(`[feishu] failed to remove typing indicator: ${err}`);
}
}