fix: import errors

This commit is contained in:
Junyan Qin
2025-11-21 23:39:19 +08:00
parent 442c93193c
commit 2412e080b4
6 changed files with 96 additions and 101 deletions
+23 -24
View File
@@ -13,9 +13,9 @@ import httpx
from Crypto.Cipher import AES from Crypto.Cipher import AES
from quart import Quart, request, Response, jsonify from quart import Quart, request, Response, jsonify
from libs.wecom_ai_bot_api import wecombotevent from langbot.libs.wecom_ai_bot_api import wecombotevent
from libs.wecom_ai_bot_api.WXBizMsgCrypt3 import WXBizMsgCrypt from langbot.libs.wecom_ai_bot_api.WXBizMsgCrypt3 import WXBizMsgCrypt
from pkg.platform.logger import EventLogger from langbot.pkg.platform.logger import EventLogger
@dataclass @dataclass
@@ -224,10 +224,7 @@ class WecomBotClient:
# 只有在非统一模式下才注册独立路由 # 只有在非统一模式下才注册独立路由
if not self.unified_mode: if not self.unified_mode:
self.app.add_url_rule( self.app.add_url_rule(
'/callback/command', '/callback/command', 'handle_callback', self.handle_callback_request, methods=['POST', 'GET']
'handle_callback',
self.handle_callback_request,
methods=['POST', 'GET']
) )
self._message_handlers = { self._message_handlers = {
@@ -445,7 +442,7 @@ class WecomBotClient:
await self.logger.error("请求体中缺少 'encrypt' 字段") await self.logger.error("请求体中缺少 'encrypt' 字段")
return Response('Bad Request', status=400) return Response('Bad Request', status=400)
xml_post_data = f"<xml><Encrypt><![CDATA[{encrypted_msg}]]></Encrypt></xml>" xml_post_data = f'<xml><Encrypt><![CDATA[{encrypted_msg}]]></Encrypt></xml>'
ret, decrypted_xml = self.wxcpt.DecryptMsg(xml_post_data, msg_signature, timestamp, nonce) ret, decrypted_xml = self.wxcpt.DecryptMsg(xml_post_data, msg_signature, timestamp, nonce)
if ret != 0: if ret != 0:
await self.logger.error('解密失败') await self.logger.error('解密失败')
@@ -483,7 +480,7 @@ class WecomBotClient:
picurl = item.get('image', {}).get('url') picurl = item.get('image', {}).get('url')
if texts: if texts:
message_data['content'] = "".join(texts) # 拼接所有 text message_data['content'] = ''.join(texts) # 拼接所有 text
if picurl: if picurl:
base64 = await self.download_url_to_base64(picurl, self.EnCodingAESKey) base64 = await self.download_url_to_base64(picurl, self.EnCodingAESKey)
message_data['picurl'] = base64 # 只保留第一个 image message_data['picurl'] = base64 # 只保留第一个 image
@@ -491,7 +488,9 @@ class WecomBotClient:
# Extract user information # Extract user information
from_info = msg_json.get('from', {}) from_info = msg_json.get('from', {})
message_data['userid'] = from_info.get('userid', '') message_data['userid'] = from_info.get('userid', '')
message_data['username'] = from_info.get('alias', '') or from_info.get('name', '') or from_info.get('userid', '') message_data['username'] = (
from_info.get('alias', '') or from_info.get('name', '') or from_info.get('userid', '')
)
# Extract chat/group information # Extract chat/group information
if msg_json.get('chattype', '') == 'group': if msg_json.get('chattype', '') == 'group':
@@ -580,7 +579,7 @@ class WecomBotClient:
encrypted_bytes = response.content encrypted_bytes = response.content
aes_key = base64.b64decode(encoding_aes_key + "=") # base64 补齐 aes_key = base64.b64decode(encoding_aes_key + '=') # base64 补齐
iv = aes_key[:16] iv = aes_key[:16]
cipher = AES.new(aes_key, AES.MODE_CBC, iv) cipher = AES.new(aes_key, AES.MODE_CBC, iv)
@@ -589,22 +588,22 @@ class WecomBotClient:
pad_len = decrypted[-1] pad_len = decrypted[-1]
decrypted = decrypted[:-pad_len] decrypted = decrypted[:-pad_len]
if decrypted.startswith(b"\xff\xd8"): # JPEG if decrypted.startswith(b'\xff\xd8'): # JPEG
mime_type = "image/jpeg" mime_type = 'image/jpeg'
elif decrypted.startswith(b"\x89PNG"): # PNG elif decrypted.startswith(b'\x89PNG'): # PNG
mime_type = "image/png" mime_type = 'image/png'
elif decrypted.startswith((b"GIF87a", b"GIF89a")): # GIF elif decrypted.startswith((b'GIF87a', b'GIF89a')): # GIF
mime_type = "image/gif" mime_type = 'image/gif'
elif decrypted.startswith(b"BM"): # BMP elif decrypted.startswith(b'BM'): # BMP
mime_type = "image/bmp" mime_type = 'image/bmp'
elif decrypted.startswith(b"II*\x00") or decrypted.startswith(b"MM\x00*"): # TIFF elif decrypted.startswith(b'II*\x00') or decrypted.startswith(b'MM\x00*'): # TIFF
mime_type = "image/tiff" mime_type = 'image/tiff'
else: else:
mime_type = "application/octet-stream" mime_type = 'application/octet-stream'
# 转 base64 # 转 base64
base64_str = base64.b64encode(decrypted).decode("utf-8") base64_str = base64.b64encode(decrypted).decode('utf-8')
return f"data:{mime_type};base64,{base64_str}" return f'data:{mime_type};base64,{base64_str}'
async def run_task(self, host: str, port: int, *args, **kwargs): async def run_task(self, host: str, port: int, *args, **kwargs):
""" """
+3 -3
View File
@@ -58,11 +58,11 @@ class BotService:
if runtime_bot is not None: if runtime_bot is not None:
adapter_runtime_values['bot_account_id'] = runtime_bot.adapter.bot_account_id adapter_runtime_values['bot_account_id'] = runtime_bot.adapter.bot_account_id
if persistence_bot['adapter'] in ['wecom', 'wecombot', 'officialaccount', 'qqofficial', 'slack','wecomcs']: if persistence_bot['adapter'] in ['wecom', 'wecombot', 'officialaccount', 'qqofficial', 'slack', 'wecomcs']:
api_port = self.ap.instance_config.data['api']['port'] api_port = self.ap.instance_config.data['api']['port']
webhook_url = f"/bots/{bot_uuid}" webhook_url = f'/bots/{bot_uuid}'
adapter_runtime_values['webhook_url'] = webhook_url adapter_runtime_values['webhook_url'] = webhook_url
adapter_runtime_values['webhook_full_url'] = f"http://<Your-Server-IP>:{api_port}{webhook_url}" adapter_runtime_values['webhook_full_url'] = f'http://<Your-Server-IP>:{api_port}{webhook_url}'
else: else:
adapter_runtime_values['webhook_url'] = None adapter_runtime_values['webhook_url'] = None
adapter_runtime_values['webhook_full_url'] = None adapter_runtime_values['webhook_full_url'] = None
@@ -5,13 +5,12 @@ import traceback
import pydantic import pydantic
import datetime import datetime
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from libs.official_account_api.oaevent import OAEvent from langbot.libs.official_account_api.oaevent import OAEvent
from libs.official_account_api.api import OAClient from langbot.libs.official_account_api.api import OAClient
from libs.official_account_api.api import OAClientForLongerResponse from langbot.libs.official_account_api.api import OAClientForLongerResponse
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events import langbot_plugin.api.entities.builtin.platform.events as platform_events
from langbot_plugin.api.entities.builtin.command import errors as command_errors
from ..logger import EventLogger from ..logger import EventLogger
@@ -93,7 +92,6 @@ class OfficialAccountAdapter(abstract_platform_adapter.AbstractMessagePlatformAd
bot_account_id = config.get('AppID', '') bot_account_id = config.get('AppID', '')
super().__init__( super().__init__(
bot=bot, bot=bot,
bot_account_id=bot_account_id, bot_account_id=bot_account_id,
@@ -101,10 +99,6 @@ class OfficialAccountAdapter(abstract_platform_adapter.AbstractMessagePlatformAd
logger=logger, logger=logger,
) )
async def reply_message( async def reply_message(
self, self,
message_source: platform_events.FriendMessage, message_source: platform_events.FriendMessage,
@@ -165,19 +159,20 @@ class OfficialAccountAdapter(abstract_platform_adapter.AbstractMessagePlatformAd
if self.bot_uuid and hasattr(self.logger, 'ap'): if self.bot_uuid and hasattr(self.logger, 'ap'):
try: try:
api_port = self.logger.ap.instance_config.data['api']['port'] api_port = self.logger.ap.instance_config.data['api']['port']
webhook_url = f"http://127.0.0.1:{api_port}/bots/{self.bot_uuid}" webhook_url = f'http://127.0.0.1:{api_port}/bots/{self.bot_uuid}'
webhook_url_public = f"http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}" webhook_url_public = f'http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}'
await self.logger.info(f"微信公众号 Webhook 回调地址:") await self.logger.info('微信公众号 Webhook 回调地址:')
await self.logger.info(f" 本地地址: {webhook_url}") await self.logger.info(f' 本地地址: {webhook_url}')
await self.logger.info(f" 公网地址: {webhook_url_public}") await self.logger.info(f' 公网地址: {webhook_url_public}')
await self.logger.info(f"请在微信公众号后台配置此回调地址") await self.logger.info('请在微信公众号后台配置此回调地址')
except Exception as e: except Exception as e:
await self.logger.warning(f"无法生成 webhook URL: {e}") await self.logger.warning(f'无法生成 webhook URL: {e}')
async def keep_alive(): async def keep_alive():
while True: while True:
await asyncio.sleep(1) await asyncio.sleep(1)
await keep_alive() await keep_alive()
async def kill(self) -> bool: async def kill(self) -> bool:
@@ -192,5 +187,8 @@ class OfficialAccountAdapter(abstract_platform_adapter.AbstractMessagePlatformAd
): ):
return super().unregister_listener(event_type, callback) return super().unregister_listener(event_type, callback)
async def is_muted(self, group_id: str, ) -> bool: async def is_muted(
self,
group_id: str,
) -> bool:
pass pass
+11 -15
View File
@@ -9,9 +9,8 @@ import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platf
import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
from langbot_plugin.api.entities.builtin.command import errors as command_errors from langbot.libs.qq_official_api.api import QQOfficialClient
from libs.qq_official_api.api import QQOfficialClient from langbot.libs.qq_official_api.qqofficialevent import QQOfficialEvent
from libs.qq_official_api.qqofficialevent import QQOfficialEvent
from ...utils import image from ...utils import image
from ..logger import EventLogger from ..logger import EventLogger
@@ -141,11 +140,7 @@ class QQOfficialAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter
def __init__(self, config: dict, logger: EventLogger): def __init__(self, config: dict, logger: EventLogger):
bot = QQOfficialClient( bot = QQOfficialClient(
app_id=config['appid'], app_id=config['appid'], secret=config['secret'], token=config['token'], logger=logger, unified_mode=True
secret=config['secret'],
token=config['token'],
logger=logger,
unified_mode=True
) )
super().__init__( super().__init__(
@@ -256,19 +251,20 @@ class QQOfficialAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter
if self.bot_uuid and hasattr(self.logger, 'ap'): if self.bot_uuid and hasattr(self.logger, 'ap'):
try: try:
api_port = self.logger.ap.instance_config.data['api']['port'] api_port = self.logger.ap.instance_config.data['api']['port']
webhook_url = f"http://127.0.0.1:{api_port}/bots/{self.bot_uuid}" webhook_url = f'http://127.0.0.1:{api_port}/bots/{self.bot_uuid}'
webhook_url_public = f"http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}" webhook_url_public = f'http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}'
await self.logger.info(f"QQ 官方机器人 Webhook 回调地址:") await self.logger.info('QQ 官方机器人 Webhook 回调地址:')
await self.logger.info(f" 本地地址: {webhook_url}") await self.logger.info(f' 本地地址: {webhook_url}')
await self.logger.info(f" 公网地址: {webhook_url_public}") await self.logger.info(f' 公网地址: {webhook_url_public}')
await self.logger.info(f"请在 QQ 官方机器人后台配置此回调地址") await self.logger.info('请在 QQ 官方机器人后台配置此回调地址')
except Exception as e: except Exception as e:
await self.logger.warning(f"无法生成 webhook URL: {e}") await self.logger.warning(f'无法生成 webhook URL: {e}')
async def keep_alive(): async def keep_alive():
while True: while True:
await asyncio.sleep(1) await asyncio.sleep(1)
await keep_alive() await keep_alive()
async def kill(self) -> bool: async def kill(self) -> bool:
+11 -14
View File
@@ -5,10 +5,9 @@ import traceback
import datetime import datetime
from libs.wecom_api.api import WecomClient from langbot.libs.wecom_api.api import WecomClient
import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter
from libs.wecom_api.wecomevent import WecomEvent from langbot.libs.wecom_api.wecomevent import WecomEvent
from langbot_plugin.api.entities.builtin.command import errors as command_errors
from ...utils import image from ...utils import image
from ..logger import EventLogger from ..logger import EventLogger
import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.message as platform_message
@@ -159,12 +158,11 @@ class WecomAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
unified_mode=True, unified_mode=True,
) )
super().__init__( super().__init__(
config=config, config=config,
logger=logger, logger=logger,
bot=bot, bot=bot,
bot_account_id="", bot_account_id='',
) )
def set_bot_uuid(self, bot_uuid: str): def set_bot_uuid(self, bot_uuid: str):
@@ -189,7 +187,6 @@ class WecomAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
await self.bot.send_image(fixed_user_id, Wecom_event.agent_id, content['media_id']) await self.bot.send_image(fixed_user_id, Wecom_event.agent_id, content['media_id'])
async def send_message(self, target_type: str, target_id: str, message: platform_message.MessageChain): async def send_message(self, target_type: str, target_id: str, message: platform_message.MessageChain):
content_list = await WecomMessageConverter.yiri2target(message, self.bot) content_list = await WecomMessageConverter.yiri2target(message, self.bot)
parts = target_id.split('|') parts = target_id.split('|')
user_id = parts[0] user_id = parts[0]
@@ -235,23 +232,23 @@ class WecomAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
return await self.bot.handle_unified_webhook(request) return await self.bot.handle_unified_webhook(request)
async def run_async(self): async def run_async(self):
if self.bot_uuid and hasattr(self.logger, 'ap'): if self.bot_uuid and hasattr(self.logger, 'ap'):
try: try:
api_port = self.logger.ap.instance_config.data['api']['port'] api_port = self.logger.ap.instance_config.data['api']['port']
webhook_url = f"http://127.0.0.1:{api_port}/bots/{self.bot_uuid}" webhook_url = f'http://127.0.0.1:{api_port}/bots/{self.bot_uuid}'
webhook_url_public = f"http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}" webhook_url_public = f'http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}'
await self.logger.info(f"企业微信 Webhook 回调地址:") await self.logger.info('企业微信 Webhook 回调地址:')
await self.logger.info(f" 本地地址: {webhook_url}") await self.logger.info(f' 本地地址: {webhook_url}')
await self.logger.info(f" 公网地址: {webhook_url_public}") await self.logger.info(f' 公网地址: {webhook_url_public}')
await self.logger.info(f"请在企业微信后台配置此回调地址") await self.logger.info('请在企业微信后台配置此回调地址')
except Exception as e: except Exception as e:
await self.logger.warning(f"无法生成 webhook URL: {e}") await self.logger.warning(f'无法生成 webhook URL: {e}')
async def keep_alive(): async def keep_alive():
while True: while True:
await asyncio.sleep(1) await asyncio.sleep(1)
await keep_alive() await keep_alive()
async def kill(self) -> bool: async def kill(self) -> bool:
+29 -24
View File
@@ -8,11 +8,10 @@ import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platf
import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.message as platform_message
import langbot_plugin.api.entities.builtin.platform.events as platform_events import langbot_plugin.api.entities.builtin.platform.events as platform_events
import langbot_plugin.api.entities.builtin.platform.entities as platform_entities import langbot_plugin.api.entities.builtin.platform.entities as platform_entities
import pydantic from ..logger import EventLogger
from ..logger import EventLogger from langbot.libs.wecom_ai_bot_api.wecombotevent import WecomBotEvent
from libs.wecom_ai_bot_api.wecombotevent import WecomBotEvent from langbot.libs.wecom_ai_bot_api.api import WecomBotClient
from libs.wecom_ai_bot_api.api import WecomBotClient
from ...core import app
class WecomBotMessageConverter(abstract_platform_adapter.AbstractMessageConverter): class WecomBotMessageConverter(abstract_platform_adapter.AbstractMessageConverter):
@staticmethod @staticmethod
@@ -36,14 +35,14 @@ class WecomBotMessageConverter(abstract_platform_adapter.AbstractMessageConverte
return chain return chain
class WecomBotEventConverter(abstract_platform_adapter.AbstractEventConverter):
class WecomBotEventConverter(abstract_platform_adapter.AbstractEventConverter):
@staticmethod @staticmethod
async def yiri2target(event:platform_events.MessageEvent): async def yiri2target(event: platform_events.MessageEvent):
return event.source_platform_object return event.source_platform_object
@staticmethod @staticmethod
async def target2yiri(event:WecomBotEvent): async def target2yiri(event: WecomBotEvent):
message_chain = await WecomBotMessageConverter.target2yiri(event) message_chain = await WecomBotMessageConverter.target2yiri(event)
if event.type == 'single': if event.type == 'single':
return platform_events.FriendMessage( return platform_events.FriendMessage(
@@ -82,6 +81,7 @@ class WecomBotEventConverter(abstract_platform_adapter.AbstractEventConverter):
except Exception: except Exception:
print(traceback.format_exc()) print(traceback.format_exc())
class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
bot: WecomBotClient bot: WecomBotClient
bot_account_id: str bot_account_id: str
@@ -91,13 +91,11 @@ class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
bot_uuid: str = None bot_uuid: str = None
def __init__(self, config: dict, logger: EventLogger): def __init__(self, config: dict, logger: EventLogger):
required_keys = ['Token', 'EncodingAESKey', 'Corpid', 'BotId'] required_keys = ['Token', 'EncodingAESKey', 'Corpid', 'BotId']
missing_keys = [key for key in required_keys if key not in config] missing_keys = [key for key in required_keys if key not in config]
if missing_keys: if missing_keys:
raise Exception(f'WecomBot 缺少配置项: {missing_keys}') raise Exception(f'WecomBot 缺少配置项: {missing_keys}')
bot = WecomBotClient( bot = WecomBotClient(
Token=config['Token'], Token=config['Token'],
EnCodingAESKey=config['EncodingAESKey'], EnCodingAESKey=config['EncodingAESKey'],
@@ -114,9 +112,12 @@ class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
bot_account_id=bot_account_id, bot_account_id=bot_account_id,
) )
async def reply_message(
async def reply_message(self, message_source:platform_events.MessageEvent, message:platform_message.MessageChain,quote_origin: bool = False): self,
message_source: platform_events.MessageEvent,
message: platform_message.MessageChain,
quote_origin: bool = False,
):
content = await self.message_converter.yiri2target(message) content = await self.message_converter.yiri2target(message)
await self.bot.set_message(message_source.source_platform_object.message_id, content) await self.bot.set_message(message_source.source_platform_object.message_id, content)
@@ -170,7 +171,9 @@ class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
def register_listener( def register_listener(
self, self,
event_type: typing.Type[platform_events.Event], event_type: typing.Type[platform_events.Event],
callback: typing.Callable[[platform_events.Event, abstract_platform_adapter.AbstractMessagePlatformAdapter], None], callback: typing.Callable[
[platform_events.Event, abstract_platform_adapter.AbstractMessagePlatformAdapter], None
],
): ):
async def on_message(event: WecomBotEvent): async def on_message(event: WecomBotEvent):
try: try:
@@ -178,6 +181,7 @@ class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
except Exception: except Exception:
await self.logger.error(f'Error in wecombot callback: {traceback.format_exc()}') await self.logger.error(f'Error in wecombot callback: {traceback.format_exc()}')
print(traceback.format_exc()) print(traceback.format_exc())
try: try:
if event_type == platform_events.FriendMessage: if event_type == platform_events.FriendMessage:
self.bot.on_message('single')(on_message) self.bot.on_message('single')(on_message)
@@ -211,19 +215,20 @@ class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
if self.bot_uuid and hasattr(self.logger, 'ap'): if self.bot_uuid and hasattr(self.logger, 'ap'):
try: try:
api_port = self.logger.ap.instance_config.data['api']['port'] api_port = self.logger.ap.instance_config.data['api']['port']
webhook_url = f"http://127.0.0.1:{api_port}/bots/{self.bot_uuid}" webhook_url = f'http://127.0.0.1:{api_port}/bots/{self.bot_uuid}'
webhook_url_public = f"http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}" webhook_url_public = f'http://<Your-Public-IP>:{api_port}/bots/{self.bot_uuid}'
await self.logger.info(f"企业微信机器人 Webhook 回调地址:") await self.logger.info('企业微信机器人 Webhook 回调地址:')
await self.logger.info(f" 本地地址: {webhook_url}") await self.logger.info(f' 本地地址: {webhook_url}')
await self.logger.info(f" 公网地址: {webhook_url_public}") await self.logger.info(f' 公网地址: {webhook_url_public}')
await self.logger.info(f"请在企业微信后台配置此回调地址") await self.logger.info('请在企业微信后台配置此回调地址')
except Exception as e: except Exception as e:
await self.logger.warning(f"无法生成 webhook URL: {e}") await self.logger.warning(f'无法生成 webhook URL: {e}')
async def keep_alive(): async def keep_alive():
while True: while True:
await asyncio.sleep(1) await asyncio.sleep(1)
await keep_alive() await keep_alive()
async def kill(self) -> bool: async def kill(self) -> bool:
@@ -232,11 +237,11 @@ class WecomBotAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
async def unregister_listener( async def unregister_listener(
self, self,
event_type: type, event_type: type,
callback: typing.Callable[[platform_events.Event, abstract_platform_adapter.AbstractMessagePlatformAdapter], None], callback: typing.Callable[
[platform_events.Event, abstract_platform_adapter.AbstractMessagePlatformAdapter], None
],
): ):
return super().unregister_listener(event_type, callback) return super().unregister_listener(event_type, callback)
async def is_muted(self, group_id: int) -> bool: async def is_muted(self, group_id: int) -> bool:
pass pass