123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- from bot_settings import *
- from some_data import *
- from twitchio.ext import commands, routines
- from twitchio.user import User
- from twitchio.channel import Channel
- from db_client import db_message_log_client
- import datetime
- import calendar
- from dateutil import tz
- import random
- import re
- import requests
- from bot_utilities import *
- from gpiozero import CPUTemperature
- class twitch_bot(commands.Bot):
- name = str()
- dbLogClient = db_message_log_client(DB_CONNECTION_STRING)
- msg_titles = ['сообщение', 'сообщения', 'сообщений']
-
- #Инициализация бота
- def __init__(self, name):
- super().__init__(token=ACCESS_TOKEN, prefix=PREFIX, initial_channels=INITIAL_CHANNELS)
- self.dbLogClient.connect()
- #Событие готовности бота
- async def event_ready(self):
- print(f'Вошел как | {self.nick}')
- print(f'Id пользователя | {self.user_id}')
- #Обработка сообщений
- async def event_message(self, message):
- if message.echo:
- author_id = self.user_id
- author_name = self.nick
- else:
- author_id = message.author.id
- author_name = message.author.name
-
- utc_time = message.timestamp
- utc_time = utc_time.replace(tzinfo=tz.tzutc())
- localTime = utc_time.astimezone(tz.tzlocal())
- print(f'{localTime}({message.channel.name}){author_name}:{message.content}')
- channel_user = await message.channel.user(False)
- self.dbLogClient.insert_message(message.content, author_id, author_name, channel_user, localTime)
-
- if message.echo:
- return
-
- if str(message.content).startswith(PREFIX):
- await self.handle_commands(message)
- return
-
- #Опускание мубота
- if message.author.name == 'moobot':
- await message.channel.send(f'@{message.author.name}, мубот соси')
- return
- #Приветствия и покатствия
- check_str = re.split(r',|!|;|\.|\?', message.content)[0]
- if check_str in hellos:
- await message.channel.send(f'@{message.author.name}, {random.choice(hellos)}')
- return
- if check_str in byes:
- await message.channel.send(f'@{message.author.name}, {random.choice(byes)}')
- return
-
-
- if check_str in custom_copypast_cmd and message.channel.name in ALLOW_FLOOD:
- await message.channel.send(check_str)
- return
-
- if(str(f'@{self.nick}') in str(message.content).lower()):
- channel_user = await message.channel.user()
- await message.channel.send(f'@{message.author.name}, {self.dbLogClient.get_random_message_by_user(channel_user.id)}')
- #await message.channel.send(f'@{message.author.name}, {self.dbLogClient.GetRandomMessageByUser(40348923)}')
- return
-
- #Информационные команды
- @commands.command(name='тг', aliases=['телеграм', 'телега', 'telegram', 'tg'])
- async def telegram(self, ctx: commands.Context):
- msg = telegrams.get(ctx.channel.name)
- if(not msg == None):
- await ctx.send(msg)
-
- @commands.command(name='вконтакте', aliases=['вк', 'vk', 'vkontakte'])
- async def vkontakte(self, ctx: commands.Context):
- msg = vks.get(ctx.channel.name)
- if(not msg == None):
- await ctx.send(msg)
-
- @commands.command(name='бусти', aliases=['boosty', 'кошка'])
- async def boosty(self, ctx: commands.Context):
- msg = boostys.get(ctx.channel.name)
- if(not msg == None):
- await ctx.send(msg)
-
- @commands.command(name='донат', aliases=['donat', 'пожертвование'])
- async def donat(self, ctx: commands.Context):
- msg = donats.get(ctx.channel.name)
- if(not msg == None):
- await ctx.send(msg)
-
- @commands.command(name='мем', aliases=['меме', 'meme'])
- async def meme(self, ctx: commands.Context):
- msg = memes.get(ctx.channel.name)
- if(not msg == None):
- await ctx.send(msg)
-
- @commands.command(name='смайлы', aliases=['7tv', 'smiles', 'emoji', 'смайлики', 'эмоуты'])
- async def SpecialSmiles(self, ctx: commands.Context):
- if ctx.channel.name in ALLOW_URL:
- await ctx.send('Чтобы видеть и посылать крутые смайлы в чате устанавливайте расширение для браузера по ссылке: https://7tv.app/')
-
- @commands.command(name='help', aliases=['commands', 'команды', 'помощь', 'бот'])
- async def help_bot(self, ctx: commands.Context):
- await ctx.send(f'@{ctx.author.name} Я бот и я ничего не умею 4Head')
-
- @commands.cooldown(rate=1, per=60, bucket=commands.Bucket.channel)
- @commands.command(name='lastseen', aliases=['когдавидели'])
- async def last_seen(self, ctx: commands.Context):
- channel_user = await ctx.channel.user()
- last_activity = self.dbLogClient.get_channel_author_last_activity(channel_user.id)
- if (last_activity):
- await ctx.send(f'@{ctx.author.name}, в последний раз {ctx.channel.name} видели в чате {last_activity.strftime("%d.%m.%Y в %H:%M:%S")} CoolStoryBob');
- else:
- await ctx.send(f'@{ctx.author.name}, я не помню когда в последний раз видел в чате {ctx.channel.name} PoroSad');
-
- @commands.cooldown(rate=1, per=300, bucket=commands.Bucket.member)
- @commands.command(name='followage', aliases=['возрастотслеживания'])
- async def followage(self, ctx: commands.Context):
- if ctx.author.name == ctx.channel.name:
- await ctx.send(f'@{ctx.author.name}, ты не можешь отслеживать сам себя CoolStoryBob')
- return
- r = requests.get(f'https://api.ivr.fi/v2/twitch/subage/{ctx.author.name}/{ctx.channel.name}')
- if r.status_code >= 400:
- await ctx.send(f'@{ctx.author.name}, не удалось выполнить запрос времени отслеживания PoroSad')
- return
- followedAt = r.json()["followedAt"]
- if followedAt :
- follow_age = datetime.datetime.now() - datetime.datetime.fromisoformat(followedAt.replace('Z',''))
- await ctx.send(f'@{ctx.author.name}, ты отслеживаешь канал {ctx.channel.name} {follow_age.days} дней SeemsGood')
- else:
- await ctx.send(f'@{ctx.author.name}, ты не отслеживаешь канал {ctx.channel.name} D:')
-
- @commands.cooldown(rate=1, per=30, bucket=commands.Bucket.channel)
- @commands.command(name='день')
- async def whatdaytoday(self, ctx: commands.Context):
- await ctx.send(f'@{ctx.author.name}, {get_today_holiday()}')
-
- @commands.cooldown(rate=1, per=30, bucket=commands.Bucket.member)
- @commands.command(name='погода', aliases=['weather'])
- async def weather(self, ctx: commands.Context):
- direct_translate = {
- 'N' : 'С',
- 'W' : 'З',
- 'S' : 'Ю',
- 'E' : 'В'
- }
- url = "https://weatherapi-com.p.rapidapi.com/current.json"
- arg = ctx.message.content.rstrip(' ').split(' ', 1)[1]
- querystring = {"q":arg,"lang":"ru"}
- response = requests.get(url, headers=weather_headers, params=querystring)
- if response.status_code < 400:
- jsonR = response.json()
- await ctx.send(f'@{ctx.author.name}, в {jsonR["location"]["name"]} на данный момент {jsonR["current"]["temp_c"]}°C. {jsonR["current"]["condition"]["text"]}. Ветер {replace_chars(jsonR["current"]["wind_dir"], direct_translate)} {jsonR["current"]["wind_kph"] * 1000 / 3600:.2f} м/с. peepoPls')
- else:
- await ctx.send(f'@{ctx.author.name}, не удалось выполнить запрос погоды PoroSad')
-
- @commands.cooldown(rate=1, per=30, bucket=commands.Bucket.member)
- @commands.command(name='ogeyofday')
- async def ogeyofday(self, ctx: commands.Context):
- if ctx.channel.name not in OGEY_OF_DAY_CHANNELS:
- return
- channel_user = await ctx.channel.user()
- ogey_name = self.dbLogClient.get_ogey(channel_user.id)
- if ogey_name != None:
- await ctx.send(f'@{ctx.author.name}, Ogey дня сегодня {ogey_name}, можно только позавидовать этому чатеру EZ Clap')
- else:
- await ctx.send(f'@{ctx.author.name}, Ogey дня не определен PoroSad')
-
- #Команды под оффлайн чат
- @commands.cooldown(rate=1, per=10, bucket=commands.Bucket.member)
- @commands.command(name='чмок')
- async def chmok(self, ctx: commands.Context, phrase: str | None):
- if await self.is_stream_online(ctx.channel):
- return
- if len(ctx.chatters) == 0:
- await ctx.send('В этом чате некого чмокнуть PoroSad')
- elif not phrase:
- await ctx.send(f'@{ctx.author.name} чмокнул @{random.choice(tuple(ctx.chatters)).name} 😘')
- else:
- if not is_valid_args(phrase):
- await ctx.send(f'@{ctx.author.name}, бана хочешь моего?')
- elif ctx.author.name in phrase.lower():
- await ctx.send(f'@{ctx.author.name} боюсь что это нереально. Давай лучше я 😘')
- elif self.nick in phrase.lower():
- await ctx.send(f'@{ctx.author.name}, и тебе чмок 😘')
- else:
- await ctx.send(f'@{ctx.author.name} чмокнул {phrase} 😘')
-
- @commands.cooldown(rate=1, per=10, bucket=commands.Bucket.member)
- @commands.command(name='лапочка')
- async def lapochka(self, ctx: commands.Context, phrase: str | None):
- if await self.is_stream_online(ctx.channel):
- return
- if len(ctx.chatters) == 0:
- await ctx.send('В этом чате пусто PoroSad')
- elif not phrase:
- await ctx.send(f'@{ctx.author.name} назвал лапочкой @{random.choice(tuple(ctx.chatters)).name} <3')
- else:
- if not is_valid_args(phrase):
- await ctx.send(f'@{ctx.author.name}, бана хочешь моего?')
- elif ctx.author.name in phrase.lower():
- await ctx.send(f'@{ctx.author.name} высокая самооценка это хорошо SeemsGood')
- elif self.nick in phrase.lower():
- await ctx.send(f'@{ctx.author.name}, ой спасибо bleedPurple')
- else:
- await ctx.send(f'@{ctx.author.name} назвал лапочкой {phrase} <3')
-
- @commands.cooldown(rate=1, per=60, bucket=commands.Bucket.channel)
- @commands.command(name='анек', aliases=['кринж'])
- async def anek(self, ctx: commands.Context):
- await ctx.send(get_rand_anek())
-
- @commands.cooldown(rate=1, per=10, bucket=commands.Bucket.user)
- @commands.command(name='ауф', aliases=['auf'])
- async def auf(self, ctx: commands.Context):
- await ctx.send(random.choice(auf_messages))
-
- @commands.cooldown(rate=1, per=7200, bucket=commands.Bucket.channel)
- @commands.command(name='привет', aliases=['hello', 'hi'])
- async def hello(self, ctx: commands.Context):
- if await self.is_stream_online(ctx.channel):
- return
- channel_user = await ctx.channel.user()
- active_users = self.dbLogClient.get_last_active_users(channel_user.id)
- if not active_users:
- await ctx.send('Я не знаю кто был в чате недавно. Поэтому привет всем KonCha')
- return
- msg = f'Привет,'
- for user_row in active_users:
- msg = f' {msg} @{user_row[0]},'
- msg = msg + ' KonCha'
- await ctx.send(msg)
-
- @commands.cooldown(rate=1, per=600, bucket=commands.Bucket.channel)
- @commands.command(name='топ', aliases=['top'])
- async def top(self, ctx: commands.Context):
- channel_user = await ctx.channel.user()
- top_users = self.dbLogClient.get_top_of_month_users(channel_user.id)
- if not top_users:
- await ctx.send('Не найдены сообщения для топа NotLikeThis')
- return
- msg = f'Топ месяца по сообщениям:'
- for user_row in top_users:
- msg = f' {msg} {user_row[0]}({user_row[1]:,}),'
- msg = msg + ' PogChamp'
- await ctx.send(msg)
-
- @commands.cooldown(rate=1, per=30, bucket=commands.Bucket.user)
- @commands.command(name='скольконасрал')
- async def skolkonasral(self, ctx: commands.Context, phrase: str | None):
- if await self.is_stream_online(ctx.channel):
- return
- channel_user = await ctx.channel.user()
- if phrase:
- name = phrase
- else:
- name = ctx.author.name
- msg_count = self.dbLogClient.get_users_message_count_for_mounth_by_name(channel_user.id, name.lower())
- if not msg_count:
- await ctx.send(f'@{ctx.author.name}, не удалось подсчитать сообщения запрошеного пользователя NotLikeThis.')
- return
- await ctx.send(f"В этом месяце {name} написал в чате {msg_count:,} {decl_of_num(msg_count, self.msg_titles)} PogChamp")
-
- @commands.cooldown(rate=1, per=300, bucket=commands.Bucket.channel)
- @commands.command(name='всегонасрано')
- async def vsegonasrano(self, ctx: commands.Context):
- channel_user = await ctx.channel.user()
- msg_count = self.dbLogClient.get_all_users_message_count_for_mounth(channel_user.id)
- if not msg_count:
- await ctx.send(f'@{ctx.author.name}, не удалось подсчитать количество написаных сообщений NotLikeThis')
- return
- await ctx.send(f"В этом месяце в чате насрали {msg_count:,} сообщений SHTO")
-
- @commands.cooldown(rate=1, per=60, bucket=commands.Bucket.channel)
- @commands.command(name='маления')
- async def malenia(self, ctx: commands.Context):
- channel_user = await ctx.channel.user()
- msg_count = self.dbLogClient.get_malenia_in_channel(channel_user.id)
- if not msg_count:
- await ctx.send(f'@{ctx.author.name}, не удалось подсчитать упоминаний малений в этом чате NotLikeThis')
- return
- await ctx.send(f"В этом чате вспомнили Малению {msg_count:,} раз MaleniaTime")
-
- @commands.cooldown(rate=1, per=10, bucket=commands.Bucket.channel)
- @commands.command(name='год', aliases=['year', 'прогресс'])
- async def year(self, ctx: commands.Context):
- now = datetime.datetime.now()
- start_of_year = now.replace(day=1, month=1, year=now.year)
- days_passed = (now - start_of_year).days
- seconds_since_midnight = (now - now.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()
- await ctx.send(f"@{ctx.author.name}, прогресс года: {(days_passed * 86400 + seconds_since_midnight) / ((365 + calendar.isleap(datetime.datetime.now().year)) * 86400) * 100:.10f}% catDespair")
-
- @commands.cooldown(rate=1, per=600, bucket=commands.Bucket.user)
- @commands.command(name='сосиска')
- async def sousage(self, ctx: commands.Context):
- length = random.randint(0, 30)
- emote = get_val_by_max_val({5: "PoroSad",
- 10: "Stare",
- 15: "Hmm",
- 20: "Hmmege",
- 25: "SHTO",
- 30: "EZ"}, length)
- await ctx.send(f"@{ctx.author.name} имеет сосиску {length} см. {emote}")
-
- #Рутины
- @routines.routine(time = datetime.datetime(year = 2024, month = 6, day = 1, hour = 18, minute = 00))
- async def ogey_of_day_routine(self):
- for ch in OGEY_OF_DAY_CHANNELS:
- channels = await self.fetch_users([ch])
- channel_id = channels[0].id
- channel = self.get_channel(ch)
- ogey_id = self.dbLogClient.get_random_user_by_last_n_hours(channel_id, 24)
- if self.dbLogClient.update_ogey(channel_id, ogey_id):
- await channel.send(f'Ogey дня обновился. Чтобы узнать кто им стал введите команду !ogeyofday 4Head')
- else:
- await channel.send(f'Не удалось определить нового Ogey. PoroSad')
-
- #Команды для белого списка
- @commands.command(name='горячесть', aliases=['температура', 'темп', 'temp'])
- async def temperature(self, ctx: commands.Context):
- if ctx.author.name in white_list:
- cpu_t = CPUTemperature()
- await ctx.send(f'Моя горячесть равна {cpu_t.temperature} градусам')
- #Обработка исключений
- async def event_command_error(self, ctx, error: Exception) -> None:
- if isinstance(error, commands.CommandOnCooldown) and not await self.is_stream_online(ctx.channel):
- await ctx.send(f'Команда "{error.command.name}" заряжается, еще {int(error.retry_after)} сек.')
- print(error)
-
- #Событие подключения к чату
- async def event_join(self, channel: Channel, user: User):
- print(f'{datetime.datetime.now()}: Пользователь {user.name} вошел в чат {channel.name}')
- if channel.name == user.name:
- channel_user = await channel.user() #id отсутвует в User поэтому приходится запрашивать
- await channel.send(f'Привет, мир! KonCha')
- print(f'{datetime.datetime.now()}: Стример в чате {channel_user.name}')
-
- async def event_ready(self):
- #Старт рутин
- self.ogey_of_day_routine.start()
-
- #Дополнительные функции
- async def is_stream_online(self, channel) -> bool:
- chan_user = await channel.user()
- streams = await self.fetch_streams([chan_user.id])
- if len(streams) == 0:
- return False
- return True
|