diff --git a/README.md b/README.md index a2ea20f8c..32d0c2681 100644 --- a/README.md +++ b/README.md @@ -558,6 +558,8 @@ Uses **WebSocket** long connection — no public IP required. "verificationToken": "", "allowFrom": ["ou_YOUR_OPEN_ID"], "groupPolicy": "mention", + "reactEmoji": "OnIt", + "doneEmoji": "DONE", "streaming": true } } @@ -568,6 +570,8 @@ Uses **WebSocket** long connection — no public IP required. > `encryptKey` and `verificationToken` are optional for Long Connection mode. > `allowFrom`: Add your open_id (find it in nanobot logs when you message the bot). Use `["*"]` to allow all users. > `groupPolicy`: `"mention"` (default — respond only when @mentioned), `"open"` (respond to all group messages). Private chats always respond. +> `reactEmoji`: Emoji for "processing" status (default: `OnIt`). See [available emojis](https://open.larkoffice.com/document/server-docs/im-v1/message-reaction/emojis-introduce). +> `doneEmoji`: Optional emoji for "completed" status (e.g., `DONE`, `OK`, `HEART`). When set, bot adds this reaction after removing `reactEmoji`. **3. Run** diff --git a/nanobot/channels/feishu.py b/nanobot/channels/feishu.py index bac14cb84..e18ed8b01 100644 --- a/nanobot/channels/feishu.py +++ b/nanobot/channels/feishu.py @@ -250,6 +250,7 @@ class FeishuConfig(Base): verification_token: str = "" allow_from: list[str] = Field(default_factory=list) react_emoji: str = "THUMBSUP" + done_emoji: str | None = None # Emoji to show when task is completed (e.g., "DONE", "OK") group_policy: Literal["open", "mention"] = "mention" reply_to_message: bool = False # If True, bot replies quote the user's original message streaming: bool = True @@ -1274,6 +1275,9 @@ class FeishuChannel(BaseChannel): if meta.get("_stream_end"): if (message_id := meta.get("message_id")) and (reaction_id := meta.get("reaction_id")): await self._remove_reaction(message_id, reaction_id) + # Add completion emoji if configured + if self.config.done_emoji and message_id: + await self._add_reaction(message_id, self.config.done_emoji) buf = self._stream_bufs.pop(chat_id, None) if not buf or not buf.text: