-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbot.py
147 lines (130 loc) · 6.2 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
import discord
import os
import dotenv
import asyncio
import math
# get secret token from .env file
dotenv.load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
admin_cmd_prefix = "m"
time_dict = {'s': 1, 'm': 60, 'h': 3600}
bound_channels = {"bot-commands"}
admin_roles = {"super admin", "artem", "nice person"}
msg_dict = {"mute": "muted", "blind": "blinded"}
admin_commands = {"admin": admin_roles, "channel": bound_channels}
admin_commands_txt = {"admin": "as an admin role", "channel": "as a bound channel"}
max_time = 86400
fail_text = "Could not execute command, try using ;help :slight_smile:"
# would really love to avoid having to do this
intents = discord.Intents.default()
intents.members = True
intents.message_content = True
client = discord.Client(intents = intents)
@client.event
async def on_ready():
print("Connected")
await client.change_presence(activity = discord.Game(name=";help"))
@client.event
async def on_message(message):
author = message.author
channel = message.channel
# help command
if not (author.bot or author.system) and message.content == ';help':
await author.send("""*User Commands (only work in work/spam channels):*
**;mute [time][s/m/h]**
Mutes you for a specified amount of time.
Only works in the work channel.\n
**;blind [time][s/m/h]**
Blinds you for a specified amount of time.
Only works in the work channel.\n
*Admin only commands:*
**;m clear [@user1] [@user2] ...**
Unmutes and unblinds specified users.\n
**;m admin [add/remove] [role name]**
Adds or removes the specified role as an admin role for this bot.\n
**;m admin display**
Displays the current admin roles.\n
**;m channel [add/remove] [channel name]**
Adds or removes the specified channel as a usable channel for the mute and blind commands\n
**;m channel display**
Displays the current bound channels.\n
**;m maxtime [set] [time][s/m/h]**
Sets the maximum mute/blind time.\n
**;m maxtime display**
Displays the current maximum mute/blind time.""")
return
if type(channel).__name__ == "TextChannel" and type(author).__name__ == "Member":
global max_time
is_admin = set([r.name for r in author.roles]).intersection(admin_roles) or author.permissions_in(channel).administrator
# other commands
if (channel.name in bound_channels or is_admin) and not (author.bot or author.system):
text = message.content
if text[0] == ";":
try:
#get role to add
roleDict = {"mute": discord.utils.get(message.guild.roles, name="muted"), "blind": discord.utils.get(message.guild.roles, name="blind")}
words = text[1:].split(" ")
# mute/blind command
if words[0] in roleDict.keys():
new_role = roleDict[words[0]]
time = getTimeVal(words[1])
if time != -1:
time = min(time, max_time)
await author.add_roles(new_role)
await channel.send(msg_dict[words[0]].title() + " " + author.name + " for " + getTimeStr(time))
await asyncio.sleep(time)
# fuckery needed to get updated roles after wait
if new_role in discord.utils.get(message.guild.members, id = author.id).roles:
await author.remove_roles(new_role)
await channel.send(author.name + " is back!")
return
else:
await channel.send(fail_text)
# admin-only commands
if is_admin:
if words[0] == "clear":
savedUsers = message.mentions
for u in savedUsers:
await u.remove_roles(roleDict["mute"])
await u.remove_roles(roleDict["blind"])
await channel.send(author.name + " force cleared " + "".join([(u.name + ", ") for u in savedUsers[:-1]]) + (" and " if len(savedUsers) > 1 else "") + savedUsers[-1].name)
return
if words[0] == admin_cmd_prefix and words[1] in admin_commands.keys():
if words[2] == "add":
admin_commands[words[1]].add(words[3])
await channel.send("Added " + words[3] + " " + admin_commands_txt[words[1]])
elif words[2] == "remove":
admin_commands[words[1]].remove(words[3])
await channel.send("Removed " + words[3] + " " + admin_commands_txt[words[1]])
elif words[2] == "display":
await channel.send(admin_commands[words[1]])
return
if words[0] == admin_cmd_prefix and words[1] == "maxtime":
if words[2] == "display":
await channel.send("Maximum time is " + getTimeStr(max_time))
elif words[2] == "set":
new_time = getTimeVal(words[3])
if new_time != -1:
max_time = new_time
await channel.send("Set max time to " + getTimeStr(new_time))
else:
await channel.send(fail_text)
except:
await channel.send(fail_text)
# converts time string into numerical value (-1 if it fails)
def getTimeVal(timeStr):
# need to improve this to read eg 1h30m or 1h 30m
if len(timeStr) > 1:
base = timeStr[:-1]
if base.isdigit():
multi = timeStr[-1]
time = time_dict.get(multi, 60) * int(base)
return time
return -1
# converts number of seconds into time string
def getTimeStr(time):
secs = time % 60
mins = math.floor(time/60) % 60
hrs = math.floor(time/3600)
return str(hrs) + "h " + str(mins) + "m " + str(secs) + "s"
client.run(TOKEN)