mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-26 21:05:49 +00:00
feat: auto-remove reaction after message processing complete
- _add_reaction now returns reaction_id on success - Add _remove_reaction_sync and _remove_reaction methods - Remove reaction when stream ends to clear processing indicator - Store reaction_id in metadata for later removal
This commit is contained in:
parent
7e1ae3eab4
commit
bb70b6158c
@ -417,7 +417,7 @@ class FeishuChannel(BaseChannel):
|
|||||||
return True
|
return True
|
||||||
return self._is_bot_mentioned(message)
|
return self._is_bot_mentioned(message)
|
||||||
|
|
||||||
def _add_reaction_sync(self, message_id: str, emoji_type: str) -> None:
|
def _add_reaction_sync(self, message_id: str, emoji_type: str) -> str | None:
|
||||||
"""Sync helper for adding reaction (runs in thread pool)."""
|
"""Sync helper for adding reaction (runs in thread pool)."""
|
||||||
from lark_oapi.api.im.v1 import CreateMessageReactionRequest, CreateMessageReactionRequestBody, Emoji
|
from lark_oapi.api.im.v1 import CreateMessageReactionRequest, CreateMessageReactionRequestBody, Emoji
|
||||||
try:
|
try:
|
||||||
@ -433,22 +433,54 @@ class FeishuChannel(BaseChannel):
|
|||||||
|
|
||||||
if not response.success():
|
if not response.success():
|
||||||
logger.warning("Failed to add reaction: code={}, msg={}", response.code, response.msg)
|
logger.warning("Failed to add reaction: code={}, msg={}", response.code, response.msg)
|
||||||
|
return None
|
||||||
else:
|
else:
|
||||||
logger.debug("Added {} reaction to message {}", emoji_type, message_id)
|
logger.debug("Added {} reaction to message {}", emoji_type, message_id)
|
||||||
|
return response.data.reaction_id if response.data else None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("Error adding reaction: {}", e)
|
logger.warning("Error adding reaction: {}", e)
|
||||||
|
return None
|
||||||
|
|
||||||
async def _add_reaction(self, message_id: str, emoji_type: str = "THUMBSUP") -> None:
|
async def _add_reaction(self, message_id: str, emoji_type: str = "THUMBSUP") -> str | None:
|
||||||
"""
|
"""
|
||||||
Add a reaction emoji to a message (non-blocking).
|
Add a reaction emoji to a message (non-blocking).
|
||||||
|
|
||||||
Common emoji types: THUMBSUP, OK, EYES, DONE, OnIt, HEART
|
Common emoji types: THUMBSUP, OK, EYES, DONE, OnIt, HEART
|
||||||
"""
|
"""
|
||||||
if not self._client:
|
if not self._client:
|
||||||
|
return None
|
||||||
|
|
||||||
|
loop = asyncio.get_running_loop()
|
||||||
|
return await loop.run_in_executor(None, self._add_reaction_sync, message_id, emoji_type)
|
||||||
|
|
||||||
|
def _remove_reaction_sync(self, message_id: str, reaction_id: str) -> None:
|
||||||
|
"""Sync helper for removing reaction (runs in thread pool)."""
|
||||||
|
from lark_oapi.api.im.v1 import DeleteMessageReactionRequest
|
||||||
|
try:
|
||||||
|
request = DeleteMessageReactionRequest.builder() \
|
||||||
|
.message_id(message_id) \
|
||||||
|
.reaction_id(reaction_id) \
|
||||||
|
.build()
|
||||||
|
|
||||||
|
response = self._client.im.v1.message_reaction.delete(request)
|
||||||
|
if response.success():
|
||||||
|
logger.debug("Removed reaction {} from message {}", reaction_id, message_id)
|
||||||
|
else:
|
||||||
|
logger.debug("Failed to remove reaction: code={}, msg={}", response.code, response.msg)
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug("Error removing reaction: {}", e)
|
||||||
|
|
||||||
|
async def _remove_reaction(self, message_id: str, reaction_id: str) -> None:
|
||||||
|
"""
|
||||||
|
Remove a reaction emoji from a message (non-blocking).
|
||||||
|
|
||||||
|
Used to clear the "processing" indicator after bot replies.
|
||||||
|
"""
|
||||||
|
if not self._client or not reaction_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
await loop.run_in_executor(None, self._add_reaction_sync, message_id, emoji_type)
|
await loop.run_in_executor(None, self._remove_reaction_sync, message_id, reaction_id)
|
||||||
|
|
||||||
# Regex to match markdown tables (header + separator + data rows)
|
# Regex to match markdown tables (header + separator + data rows)
|
||||||
_TABLE_RE = re.compile(
|
_TABLE_RE = re.compile(
|
||||||
@ -1046,6 +1078,9 @@ class FeishuChannel(BaseChannel):
|
|||||||
|
|
||||||
# --- stream end: final update or fallback ---
|
# --- stream end: final update or fallback ---
|
||||||
if meta.get("_stream_end"):
|
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)
|
||||||
|
|
||||||
buf = self._stream_bufs.pop(chat_id, None)
|
buf = self._stream_bufs.pop(chat_id, None)
|
||||||
if not buf or not buf.text:
|
if not buf or not buf.text:
|
||||||
return
|
return
|
||||||
@ -1227,7 +1262,7 @@ class FeishuChannel(BaseChannel):
|
|||||||
return
|
return
|
||||||
|
|
||||||
# Add reaction
|
# Add reaction
|
||||||
await self._add_reaction(message_id, self.config.react_emoji)
|
reaction_id = await self._add_reaction(message_id, self.config.react_emoji)
|
||||||
|
|
||||||
# Parse content
|
# Parse content
|
||||||
content_parts = []
|
content_parts = []
|
||||||
@ -1305,6 +1340,7 @@ class FeishuChannel(BaseChannel):
|
|||||||
media=media_paths,
|
media=media_paths,
|
||||||
metadata={
|
metadata={
|
||||||
"message_id": message_id,
|
"message_id": message_id,
|
||||||
|
"reaction_id": reaction_id,
|
||||||
"chat_type": chat_type,
|
"chat_type": chat_type,
|
||||||
"msg_type": msg_type,
|
"msg_type": msg_type,
|
||||||
"parent_id": parent_id,
|
"parent_id": parent_id,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user