-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathbot.py
More file actions
326 lines (264 loc) · 12.3 KB
/
Copy pathbot.py
File metadata and controls
326 lines (264 loc) · 12.3 KB
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# bot.py
import asyncio
import logging
import os # for importing env vars for the bot to use
import random
import sys
from datetime import datetime, timedelta, timezone
from pathlib import Path
import custom_commands
from twitchio import Channel, Client, User
from twitchio.ext import commands, routines, eventsub
from utils import auto_so, random_bot_reply, random_reply, play_alert
from db import init_channels, add_channel, leave_channel, get_channels_info, update_name
class LeixBot(commands.Bot):
def __init__(self):
super().__init__(
token=os.environ['ACCESS_TOKEN'],
prefix=os.environ['BOT_PREFIX'],
client_id=os.environ['CLIENT_ID'],
initial_channels=init_channels(),
case_insensitive=True
)
self.channel = None
self._cogs_names: t.Dict[str] = [
p.stem for p in Path(".").glob("./cogs/*.py")
]
self.vip_so = {
x: {} for x in init_channels()
}
self.bot_to_reply = ['wizebot', 'streamelements', 'nightbot', 'moobot']
self.routines = {}
self.esclient = eventsub.EventSubWSClient(self)
def setup(self):
random.seed()
logging.info("Chargement des cogs...")
for cog in self._cogs_names:
logging.info(f"Loading `{cog}` cog.")
self.load_module(f"cogs.{cog}")
logging.info("Chargement terminé")
# Retrieving custom commands from db
custom_commands.init_commands()
def run(self):
self.setup()
super().run()
async def event_ready(self):
# Notify us when everything is ready!
self.channel = self.get_channel(os.environ['CHANNEL'])
# Retrieving routines from db
self.routines = custom_commands.init_routines(self)
# Starting timers
logging.info("Starting routines...")
self.links.start()
self.id_updater.start()
# We are logged in and ready to chat and use commands...
logging.info(f'Logged in as | {self.nick}')
async def event_message(self, message):
# Messages with echo set to True are messages sent by the bot...
# For now we just want to ignore them...
if message.echo:
return
# Print the contents of our message to console...
logging.info(
f'{message.author.name} on channel {message.author.channel.name}: '
f'{message.content}'
)
ctx = await self.get_context(message)
# if check_for_bot(message.content):
# logging.info("BOT DETECTED")
# message.author.channel.send(
# f'/ban {message.author.name} Vilain Bot')
if message.content[0] == os.environ['BOT_PREFIX']:
reply = custom_commands.get_command(message)
if reply is not None:
await ctx.reply(reply)
return
if "@leixbot" in message.content.lower():
await random_reply(self, message)
elif message.author.name.lower() in self.bot_to_reply and custom_commands.is_bot_reply(ctx.author.channel.name):
await random_bot_reply(message)
else:
await auto_so(self, message, self.vip_so[message.author.channel.name])
# Since we have commands and are overriding the default `event_message`
# We must let the bot know we want to handle and invoke our commands...
await self.handle_commands(message)
async def event_raw_usernotice(self, channel, tags):
if tags["msg-id"] == "sub":
await channel.send(f"/me PogChamp {tags['display-name']} rejoint la légion! Merci pour le sub PogChamp")
await play_alert(channel.name, 'subscription', tags['display-name'])
elif tags["msg-id"] == "resub":
await channel.send(
f"/me PogChamp Le resub de {tags['display-name']}!! Merci de fièrement soutenir la chaine depuis {tags['msg-param-cumulative-months']} mois <3"
)
await play_alert(channel.name, 'subscription', tags['display-name'])
elif tags['msg-id'] == 'subgift':
await channel.send(
f'/me {tags["display-name"]} est vraiment trop sympa, il régale {tags["msg-param-recipient-display-name"]} avec un sub!'
)
await play_alert(channel.name, 'subscription', tags['msg-param-recipient-display-name'])
elif tags['msg-id'] == 'anonsubgift':
await channel.send(
f'/me Un donateur anonyme est vraiment trop sympa, il régale {tags["msg-param-recipient-display-name"]} avec un sub!'
)
await play_alert(channel.name, 'subscription', tags['msg-param-recipient-display-name'])
elif tags["msg-id"] == "raid":
await channel.send(
f"/me Il faut se défendre SwiftRage ! Nous sommes raid par {tags['msg-param-displayName']} et ses {tags['msg-param-viewerCount']} margoulins!"
)
await play_alert(channel.name, tags["msg-id"], tags['msg-param-displayName'])
async def event_command_error(self, ctx: commands.Context, error: Exception):
if isinstance(error, commands.CommandNotFound):
logging.error("Command does not exist")
## EVENTSUB WS FUNCTIONS ##
async def event_eventsub_notification(self, payload: eventsub.NotificationEvent) -> None:
print('Received event!')
print(payload.headers.message_id)
async def event_eventsub_notification_channel_reward_redeem(self, payload: eventsub.CustomRewardRedemptionAddUpdateData) -> None:
print('Received event!')
print(payload.data.id)
async def event_eventsub_notification_stream_start(self, payload: eventsub.StreamOnlineData) -> None:
print('Received event!')
print(payload)
async def event_eventsub_notification_followV2(self, payload: eventsub.ChannelFollowData) -> None:
print('Received event!')
print(f'{payload.data.user.name} followed woohoo!')
async def event_eventsub_notification_channel_update(self, payload: eventsub.ChannelUpdateData) -> None:
print('Received event!')
print(payload)
async def sub(self):
await self.esclient.subscribe_channel_points_redeemed(broadcaster=self.channel, token=os.environ['CHANNEL_ACCESS_TOKEN'],)
await self.esclient.subscribe_channel_stream_start(broadcaster=self.channel, token=os.environ['CHANNEL_ACCESS_TOKEN'])
await self.esclient.subscribe_channel_update(broadcaster=self.channel, token=os.environ['CHANNEL_ACCESS_TOKEN'])
await self.esclient.subscribe_channel_follows_v2(broadcaster=self.channel, moderator=self.channel, token=os.environ['CHANNEL_ACCESS_TOKEN'])
## ROUTINES ##
@routines.routine(minutes=30.0, wait_first=False)
async def links(self):
await self.channel.send("Mon YouTube: https://youtube.com/leix34")
await asyncio.sleep(60 * 30)
await self.channel.send("Guide Apex Legends: https://leochely.github.io/apexLegendsGuide/")
await asyncio.sleep(60 * 30)
await self.channel.send("Le discord: https://discord.com/invite/jzU7xWstS9")
await asyncio.sleep(60 * 30)
await self.channel.send("La radio Guilty, 24h/24 et 7j/7 sur https://www.youtube.com/@leix34/live ")
await asyncio.sleep(60 * 30)
@routines.routine(hours=1.0, wait_first=False)
async def id_updater(self):
channels_info = get_channels_info()
channels = await self.fetch_channels(channels_info.keys())
for channel in channels:
user = await channel.user.fetch()
if user.name != channels_info[channel.user.id]:
update_name(channel.user.id, user.name)
@commands.command(name="routineAdd")
async def routine_add(self, ctx: commands.Context, name, seconds, minutes, hours, *text):
"""Ajoute et démarre une routine. Requiert privilege modérateur.
Ex: !routineAdd mon_nom_de_routine 1 2 3 Mon texte de routine
"""
if not ctx.author.is_mod:
return
routine_text = ' '.join(text)
channel = self.get_channel(ctx.author.channel.name)
logging.info(channel)
@routines.routine(seconds=int(seconds), minutes=int(minutes), hours=int(hours), wait_first=False)
async def temp_routine():
await channel.send(routine_text)
# Starts routine
self.routines[ctx.author.channel.name + '_' + name] = temp_routine
self.routines[ctx.author.channel.name + '_' + name].start()
# Adds routine to db
custom_commands.add_routine(
ctx.author.channel.name,
name,
seconds,
minutes,
hours,
routine_text
)
await ctx.send('Routine créée avec succès SeemsGood')
@commands.command(name="routineStop")
async def routine_stop(self, ctx: commands.Context, name):
"""Arrete et supprime une routine. Requiert privilege modérateur.
Ex: !routineStop ma_routine
"""
if not ctx.author.is_mod:
return
# Stops routine
self.routines[ctx.author.channel.name + '_' + name].cancel()
# Removes routine from db
custom_commands.remove_routine(ctx.author.channel.name, name)
await ctx.send('Routine stoppée avec succès MrDestructoid')
## GENERAL FUNCTIONS ##
@commands.command(name="git")
async def git(self, ctx: commands.Context):
"""Renvoie le lien vers le repo GitHub de LeixBot. Ex: !git"""
await ctx.send(
f'Here is my source code https://github.com/leochely/leixbot/ MrDestructoid'
)
@commands.command(name='commandes', aliases=['commands'])
async def commandes(self, ctx: commands.Context):
"""
Retourne la liste des commandes de LeixBot sur cette chaine
"""
channel = ctx.author.channel.name
commands = custom_commands.find_commands_channel(channel)
cmd_list = ""
for command in commands:
cmd_list += command[0] + ", "
# Remove last comma and space
cmd_list = cmd_list[:-2]
await ctx.send(
f'La liste de mes commandes sur ce chat: {cmd_list}'
)
@commands.command(name="list")
async def list(self, ctx: commands.Context):
"""
Retourne la liste des commandes globales de LeixBot
"""
cmd_list = ""
for command in self.commands:
cmd_list += command + ", "
# Remove last comma and space
cmd_list = cmd_list[:-2]
await ctx.send(f'La liste des commandes globales de LeixBot: {cmd_list}')
@commands.command(name="help")
async def help(self, ctx: commands.Context, name):
"""Fournit l'aide d'une commande globale. Ex: !help help"""
if name in self.commands:
await ctx.send(self.commands[name]._callback.__doc__)
else:
await ctx.send("Désolé, ce n'est pas une de mes commandes globales :(")
@commands.command(name="join")
async def join(self, ctx: commands.Context, channel):
"""Envoie LeixBot sur votre chaine. Ex: !join ma_chaine"""
if ctx.author.name == os.environ['CHANNEL'] or ctx.author.name == channel:
channel = channel.lower()
await ctx.send(f'Joining channel {channel}')
user = await ctx.channel.user()
id = user.id
await self.join_channels({channel})
self.vip_so[channel] = {}
add_channel(channel, id)
@commands.command(name="leave")
async def leave(self, ctx: commands.Context, channel):
"""Retire LeixBot de votre chaine. Ex: !leave ma_chaine"""
if ctx.author.name == os.environ['CHANNEL'] or ctx.author.name == channel:
channel = channel.lower()
await ctx.send(f'Leaving channel {channel}')
await self.part_channels({channel})
leave_channel(channel)
if __name__ == "__main__":
logging.basicConfig(
encoding='utf-8',
level=logging.INFO,
handlers=[
logging.FileHandler("debug.log"),
logging.StreamHandler()
]
)
client = Client(
token=os.environ['CHANNEL_ACCESS_TOKEN'],
client_secret=os.environ['CLIENT_SECRET']
)
bot = LeixBot()
bot.loop.create_task(bot.sub())
bot.run()