Add line-specific eslint-disable-next-line comments for SDK type casts and union type issues, rather than file-level disables. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
79 lines
2.2 KiB
TypeScript
79 lines
2.2 KiB
TypeScript
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 },
|
|
},
|
|
});
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK response type
|
|
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}`);
|
|
}
|
|
}
|