Feat/complete adapter features (#1849)

* feat: add voice and file supports for wecom

* feat: add   and  in query variables

* feat: supports for lark recv file message

* feat: kook recv voice msg

* feat: supports for Voice and File in discord

* chore: remove debug msg

* perf: remove unnecessary bot logs

* feat: implement bot log filtering and per label color (#1839)

* feat: add sender_name and group_name in query variables
This commit is contained in:
Junyan Qin (Chin)
2025-12-06 21:11:01 +08:00
committed by GitHub
parent daf56e5dc2
commit 6421a6f5cb
22 changed files with 464 additions and 145 deletions
+13 -12
View File
@@ -137,7 +137,11 @@ class KookMessageConverter(abstract_platform_adapter.AbstractMessageConverter):
# For file messages, content is typically the file URL
attachments = extra.get('attachments', {})
file_name = attachments.get('name', 'file')
components.append(platform_message.Plain(text=f'[File: {file_name}]'))
components.append(platform_message.File(url=content, name=file_name))
elif msg_type == 8: # Audio message
# For audio messages, content is typically the audio URL
attachments = extra.get('attachments', {})
components.append(platform_message.Voice(url=content))
elif msg_type == 9: # KMarkdown message
# Note: content is already stripped of mention patterns above
if content:
@@ -317,9 +321,6 @@ class KookAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
data = await response.json()
if data.get('code') == 0:
user_info = data['data']
await self.logger.info(
f'Retrieved bot user info: {user_info.get("username")} (ID: {user_info.get("id")})'
)
return user_info
else:
raise Exception(f'Failed to get bot user info: {data.get("message")}')
@@ -343,11 +344,10 @@ class KookAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
# Ignore messages from bot itself to prevent infinite loops
if self.bot_account_id and str(author_id) == self.bot_account_id:
await self.logger.debug(f'Ignoring message from bot itself (author_id: {author_id})')
return
# Only process text messages (type 1, 2, 4, 9, 10) in GROUP or PERSON channels
if event_type in [1, 2, 4, 9, 10] and channel_type in ['GROUP', 'PERSON']:
# Only process text messages (type 1, 2, 4, 8, 9, 10) in GROUP or PERSON channels
if event_type in [1, 2, 4, 8, 9, 10] and channel_type in ['GROUP', 'PERSON']:
try:
# Convert to LangBot event
lb_event = await self.event_converter.target2yiri(data, self.bot_account_id)
@@ -377,7 +377,6 @@ class KookAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
'sn': self.current_sn,
}
await self.ws.send(json.dumps(ping_msg))
await self.logger.debug(f'Sent PING with sn={self.current_sn}')
except Exception:
# Connection closed or send failed, exit loop
break
@@ -398,10 +397,9 @@ class KookAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
self.gateway_url = await self._get_gateway_url()
# Connect to WebSocket
await self.logger.info(f'Connecting to KOOK WebSocket: {self.gateway_url}')
async with websockets.connect(self.gateway_url) as ws:
await self.logger.info(f'Connected to KOOK WebSocket: {self.gateway_url}')
self.ws = ws
await self.logger.info('KOOK WebSocket connected')
# Start heartbeat
self.heartbeat_task = asyncio.create_task(self._heartbeat_loop())
@@ -452,10 +450,11 @@ class KookAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
elif signal == 3: # PONG
await self._handle_pong(msg_data.get('d', {}))
elif signal == 5: # RECONNECT
await self.logger.info('Received RECONNECT signal')
# await self.logger.info('Received RECONNECT signal')
break # Break to reconnect
elif signal == 6: # RESUME ACK
await self.logger.info('Resume successful')
# await self.logger.info('Resume successful')
pass
except json.JSONDecodeError:
await self.logger.error(f'Failed to parse message: {message}')
except Exception as e:
@@ -568,6 +567,8 @@ class KookAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
if quote_origin and msg_id:
payload['quote'] = msg_id
payload['reply_msg_id'] = msg_id
headers = {
'Authorization': f'Bot {self.config["token"]}',
'Content-Type': 'application/json',