-
Notifications
You must be signed in to change notification settings - Fork 0
/
emojilang.py
162 lines (133 loc) · 5.76 KB
/
emojilang.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
import asyncio
import regex
import discord
from discord import Member
from decouple import config, Csv
import emoji
CONFIG = {
"BOT_TOKEN": config("BOT_TOKEN", default=""),
"CHANNEL_IDS": config("CHANNEL_IDS", default="", cast=Csv(int))
}
client = discord.Client()
emoji_regex = regex.compile(r"^[{}\s]+$".format(emoji.get_emoji_regexp().pattern), regex.UNICODE)
regional_indicators_regex = regex.compile(
u"([^\U0001F1E6-\U0001F1FF]|^)[\U0001F1E6-\U0001F1FF]([^\U0001F1E6-\U0001F1FF]|$)",
regex.UNICODE
)
flags_regex = regex.compile(u"([\U0001F1E6-\U0001F1FF][\U0001F1E6-\U0001F1FF])", regex.UNICODE)
mention_regex = regex.compile(r"<@[!\d]+>")
FORBIDDEN_EMOJIS = ["\U0001F170", "\U0001F171"]
FLAGS_EMOJIS = [
v.replace(" ", "")
for k, v in emoji.EMOJI_UNICODE.items()
if all([0x1F1E6 <= ord(x) <= 0x1F1FF or x == " " for x in v])
]
def num_to_emoji(n):
assert type(n) is int
numbers = [":zero:", ":one:", ":two:", ":three:", ":four:", ":five:", ":six:", ":seven:", ":eight:", ":nine:"]
n = str(n)
s = ""
for x in n:
s += numbers[int(x)]
return s
def is_emojilang(s):
# Strip mentions from the message
original_content = s.content
clean_content = mention_regex.sub("", s.content).strip()
print(clean_content)
print([(ord(x), hex(ord(x))) for x in clean_content])
# Mention only message
if not clean_content and original_content.strip():
return True
# Regexes check
if not clean_content or not emoji_regex.match(clean_content) or regional_indicators_regex.search(clean_content):
return False
# Forbidden emojis
for x in clean_content:
if x in FORBIDDEN_EMOJIS:
return False
# Flags check
for flag in flags_regex.findall(clean_content):
if flag.strip() not in FLAGS_EMOJIS:
return False
# All fine
return True
@client.event
async def on_ready():
# Just for logging purposes
print("=> Logged in as {} [{}]. Ready!".format(
client.user.name, client.user.id
))
@client.event
async def on_message(message):
# Ignore PMs, messages in different channels and our messages
if message.server is None or int(message.channel.id) not in CONFIG["CHANNEL_IDS"] or message.author == client.user:
return
# Post rules if needed
if type(message.author) is Member and message.author.server_permissions.administrator:
if message.content.startswith(";emoji"):
await client.send_message(message.channel, "**:wave: Welcome to the :joy: :speaking_head: channel!**\n\n"
"_The_ :person_with_blond_hair:_kind has been :thinking:_ "
"_a_ :question: _for ages..._\n"
"**Is it possible to :person_with_blond_hair::speech_balloon:"
":speech_left::person_with_blond_hair: only by using :joy::joy:?**\n"
"For the sake of :alembic::nerd:, I'm here to try to :bulb:!\n"
"In this :hash:, you'll be able to :person_with_blond_hair:"
":speech_balloon::speech_left::person_with_blond_hair: "
"only by :joy::joy:.\n\n"
"__**All :speech_balloon: containing :abcd:, :one: :two:, :symbols: "
"will get :put_litter_in_its_place:! :angry::anger:**__"
"\n**Have fun! :smile:**")
elif message.content.startswith(";clean"):
# Delete trigger message immediately
await client.delete_message(message)
bot_response = await client.send_message(
message.channel, ":robot: :timer: :envelope: :mag: :five::zero::zero:"
)
try:
counter = 0
async for log in client.logs_from(message.channel, limit=500):
if log.author != client.user:
counter += 1
if not is_emojilang(log):
await client.delete_message(log)
except:
await client.edit_message(bot_response, ":warning: :frowning2: :envelope: :mag:")
raise
await client.edit_message(bot_response, ":grimacing: :ok_hand: :envelope: :mag: :point_right: {}".format(
num_to_emoji(counter)
))
await asyncio.sleep(5)
await client.delete_message(bot_response)
return
# Strip mentions from the message
if not is_emojilang(message):
await client.delete_message(message)
print("=> Deleted message {}".format(message.content))
@client.event
async def on_message_edit(before, after):
# TODO: decorator
# Ignore PMs, messages in different channels and our messages
if before.server is None or int(before.channel.id) not in CONFIG["CHANNEL_IDS"] or before.author == client.user:
return
# Run emoji check again
if not is_emojilang(after):
await client.delete_message(after)
print("=> Somebody tried to be akerino `{}` => `{}`".format(before.content, after.content))
def main():
print("""\033[92m ∩
\\
/ )
⊂\_/ ̄ ̄ ̄ /
\_/ ° ͜ʖ °(
) /⌒\
/ ___/⌒\⊃
( /
\\
U
E M O J I S ! ! !
Made by Nyo\033[0m\n""")
print("=> Starting Discord Bot")
client.run(CONFIG["BOT_TOKEN"])
if __name__ == "__main__":
main()