integrations.discord.events.handler
integrations/discord/events/handler.py
1""" 2integrations/discord/events/handler.py 3""" 4 5import logging 6import os 7import sys 8from typing import TYPE_CHECKING 9 10import integrations.discord.events.audioop as _audioop 11import libs.dispatcher 12from libs.types import MessageStatus 13 14if TYPE_CHECKING: 15 from integrations.discord.adapter import ServiceAdapter 16 17 18def main(adapter: "ServiceAdapter") -> None: 19 """ 20 メイン処理 21 22 Args: 23 adapter (ServiceAdapter): アダプタインターフェース 24 25 Raises: 26 ModuleNotFoundError: ライブラリ未インストール 27 28 """ 29 try: 30 sys.modules["audioop"] = _audioop 31 import discord 32 from discord.ext import commands 33 except ModuleNotFoundError as err: 34 raise ModuleNotFoundError(err.msg) from None 35 36 # ログレベル変更 37 for name in logging.Logger.manager.loggerDict: 38 if name.startswith(("discord_", "discord")): 39 logging.getLogger(name).setLevel(logging.WARNING) 40 41 intents = discord.Intents.default() 42 intents.message_content = True 43 intents.messages = True 44 bot = commands.Bot(intents=intents) 45 adapter.api.bot = bot 46 47 @bot.event 48 async def on_ready() -> None: 49 logging.info("login: %s", bot.user) 50 adapter.conf.bot_name = bot.user 51 52 @bot.event 53 async def on_message(message: discord.Message) -> None: 54 if message.author.bot: 55 return 56 57 adapter.api.response = message 58 59 m = adapter.parser() 60 m.data.status = MessageStatus.APPEND 61 m.parser(message) 62 63 libs.dispatcher.by_keyword(m) 64 65 @bot.event 66 async def on_raw_message_edit(payload: discord.RawMessageUpdateEvent) -> None: 67 channel = bot.get_channel(payload.channel_id) 68 if channel is None or not isinstance(channel, discord.TextChannel): 69 return 70 71 try: 72 message = await channel.fetch_message(payload.message_id) 73 except discord.NotFound: 74 return # メッセージが既に削除されていた場合 75 except discord.Forbidden: 76 return # 権限不足 77 except discord.HTTPException: 78 return # Discord API 側の一時的エラーなど 79 80 assert isinstance(message, discord.Message) 81 82 if message.author.bot: 83 return 84 85 adapter.api.response = message 86 87 m = adapter.parser() 88 m.data.status = MessageStatus.CHANGED 89 m.parser(message) 90 91 libs.dispatcher.by_keyword(m) 92 93 @bot.event 94 async def on_message_delete(message: discord.Message) -> None: 95 if message.author.bot: 96 return 97 98 adapter.api.response = message 99 100 m = adapter.parser() 101 m.data.status = MessageStatus.DELETED 102 m.parser(message) 103 104 libs.dispatcher.by_keyword(m) 105 106 @bot.slash_command(name=adapter.conf.slash_command) # type: ignore[no-untyped-call, untyped-decorator] 107 async def slash_command(ctx: discord.ApplicationContext, command: str) -> None: 108 adapter.api.response = ctx 109 110 m = adapter.parser() 111 m.status.command_flg = True 112 m.data.text = command 113 m.data.status = MessageStatus.APPEND 114 m.data.thread_ts = "0" 115 116 libs.dispatcher.by_keyword(m) 117 118 bot.run(token=os.environ["DISCORD_TOKEN"])
19def main(adapter: "ServiceAdapter") -> None: 20 """ 21 メイン処理 22 23 Args: 24 adapter (ServiceAdapter): アダプタインターフェース 25 26 Raises: 27 ModuleNotFoundError: ライブラリ未インストール 28 29 """ 30 try: 31 sys.modules["audioop"] = _audioop 32 import discord 33 from discord.ext import commands 34 except ModuleNotFoundError as err: 35 raise ModuleNotFoundError(err.msg) from None 36 37 # ログレベル変更 38 for name in logging.Logger.manager.loggerDict: 39 if name.startswith(("discord_", "discord")): 40 logging.getLogger(name).setLevel(logging.WARNING) 41 42 intents = discord.Intents.default() 43 intents.message_content = True 44 intents.messages = True 45 bot = commands.Bot(intents=intents) 46 adapter.api.bot = bot 47 48 @bot.event 49 async def on_ready() -> None: 50 logging.info("login: %s", bot.user) 51 adapter.conf.bot_name = bot.user 52 53 @bot.event 54 async def on_message(message: discord.Message) -> None: 55 if message.author.bot: 56 return 57 58 adapter.api.response = message 59 60 m = adapter.parser() 61 m.data.status = MessageStatus.APPEND 62 m.parser(message) 63 64 libs.dispatcher.by_keyword(m) 65 66 @bot.event 67 async def on_raw_message_edit(payload: discord.RawMessageUpdateEvent) -> None: 68 channel = bot.get_channel(payload.channel_id) 69 if channel is None or not isinstance(channel, discord.TextChannel): 70 return 71 72 try: 73 message = await channel.fetch_message(payload.message_id) 74 except discord.NotFound: 75 return # メッセージが既に削除されていた場合 76 except discord.Forbidden: 77 return # 権限不足 78 except discord.HTTPException: 79 return # Discord API 側の一時的エラーなど 80 81 assert isinstance(message, discord.Message) 82 83 if message.author.bot: 84 return 85 86 adapter.api.response = message 87 88 m = adapter.parser() 89 m.data.status = MessageStatus.CHANGED 90 m.parser(message) 91 92 libs.dispatcher.by_keyword(m) 93 94 @bot.event 95 async def on_message_delete(message: discord.Message) -> None: 96 if message.author.bot: 97 return 98 99 adapter.api.response = message 100 101 m = adapter.parser() 102 m.data.status = MessageStatus.DELETED 103 m.parser(message) 104 105 libs.dispatcher.by_keyword(m) 106 107 @bot.slash_command(name=adapter.conf.slash_command) # type: ignore[no-untyped-call, untyped-decorator] 108 async def slash_command(ctx: discord.ApplicationContext, command: str) -> None: 109 adapter.api.response = ctx 110 111 m = adapter.parser() 112 m.status.command_flg = True 113 m.data.text = command 114 m.data.status = MessageStatus.APPEND 115 m.data.thread_ts = "0" 116 117 libs.dispatcher.by_keyword(m) 118 119 bot.run(token=os.environ["DISCORD_TOKEN"])
メイン処理
Arguments:
- adapter (ServiceAdapter): アダプタインターフェース
Raises:
- ModuleNotFoundError: ライブラリ未インストール