-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathbot.py
194 lines (153 loc) · 6.97 KB
/
bot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import shlex
import aiohttp
import uvloop
import asyncio
import discord
import logging
import argparse
import commands
import datetime
from cmd_manager import dispatcher
from config import config, help_text
from cmd_manager.bot_args import parser, HelpException, UnkownCommandException
from handle_messages import private_msg, delete_user_message, send_log_message
from commands.vote_command import ongoing_votes, Vote
from commands.role_system import emotes, role_handler
from cmd_manager.filters import EX_SERVER, EX_WELCOME_CHANNEL
from utils import prison_inmates, check_and_release
from modules.pixiv import handle_pixiv
from modules.timer import init as init_timer
uvloop.install()
loop = uvloop.new_event_loop()
asyncio.set_event_loop(loop)
intents = discord.Intents.all()
client = discord.Client(intents=intents)
commands.load_commands()
@client.event
async def on_ready():
logging.info(f'Logged in as\nUsername: {client.user.name}\nID: {client.user.id}\nAPI: {discord.__version__}')
await init_timer(client)
await client.change_presence(activity=discord.Game(name=config.MAIN.get("gameplayed", "Yuri is Love!")))
@client.event
async def on_message(message: discord.Message):
await handle_commands(message)
if message.author.id != client.user.id:
await handle_pixiv(message)
@client.event
async def on_message_edit(_: discord.Message, message: discord.Message):
await handle_commands(message)
@client.event
async def on_member_join(mem: discord.Member):
if mem.guild.id == EX_SERVER:
await send_log_message(client, mem, f"{mem.display_name} has joined the server")
channel = client.get_channel(EX_WELCOME_CHANNEL)
mention = await channel.send(f"<@!{mem.id}>")
text = help_text("bot_admin", "welcome_set")["member_join"]
member_mes = await channel.send(embed=discord.Embed(description=text, color=333333))
await asyncio.sleep(300)
await delete_user_message(member_mes)
await delete_user_message(mention)
@client.event
async def on_member_remove(mem: discord.Member):
if mem.guild.id == EX_SERVER:
await send_log_message(client, mem, f"{mem.display_name} has left the server", colour=discord.Colour.red())
@client.event
async def on_member_update(before: discord.Member, after: discord.Member):
if after.guild.id != EX_SERVER:
return
if before.nick != after.nick:
await send_log_message(client, after, f"{before.display_name if before.nick is None else before.nick} "
f"changed their nickname", f"New nickname is {after.nick}",
colour=discord.Colour.blue())
elif before.name != after.name:
await send_log_message(client, after, f"{before.name} changed their username", f"New username is {after.name}",
colour=discord.Colour.orange())
@client.event
async def on_raw_reaction_add(payload: discord.RawReactionActionEvent):
if payload.user_id in prison_inmates:
return
if payload.user_id == client.user.id:
return
if payload.guild_id == EX_SERVER and payload.channel_id == EX_WELCOME_CHANNEL:
if payload.emoji.name in emotes:
member = client.get_guild(payload.guild_id).get_member(payload.user_id)
await role_handler(member, payload.emoji.name, add=True)
else:
await handle_vote_reaction(payload, reaction_added=True)
@client.event
async def on_raw_reaction_remove(payload: discord.RawReactionActionEvent):
if payload.user_id in prison_inmates:
return
if payload.user_id == client.user.id:
return
if payload.guild_id == EX_SERVER and payload.channel_id == EX_WELCOME_CHANNEL:
if payload.emoji.name in emotes:
member = client.get_guild(payload.guild_id).get_member(payload.user_id)
await role_handler(member, payload.emoji.name, add=False)
else:
await handle_vote_reaction(payload, reaction_added=False)
async def handle_vote_reaction(payload: discord.RawReactionActionEvent, reaction_added: bool):
if payload.message_id in ongoing_votes:
user = client.get_user(payload.user_id)
channel = client.get_guild(payload.guild_id).get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
# prevent triggering the vote system for all emoji not used from the bot
for reaction in message.reactions:
if reaction.me and reaction.emoji == payload.emoji.name:
reaction_used = reaction
break
else:
return
await ongoing_votes[payload.message_id].store_vote(Vote(user, reaction_used, added=reaction_added))
async def handle_commands(message: discord.Message):
is_guild = isinstance(message.channel, discord.abc.GuildChannel)
if message.author.id == client.user.id: # own bot
return
if message.author.id in prison_inmates: # user in prison are not allowed to use any command
return
if is_guild and message.guild.id == EX_SERVER:
if message.channel.id == EX_WELCOME_CHANNEL:
await delete_user_message(message) # no return here
# prevent forwarding '>>' messages
if not message.content.startswith(">>") or len(message.content) == 2: # prevent forwarding '>>' messages
return
args_string = message.clean_content[2:]
if not is_guild and args_string.split(" ")[0] not in ["getnative", "grain", "help"]:
return await message.author.send("This command is not allowed in private chat, sorry :(")
if is_guild:
today = datetime.datetime.today().strftime("%a %d %b %H:%M:%S")
logging.info(f"Date: {today} User: {message.author} Server: {message.guild.name} "
f"Channel: {message.channel.name} Command: {message.content[:50]}")
arg_list = shlex.split(args_string)
try:
args = parser.parse_args(arg_list)
except ValueError as err:
return await private_msg(message, f"```\n{err}```")
except HelpException as err:
await delete_user_message(message)
return await private_msg(message, f"```\n{err}```")
except (UnkownCommandException, argparse.ArgumentError) as err:
if arg_list[0] not in dispatcher.commands:
return # not a valid command, so just ignore it
return await private_msg(message, f"```\n{err}```")
return await dispatcher.handle(args.command, client, message, args)
def main():
while True:
# start the prison release task
loop.create_task(check_and_release(client))
logging.info("Start discord run")
try:
# bot-Bot
client.run(config.MAIN.login_token)
# Test-Bot
# client.run(config.MAIN.test_token)
except aiohttp.ClientConnectorError:
continue
except KeyboardInterrupt:
return
except (InterruptedError, Exception):
logging.exception("done")
return
return
if __name__ == "__main__":
main()