-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
268 lines (231 loc) · 12.2 KB
/
main.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
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
import telebot
import sqlite3
from random import randint
from string import ascii_uppercase
from datetime import datetime
from time import sleep
from threading import Thread
from secrets import TOKEN # Secrets is a file filled with, well, secrets:
# tokens, potentially unsafe info and such!
# Creating a connection to the bot
bot = telebot.TeleBot(TOKEN)
group = None
user_id = None
lang_ru = False # Default bot language is English
# Some two-language text constants to use later...
data_change_success_message = [("An error occured. Try again?", "Произошла ошибка. Попробуйте ещё раз."),
("Changes saved successfully.", "Изменения успешно сохранены.")]
EMOJIS = ('🥳', '🎂', '🎉', '🎁', '🎈')
# Functions that do not respond to commands and messages sent by the user
def start(message):
start_message = ["Welcome to @kylebrea's birthday bot!\
\n\nThis bot aims to help you remember the birthdays of your colleagues and subordinates.\
\nPress /help to get the list of commands.",
"Добро пожаловать в бот для поздравлений с днями рождения от @kylebrea!\
\n\nЭтот бот предназначен для информирования и уведомления о днях рождениях коллег.\
\nДля вывода списка команд нажмите на /help."
]
bot.send_message(message.chat.id, start_message[lang_ru])
def join_or_create(message):
joc_message = ["Do you want to join a group or create one?",
"Вы хотите присоединиться к существующей группе или создать свою?"]
markup_text = [("Join a group", "Присоединиться к группе"),
("Create a group", "Создать группу")]
markup = telebot.types.InlineKeyboardMarkup()
markup.row(telebot.types.InlineKeyboardButton(markup_text[0][lang_ru], callback_data='join_group'),
telebot.types.InlineKeyboardButton(markup_text[1][lang_ru], callback_data='create_group'))
bot.send_message(message.chat.id, joc_message[lang_ru], reply_markup=markup)
def verify_group(message):
global group
msg = ('Invalid code', 'Неправильный код')
group_code = message.text.strip().upper()
conn = sqlite3.connect('birthdays.sql')
cur = conn.cursor()
cur.execute(f"SELECT name FROM sqlite_master WHERE type='table' AND name='{group_code}'")
table_exists = cur.fetchone()
cur.close()
conn.close()
try:
if table_exists:
group = group_code
msg = ("Successfully joined the group!", "Успешно вошли в группу!")
bot.send_message(message.chat.id, msg[lang_ru])
else:
raise Exception
except Exception:
bot.send_message(message.chat.id, msg[lang_ru])
bot.register_next_step_handler(message, verify_group)
finally:
print('verify_group done')
def verify_name_birthday(message):
msg = data_change_success_message[0]
try:
name, surname, bday = message.text.split()
day, month, year = bday.split('.')
if len(message.text.split()) != 3 or len(bday.split('.')) != 3:
raise Exception
if len(day) != 2 or len(month) != 2 or len(year) != 4:
print('bad length')
raise Exception
elif int(day) > 31 or int(month) > 12 or int(year) > 2024:
print('out of limits date')
raise Exception
conn = sqlite3.connect('birthdays.sql')
cur = conn.cursor()
cur.execute(f"UPDATE {group} SET name='{name}', surname='{surname}', day='{day}',\
month='{month}', year='{year}' WHERE id='{message.from_user.id}'")
conn.commit()
cur.close()
conn.close()
bot.send_message(message.chat.id, data_change_success_message[1][lang_ru])
except Exception:
bot.send_message(message.chat.id, msg[lang_ru])
bot.register_next_step_handler(message, verify_name_birthday)
finally:
print('verify_name_birthday done')
def look_for_birthdays():
delay = 10
while True:
if group:
today, tomonth, toyear = datetime.now().day, datetime.now().month, datetime.now().year
conn = sqlite3.connect('birthdays.sql')
cur = conn.cursor()
cur.execute(f"SELECT name, surname, year FROM {group} WHERE day='{today}' AND month='{tomonth}'")
birthdays = cur.fetchall()
cur.close()
conn.close()
for bday in birthdays:
msg = (f"Today is {bday[0]} {bday[1]}'s {toyear - bday[-1]}th birthday!",
f"Сегодня {bday[0]} {bday[1]} отмечает {toyear - bday[-1]}летие!")
bot.send_message(user_id, msg[lang_ru])
delay = 86400
sleep(delay)
# Functions with message handlers that respond to user's commands
@bot.message_handler(commands=['start'])
def init(message):
global lang_ru, user_id
lang_ru = message.from_user.language_code == 'ru'
user_id = message.from_user.id
start(message)
manual(message)
join_or_create(message)
@bot.message_handler(commands=['set_name_birthday'])
def set_name_birthday(message):
msg = ["Enter your full name separated by spaces and date of birth strictly in DD.MM.YYYY format\
(like this: Aleksandra Semenenia 21.03.2004):",
"Введите своё полное имя, разделённое запятыми, и день рождения в формате ДД.ММ.ГГГГ\
(пример: Александра Семененя 21.03.2004):"]
bot.send_message(message.chat.id, msg[lang_ru])
bot.register_next_step_handler(message, verify_name_birthday)
@bot.message_handler(commands=['change_language'])
def change_language(message):
global lang_ru
lang_ru = not lang_ru
start(message)
@bot.message_handler(commands=['all_birthdays'])
def all_birthdays(message):
if not group:
bot.send_message(message.chat.id, data_change_success_message[0][lang_ru])
return
msg = ('No birthdays found', 'Не найдено дней рождения')
conn = sqlite3.connect('birthdays.sql')
cur = conn.cursor()
cur.execute(f"SELECT name, surname, day, month, year FROM {group} ORDER BY month, day, year")
birthdays = cur.fetchall()
result = '' if len(birthdays) > 0 else msg[lang_ru]
for i in range(len(birthdays)):
result += f"{i + 1}. {birthdays[i][0]} {birthdays[i][1]} - {birthdays[i][2]}.{birthdays[i][3]}.{birthdays[i][4]}\n"
cur.close()
conn.close()
bot.send_message(message.chat.id, result)
@bot.message_handler(commands=['join_group'])
def join_group(message):
msg = ("Enter the 6-letter group code your group admin sent you:",
'Введите шестибуквенный код, который вам отправил администратор группы:')
bot.reply_to(message, msg[lang_ru])
bot.register_next_step_handler(message, verify_group)
@bot.message_handler(commands=['create_group'])
def create_group(message):
global group
conn = sqlite3.connect('birthdays.sql')
cur = conn.cursor()
group_code = ''.join([ascii_uppercase[randint(0, 25)] for i in range(6)])
cur.execute(f'CREATE TABLE IF NOT EXISTS {group_code} (id int primary_key unique, name varchar(50), surname varchar(50), day int, month int, year int)')
conn.commit()
cur.close()
conn.close()
group = group_code
msg = (f"You have successfully created a group.\
\nYour group's code is **{group_code}**, send it to people who want to join it!",
f'Вы успешно создали группу, теперь другие пользователи могут к ней подключиться.\
\nКод вашей группы: **{group_code}**, перешлите его пользователям, которых хотите включить в группу!')
bot.send_message(message.chat.id, msg[lang_ru], parse_mode='markdown')
@bot.message_handler(commands=['register'])
def register(message):
if not group:
print('no group')
bot.send_message(message.chat.id, data_change_success_message[0][lang_ru])
return
conn = sqlite3.connect('birthdays.sql')
cur = conn.cursor()
cur.execute(f"SELECT 1 FROM {group} WHERE id='{message.from_user.id}'")
user_exists = cur.fetchone()
if not user_exists:
cur.execute(f"INSERT INTO {group} (id, name, surname, day, month, year)\
VALUES ('{message.from_user.id}', '{message.from_user.first_name}', '{message.from_user.last_name}',\
'00', '00', '0000')")
conn.commit()
cur.close()
conn.close()
register_message = ["This bot needs an account to work properly, please create one:",
"Чтобы пользоваться ботом, пройдите короткую регистрацию."]
bot.send_message(message.chat.id, register_message[lang_ru])
set_name_birthday(message)
@bot.message_handler(commands=['manual'])
def manual(message):
msg = ("1. Join a group (/join_group) or create one (/create_group);\
\n2. Register using /register;\
\n3. Now you are automatically subscribed to all your group's members' birthdays.\
\nYou'll receive notifications for their birthday, and you can view a list using /all_birthdays.",
"1. Присоединитесь к группе (/join_group) либо создайте свою (/create_group);\
\n2. Введите личные данные через /register;\
\n3. Теперь вы подписаны на дни рождения всех членов группы.\
\nВы будете получать уведомления об их днях рождения. Посмотреть весь список: /all_birthdays.",)
bot.send_message(message.chat.id, msg[lang_ru])
@bot.message_handler(commands=['help'])
def help(message):
msg = ("/start – begin working with the bot\
\n/manual - instructions\
\n/help – list of commands\
\n/register — set your name and birthday\
\n/change_language – switch language between English and Russian\
\n/join_group – join an existing group\
\n/create_group - create a new group and generate a code for it\
\n/all_birthdays - birthdays of people in your group in chronological order",
"/start – начало взаимодействия с ботом\
\n/manual - инструкция\
\n/help – список команд\
\n/register — указать своё имя и день рождения\
\n/change_language – меняет язык интерфейса между русским и английским\
\n/join_group – присоединиться к группе\
\n/create_group - создать собственную группу\
\n/all_birthdays - хронологически отсортированный список дней рождения всех людей вашей группы",)
bot.send_message(message.chat.id, msg[lang_ru])
# Default message handler, should be placed last
@bot.message_handler()
def invalid_command(message):
invalid_message = ["Invalid message! Try /help for available commands",
"В сообщении нет команды! /help содержит все ключевые слова, на которые отвечает бот"]
bot.send_message(message.chat.id, invalid_message[lang_ru])
# Callback manager
@bot.callback_query_handler(func=lambda callback: True)
def callback_manager(callback):
if callback.data == 'join_group':
join_group(callback.message)
elif callback.data == 'create_group':
create_group(callback.message)
# Making the bot run for ever and ever
if __name__ == '__main__':
t = Thread(target=look_for_birthdays)
t.start()
bot.polling(none_stop=True)