Files
LangBot/src/langbot/pkg/platform/adapters/qqofficial/event_converter.py
T
2026-07-19 22:40:16 +08:00

117 lines
5.1 KiB
Python

from __future__ import annotations
import datetime
import time
import typing
from langbot.libs.qq_official_api.qqofficialevent import QQOfficialEvent
from langbot.pkg.platform.adapters.qqofficial.message_converter import QQOfficialMessageConverter
from langbot.pkg.platform.adapters.qqofficial.types import ADAPTER_NAME
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from langbot_plugin.api.entities.builtin.platform import entities as platform_entities
from langbot_plugin.api.entities.builtin.platform import events as platform_events
class QQOfficialEventConverter(abstract_platform_adapter.AbstractEventConverter):
@staticmethod
async def yiri2target(event: platform_events.Event) -> typing.Any:
return getattr(event, 'source_platform_object', None)
async def target2legacy(self, event: QQOfficialEvent) -> platform_events.FriendMessage | platform_events.GroupMessage | None:
eba_event = await self.target2yiri(event)
if not isinstance(eba_event, platform_events.MessageReceivedEvent):
return None
if eba_event.chat_type == platform_entities.ChatType.PRIVATE:
return platform_events.FriendMessage(
sender=platform_entities.Friend(
id=eba_event.sender.id,
nickname=eba_event.sender.nickname,
remark='',
),
message_chain=eba_event.message_chain,
time=eba_event.timestamp,
source_platform_object=event,
)
return platform_events.GroupMessage(
sender=platform_entities.GroupMember(
id=eba_event.sender.id,
member_name=eba_event.sender.nickname,
permission='MEMBER',
group=platform_entities.Group(
id=eba_event.group.id if eba_event.group else eba_event.chat_id,
name=eba_event.group.name if eba_event.group else '',
permission=platform_entities.Permission.Member,
),
special_title='',
),
message_chain=eba_event.message_chain,
time=eba_event.timestamp,
source_platform_object=event,
)
async def target2yiri(self, event: QQOfficialEvent) -> platform_events.Event:
if event.t in {'C2C_MESSAGE_CREATE', 'DIRECT_MESSAGE_CREATE', 'GROUP_AT_MESSAGE_CREATE', 'AT_MESSAGE_CREATE'}:
return await self.message_to_eba(event)
return self.platform_specific(event, f'qqofficial.{event.t or "unknown"}')
async def message_to_eba(self, event: QQOfficialEvent) -> platform_events.MessageReceivedEvent:
timestamp = _timestamp_value(event.timestamp)
sender = platform_entities.User(
id=self._sender_id(event),
nickname=event.username or self._sender_id(event),
)
chat_type = platform_entities.ChatType.PRIVATE
chat_id = self._private_chat_id(event)
group = None
if event.t in {'GROUP_AT_MESSAGE_CREATE', 'AT_MESSAGE_CREATE'}:
chat_type = platform_entities.ChatType.GROUP
chat_id = event.channel_id if event.t == 'AT_MESSAGE_CREATE' else event.group_openid
chat_id = chat_id or event.group_openid or event.channel_id or ''
group = platform_entities.UserGroup(id=str(chat_id), name=str(chat_id))
return platform_events.MessageReceivedEvent(
type='message.received',
adapter_name=ADAPTER_NAME,
message_id=event.d_id or event.id or '',
message_chain=await QQOfficialMessageConverter.target2yiri(event),
sender=sender,
chat_type=chat_type,
chat_id=chat_id or '',
group=group,
timestamp=timestamp,
source_platform_object=event,
)
@staticmethod
def _sender_id(event: QQOfficialEvent) -> str:
member_openid = event.member_openid or event.get('member_openid', '')
if event.t in {'GROUP_AT_MESSAGE_CREATE', 'AT_MESSAGE_CREATE'}:
return member_openid or event.user_openid or event.d_author_id or ''
return event.user_openid or member_openid or event.d_author_id or event.guild_id or event.group_openid or ''
@staticmethod
def _private_chat_id(event: QQOfficialEvent) -> str:
if event.t == 'DIRECT_MESSAGE_CREATE':
return event.guild_id or event.user_openid or ''
return event.user_openid or event.guild_id or ''
@staticmethod
def platform_specific(event: QQOfficialEvent, action: str) -> platform_events.PlatformSpecificEvent:
return platform_events.PlatformSpecificEvent(
type='platform.specific',
adapter_name=ADAPTER_NAME,
action=action,
data=dict(event),
timestamp=_timestamp_value(event.timestamp),
source_platform_object=event,
)
def _timestamp_value(value: str) -> float:
if not value:
return time.time()
try:
return float(datetime.datetime.strptime(value, '%Y-%m-%dT%H:%M:%S%z').timestamp())
except (TypeError, ValueError):
return time.time()