Experimental Discord bot written in Python
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import traceback
  2. from typing import Optional
  3. from discord import Intents
  4. from discord.ext import commands
  5. from config import CONFIG
  6. from rocketbot.cogs.basecog import BaseCog
  7. from rocketbot.cogsetting import CogSetting
  8. from rocketbot.utils import bot_log, dump_stacktrace
  9. class Rocketbot(commands.Bot):
  10. """
  11. Bot subclass
  12. """
  13. def __init__(self, command_prefix, **kwargs):
  14. super().__init__(command_prefix, **kwargs)
  15. self.__commands_set_up = False
  16. async def on_command_error(self, context: commands.Context, exception: BaseException) -> None:
  17. bot_log(None, None, f'Command error')
  18. dump_stacktrace(exception)
  19. if context.guild is None or \
  20. context.message.channel is None or \
  21. context.message.author.bot:
  22. return
  23. if not context.message.channel.permissions_for(context.message.author).ban_members:
  24. # Don't tell non-mods about errors
  25. return
  26. if isinstance(exception, (commands.errors.CommandError, )):
  27. # Reply with the error message for ordinary command errors
  28. await context.message.reply(
  29. f'{CONFIG["failure_emoji"]} {exception}',
  30. mention_author=False)
  31. return
  32. # Stack trace everything else
  33. async def on_error(self, event_method, args=None, kwargs=None):
  34. bot_log(None, None, 'Event caused error\n' + \
  35. f' event method: {event_method}' + \
  36. f' event args: {args}' + \
  37. f' event kwargs: {kwargs}' + \
  38. traceback.format_exc())
  39. async def on_ready(self):
  40. if not self.__commands_set_up:
  41. await self.__set_up_commands()
  42. bot_log(None, None, 'Bot done initializing')
  43. print('----------------------------------------------------------')
  44. async def __set_up_commands(self):
  45. if self.__commands_set_up:
  46. return
  47. self.__commands_set_up = True
  48. for cog in self.cogs.values():
  49. if isinstance(cog, BaseCog):
  50. bcog: BaseCog = cog
  51. if len(bcog.settings) > 0:
  52. CogSetting.set_up_all(bcog, self, bcog.settings)
  53. try:
  54. synced_commands = await self.tree.sync()
  55. for command in synced_commands:
  56. bot_log(None, None, f'Synced command: /{command.name}')
  57. except Exception as e:
  58. dump_stacktrace(e)
  59. # Current active bot instance
  60. rocketbot: Optional[Rocketbot] = None
  61. def __create_bot():
  62. global rocketbot
  63. if rocketbot is not None:
  64. return
  65. bot_log(None, None, 'Creating bot...')
  66. intents = Intents.default()
  67. intents.messages = True # pylint: disable=assigning-non-slot
  68. intents.message_content = True # pylint: disable=assigning-non-slot
  69. intents.members = True # pylint: disable=assigning-non-slot
  70. intents.presences = True
  71. rocketbot = Rocketbot(command_prefix=CONFIG['command_prefix'], intents=intents)
  72. __create_bot()
  73. from rocketbot.cogs.autokickcog import AutoKickCog
  74. from rocketbot.cogs.configcog import ConfigCog
  75. from rocketbot.cogs.crosspostcog import CrossPostCog
  76. from rocketbot.cogs.generalcog import GeneralCog
  77. from rocketbot.cogs.joinraidcog import JoinRaidCog
  78. from rocketbot.cogs.logcog import LoggingCog
  79. from rocketbot.cogs.patterncog import PatternCog
  80. from rocketbot.cogs.urlspamcog import URLSpamCog
  81. from rocketbot.cogs.usernamecog import UsernamePatternCog
  82. async def start_bot():
  83. bot_log(None, None, 'Bot initializing...')
  84. bot_log(None, None, f"Type {CONFIG['command_prefix']}help in Discord for available commands.")
  85. # Core
  86. await rocketbot.add_cog(GeneralCog(rocketbot))
  87. await rocketbot.add_cog(ConfigCog(rocketbot))
  88. # Optional
  89. await rocketbot.add_cog(AutoKickCog(rocketbot))
  90. await rocketbot.add_cog(CrossPostCog(rocketbot))
  91. await rocketbot.add_cog(JoinRaidCog(rocketbot))
  92. await rocketbot.add_cog(LoggingCog(rocketbot))
  93. await rocketbot.add_cog(PatternCog(rocketbot))
  94. await rocketbot.add_cog(URLSpamCog(rocketbot))
  95. await rocketbot.add_cog(UsernamePatternCog(rocketbot))
  96. await rocketbot.start(CONFIG['client_token'], reconnect=True)
  97. print('\nBot aborted')