Compare commits

...
10 Commits
Author SHA1 Message Date
krosh d81f669e3a . 2025-08-18 16:19:14 +03:00
krosh 41a1dab913 . 2025-08-18 15:09:07 +03:00
krosh 22e55a90bb . 2025-08-18 09:10:42 +03:00
krosh 981cc3d1f9 bugs 2025-08-18 08:58:03 +03:00
krosh fc60827261 . 2025-08-18 08:53:38 +03:00
krosh 36aeb7f682 add hyperlinks support 2025-08-18 08:49:31 +03:00
kr0sh512 3b29315129 now on sql 2024-12-23 04:05:46 +03:00
kr0sh512 0e7c185517 / 2024-12-18 00:55:53 +03:00
kr0sh512 b898950f11 fun upd 2024-12-14 23:12:31 +03:00
kr0sh512 d7f499e5c6 - add example config
- add command to configure time for reminds
- little refactoring in tg and for_db
2024-11-11 23:37:15 +03:00
8 changed files with 484 additions and 193 deletions
+2
View File
@@ -1,3 +1,5 @@
config.yaml config.yaml
database/* database/*
__pycache__/* __pycache__/*
old.py
test.py
+38
View File
@@ -0,0 +1,38 @@
# TG Keeper
TG Keeper bot allows you to store notes, display them at a specified interval, and recognizes date formats: DD.MM, DD month. It works both in group chats by mentioning @username_bot and in private messages.
## Features
- Convenient setup interface
- Dependency installation via `requirements.txt`
- Initial configuration in the `config.yaml` file
## Installation
1. Clone the repository:
```sh
git clone https://github.com/yourusername/tg-keeper.git
```
2. Navigate to the project directory:
```sh
cd tg-keeper
```
3. Install the dependencies:
```sh
pip install -r requirements.txt
```
## Configuration
1. Open the `config.yaml` file and configure the parameters as you wish.
## Usage
Run the bot:
```sh
python bot.py
```
Now you can add and manage your notes through TG Keeper.
+6
View File
@@ -0,0 +1,6 @@
admin_id: "856850518"
api_token: null
test_token: null
bot_username: "@keeper_inbot"
users_path: "database/users.yaml"
user_path: "database/users/{}.yaml"
+200 -164
View File
@@ -1,178 +1,170 @@
import yaml, os import yaml, os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from telebot import types from telebot import types
from psycopg2 import pool
from sshtunnel import SSHTunnelForwarder
connection_pool: pool.SimpleConnectionPool = None
config = yaml.safe_load(open("config.yaml")) config = yaml.safe_load(open("config.yaml"))
users_path = config["users_path"]
user_path = config["user_path"] server = SSHTunnelForwarder(
(config["host"], 22),
ssh_private_key="~/.ssh/id_rsa",
ssh_username="krosh",
remote_bind_address=("localhost", config["sql_port"]),
)
server.start()
connection_pool = pool.SimpleConnectionPool(
1,
5,
database=config["sql_database"],
user=config["sql_user"],
password=config["sql_password"],
host="localhost",
port=server.local_bind_port,
)
def into_dict(curs) -> dict:
cols = [desc[0] for desc in curs.description]
data = curs.fetchone()
return dict(zip(cols, data)) if data else None
def into_list(curs) -> list[dict]:
cols = [desc[0] for desc in curs.description]
data = curs.fetchall()
return [dict(zip(cols, row)) for row in data] if data else None
def check_user(user_id: int) -> dict: def check_user(user_id: int) -> dict:
users = yaml.safe_load(open(users_path, "r", encoding="utf-8")) con = connection_pool.getconn()
curs = con.cursor()
curs.execute("SELECT * FROM users WHERE id = %s", (user_id,))
if not users: user = into_dict(curs)
users = {} connection_pool.putconn(con)
if user_id in users: return user
return users[user_id]
return None
def new_user(message: types.Message) -> bool: def new_user(message: types.Message) -> bool:
if check_user(message.chat.id): if check_user(message.chat.id):
return False return False
user = { con = connection_pool.getconn()
"id": message.chat.id, curs = con.cursor()
"type": message.chat.type, curs.execute(
"username": message.chat.username, """
"first_name": message.chat.first_name, INSERT INTO users (id, username, firstname, lastname, chat)
"last_name": message.chat.last_name, VALUES (%s, %s, %s, %s, %s)
"time_created": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), """,
"last_message": None, (
"remind_delta": 12 * 60 * 60, # 12 часов по умолчанию message.chat.id,
} message.chat.username,
message.chat.first_name,
users = yaml.safe_load(open(users_path, "r"), encoding="utf-8") message.chat.last_name,
message.chat.type,
if not users: ),
users = {}
users[user["id"]] = user
yaml_data = yaml.dump(
users,
default_flow_style=False,
encoding="utf-8",
allow_unicode=True,
width=float("inf"),
sort_keys=False,
) )
con.commit()
connection_pool.putconn(con)
with open(users_path, "wb") as file: return
file.write(yaml_data)
return True
def add_note( def add_note(
id: int, text: str, time_notif: datetime = None, list: str = "Default" id: int, text: str, remind_at: datetime = None, list: str = "Default"
) -> bool: ) -> bool:
if not check_user(id): if not check_user(id):
return False return False
notes = ( con = connection_pool.getconn()
yaml.safe_load(open(user_path.format(id), "r", encoding="utf-8")) curs = con.cursor()
if os.path.exists(user_path.format(id)) curs.execute(
else {} """
SELECT id FROM lists WHERE name = %s AND user_id = %s
""",
(list, id),
) )
if list not in notes: data = curs.fetchone()
notes[list] = {"name": list, "description": "Стандартный список", "notes": []}
notes[list]["notes"].append( if not data:
{ curs.execute(
"text": text, """
"time_notif": str(time_notif) if time_notif else None, INSERT INTO lists (name, user_id)
"time_created": str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")), VALUES (%s, %s)
} """,
(list, id),
) )
con.commit()
if True: # TODO: edit sorting curs.execute(
import functools """
INSERT INTO notes (user_id, list_id, content, remind_at)
def comp(x, y): VALUES (%s, (SELECT id FROM lists WHERE name = %s AND user_id = %s), %s, %s)
if not x["time_notif"] and not y["time_notif"]: """,
return 0 (id, list, id, text, remind_at),
elif not x["time_notif"]:
return -1
elif not y["time_notif"]:
return 1
else:
x_time = datetime.strptime(
x["time_notif"],
"%Y-%m-%d %H:%M:%S",
) )
y_time = datetime.strptime( con.commit()
y["time_notif"], rowcnt = curs.rowcount
"%Y-%m-%d %H:%M:%S",
)
if x_time > y_time:
return 1
elif x_time < y_time:
return -1
return 0
notes[list]["notes"].sort( connection_pool.putconn(con)
key=lambda x: datetime.strptime(
x["time_created"],
"%Y-%m-%d %H:%M:%S",
),
reverse=True,
)
notes[list]["notes"].sort( return True if rowcnt else False
key=functools.cmp_to_key(comp),
)
yaml_data = yaml.dump(
notes,
default_flow_style=False,
encoding="utf-8",
allow_unicode=True,
width=float("inf"),
sort_keys=False,
)
with open(user_path.format(id), "wb") as file:
file.write(yaml_data)
return True
def get_notes(id: int, list="Default") -> dict: def get_notes(id: int, list="Default") -> list[dict]:
if not check_user(id): if not check_user(id):
return None return None
if not os.path.exists(user_path.format(id)): con = connection_pool.getconn()
return None curs = con.cursor()
notes = yaml.safe_load(open(user_path.format(id), "r", encoding="utf-8")) curs.execute(
"""
SELECT * FROM notes
WHERE user_id = %s AND list_id = (SELECT id FROM lists WHERE name = %s AND user_id = %s)
ORDER BY remind_at IS NULL DESC, remind_at ASC, created_at DESC
""",
(id, list, id),
)
return notes[list] if list in notes else None notes = into_list(curs)
connection_pool.putconn(con)
return notes
def delete_note(id, note_ind, list="Default") -> bool: def delete_note(id, note_ind, list="Default") -> bool:
if not check_user(id): if not check_user(id):
return False return False
if not os.path.exists(user_path.format(id)): con = connection_pool.getconn()
return False curs = con.cursor()
curs.execute(
notes = yaml.safe_load(open(user_path.format(id), "r", encoding="utf-8")) """
DELETE FROM notes
if list not in notes: WHERE id = (
return False SELECT id FROM notes
WHERE user_id = %s AND list_id = (SELECT id FROM lists WHERE name = %s AND user_id = %s)
if note_ind >= len(notes[list]["notes"]): ORDER BY remind_at IS NULL DESC, remind_at ASC, created_at DESC
return False LIMIT 1 OFFSET %s
)
notes[list]["notes"].pop(note_ind) """,
(id, list, id, note_ind),
yaml_data = yaml.dump(
notes,
default_flow_style=False,
encoding="utf-8",
allow_unicode=True,
width=float("inf"),
sort_keys=False,
) )
with open(user_path.format(id), "wb") as file: con.commit()
file.write(yaml_data) rowcnt = curs.rowcount
connection_pool.putconn(con)
return True return True if rowcnt else False
def new_message(message: types.Message) -> int: def new_message(message: types.Message) -> int:
@@ -182,54 +174,98 @@ def new_message(message: types.Message) -> int:
if not check_user(id): if not check_user(id):
return None return None
users = yaml.safe_load(open(users_path, "r", encoding="utf-8")) con = connection_pool.getconn()
curs = con.cursor()
user = users[id] curs.execute(
"""
if "last_message" not in user: SELECT last_message FROM users WHERE id = %s
user["last_message"] = None """,
(id,),
last_id = user["last_message"]
user["last_message"] = new_msg_id
users[id] = user
yaml_data = yaml.dump(
users,
default_flow_style=False,
encoding="utf-8",
allow_unicode=True,
width=float("inf"),
sort_keys=False,
) )
last_id = curs.fetchone()[0]
with open(users_path, "wb") as file: curs.execute(
file.write(yaml_data) """
UPDATE users
SET last_message = %s
WHERE id = %s
""",
(new_msg_id, id),
)
con.commit()
connection_pool.putconn(con)
return last_id return last_id
def check_old_notes() -> list[int, str, int]: # возвращает первую устаревшую заметку def check_old_notes() -> list[int, str, int]: # возвращает первую устаревшую заметку
users = yaml.safe_load(open(users_path, "r", encoding="utf-8")) con = connection_pool.getconn()
curs = con.cursor()
for user_id in users.keys(): curs.execute(
notes = yaml.safe_load(open(user_path.format(user_id), "r", encoding="utf-8")) """
SELECT id FROM users
if "remind_delta" not in users[user_id]: """
users[user_id]["remind_delta"] = 12 * 60 * 60 # не сохранится!
timedt = timedelta(seconds=users[user_id]["remind_delta"])
for list in notes.keys():
for ind in range(len(notes[list]["notes"])):
if (
notes[list]["notes"][ind]["time_notif"]
and datetime.strptime(
notes[list]["notes"][ind]["time_notif"], "%Y-%m-%d %H:%M:%S"
) )
users = curs.fetchall()
for user_id in users:
curs.execute(
"""
SELECT * FROM notes
WHERE id = %s
ORDER BY remind_at IS NULL DESC, remind_at ASC, created_at DESC
""",
(user_id,),
)
notes = [dict(row) for row in curs.fetchall()]
if not notes:
continue
timedt = timedelta(seconds=user_settings(user_id)["remind_delta"])
for ind in range(len(notes)):
if (
notes[ind]["remind_at"]
and datetime.strptime(notes[ind]["remind_at"], "%Y-%m-%d %H:%M:%S")
- timedt - timedt
< datetime.now() < datetime.now()
): ):
return user_id, list, ind curs.execute(
"""
SELECT name FROM lists
WHERE id = %s
""",
(notes[ind]["list_id"],),
)
list_name = curs.fetchone()
connection_pool.putconn(con)
return (user_id, list_name, ind)
connection_pool.putconn(con)
return None, None, None return None, None, None
def update_user_settings(user_id: int, param: str, value: any) -> bool:
con = connection_pool.getconn()
curs = con.cursor()
query = f"UPDATE users SET {param} = %s WHERE id = %s"
curs.execute(query, (value, user_id))
con.commit()
rowcnt = curs.rowcount
connection_pool.putconn(con)
return True if rowcnt else False
def user_settings(user_id: int) -> dict:
con = connection_pool.getconn()
curs = con.cursor()
curs.execute("SELECT * FROM users WHERE id = %s", (user_id,))
user = into_dict(curs)
connection_pool.putconn(con)
return user
+78
View File
@@ -12,3 +12,81 @@
error_message: "Произошла ошибка. \ error_message: "Произошла ошибка. \
\nПожалуйста, попробуйте снова или свяжитесь с @Kr0sH_512" \nПожалуйста, попробуйте снова или свяжитесь с @Kr0sH_512"
no_reminders: "У вас нет напоминаний." no_reminders: "У вас нет напоминаний."
not_registered: "Пожалуйста, воспользуйтесь сперва командой /start"
"list_reaction":
[
"👍",
"👎",
"❤",
"🔥",
"🥰",
"👏",
"😁",
"🤔",
"🤯",
"😱",
"🤬",
"😢",
"🎉",
"🤩",
"🤮",
"💩",
"🙏",
"👌",
"🕊",
"🤡",
"🥱",
"🥴",
"😍",
"🐳",
"❤‍🔥",
"🌚",
"🌭",
"💯",
"🤣",
"⚡",
"🍌",
"🏆",
"💔",
"🤨",
"😐",
"🍓",
"🍾",
"💋",
"🖕",
"😈",
"😴",
"😭",
"🤓",
"👻",
"👨‍💻",
"👀",
"🎃",
"🙈",
"😇",
"😨",
"🤝",
"✍",
"🤗",
"🫡",
"🎅",
"🎄",
"☃",
"💅",
"🤪",
"🗿",
"🆒",
"💘",
"🙉",
"🦄",
"😘",
"💊",
"🙊",
"😎",
"👾",
"🤷‍♂",
"🤷",
"🤷‍♀",
"😡",
]
+31
View File
@@ -0,0 +1,31 @@
CREATE type chat_type AS ENUM ('private', 'group', 'supergroup', 'channel');
CREATE TABLE users (
id BIGINT PRIMARY KEY,
username TEXT,
firstname TEXT,
lastname TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_message BIGINT NOT NULL DEFAULT 0,
remind_delta BIGINT NOT NULL DEFAULT 21600,
chat chat_type NOT NULL
);
CREATE Table lists (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users (id),
name TEXT NOT NULL,
discription TEXT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE notes (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users (id),
list_id BIGINT NOT NULL REFERENCES lists (id),
content TEXT NOT NULL,
remind_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
+4
View File
@@ -0,0 +1,4 @@
pyyaml
pytelegrambotapi
schedule
python-telegram-bot
+124 -28
View File
@@ -1,16 +1,17 @@
#!/usr/bin/python3.3 #!/usr/bin/python3.3
import threading, telebot, schedule, time, yaml import threading, telebot, schedule, time, yaml
from datetime import datetime from datetime import datetime
import os, sys, inspect import os, sys, inspect, random
import re, locale import re, locale
from telegram.constants import ParseMode from telegram.constants import ParseMode
from telebot import types from telebot import types
import for_db as db import for_db as db
config = yaml.safe_load(open("config.yaml")) config = yaml.safe_load(open("config.yaml"))
lang = yaml.safe_load(open("lang.yaml"))["ru"] lang = yaml.safe_load(open("lang.yaml", encoding="utf-8"))["ru"]
list_reactions = yaml.safe_load(open("lang.yaml", encoding="utf-8"))["list_reaction"]
bot = telebot.TeleBot( bot = telebot.TeleBot(
config["api_token"], config["test_token"],
colorful_logs=True, colorful_logs=True,
disable_web_page_preview=True, disable_web_page_preview=True,
parse_mode=ParseMode.HTML, parse_mode=ParseMode.HTML,
@@ -19,7 +20,6 @@ bot = telebot.TeleBot(
admin_id = config["admin_id"] admin_id = config["admin_id"]
bot_username = config["bot_username"] bot_username = config["bot_username"]
locale.setlocale(locale.LC_ALL, "ru_RU.UTF-8") locale.setlocale(locale.LC_ALL, "ru_RU.UTF-8")
@@ -43,7 +43,10 @@ def restart_bot(message: types.Message):
@bot.message_handler(commands=["start"]) @bot.message_handler(commands=["start"])
def start(message: types.Message): def start(message: types.Message):
send_message(message, lang["start_message"]) send_message(message, lang["welcome_message"])
if not db.check_user(message.chat.id):
db.new_user(message)
return return
@@ -54,6 +57,9 @@ def help(message: types.Message):
send_message(message, help_msg) send_message(message, help_msg)
if not db.check_user(message.chat.id):
db.new_user(message)
return return
@@ -70,13 +76,13 @@ def delete_notes_callback(call):
note_ind = int(call.data.split("#")[2]) note_ind = int(call.data.split("#")[2])
prefix = call.data.split("#")[0] prefix = call.data.split("#")[0]
note = db.get_notes(call.message.chat.id, prefix)["notes"][note_ind] note = db.get_notes(call.message.chat.id, prefix)[note_ind]
db.delete_note(call.message.chat.id, note_ind, prefix) db.delete_note(call.message.chat.id, note_ind, prefix)
list_notes(call.message, prefix, edit=True) list_notes(call.message, prefix, edit=True)
bot.send_message(call.message.chat.id, f"❌ Удалено:\n\n{note['text']}") bot.send_message(call.message.chat.id, f"❌ Удалено:\n\n{note['content']}")
return return
@@ -85,7 +91,7 @@ def delete_notes_callback(call):
def edit_notes_callback(call): def edit_notes_callback(call):
note_ind = int(call.data.split("#")[2]) note_ind = int(call.data.split("#")[2])
prefix = call.data.split("#")[0] prefix = call.data.split("#")[0]
notes = db.get_notes(call.message.chat.id, prefix)["notes"] notes = db.get_notes(call.message.chat.id, prefix)
note = notes[note_ind] note = notes[note_ind]
@@ -105,10 +111,10 @@ def edit_notes_callback(call):
text = f"📝 <b>Заметка {note_ind + 1}</b>" text = f"📝 <b>Заметка {note_ind + 1}</b>"
if note["time_notif"]: if note["remind_at"]:
text += f" ⌚️ <b>{datetime.strptime(note['time_notif'], '%Y-%m-%d %H:%M:%S').strftime('%d %B %Y')}</b>" text += f" ⌚️ <b>{note['remind_at'].strftime('%d %B %Y')}</b>"
text += f"\n\n{note['text']}" text += f"\n\n{note['content']}"
bot.edit_message_text( bot.edit_message_text(
text, text,
@@ -126,7 +132,7 @@ def choose_note_callback(call):
prefix = call.data.split("#")[0] prefix = call.data.split("#")[0]
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
num_on_page = 6 # Лимит телеграмма - 8 num_on_page = 6 # Лимит телеграмма - 8
notes = db.get_notes(call.message.chat.id, prefix)["notes"] notes = db.get_notes(call.message.chat.id, prefix)
max_page = (len(notes) - 1) // num_on_page max_page = (len(notes) - 1) // num_on_page
lst_button = [] lst_button = []
@@ -187,13 +193,70 @@ def choose_note_callback(call):
return return
@bot.message_handler(commands=["settings", "setting", "edit"]) @bot.callback_query_handler(func=lambda call: "edit_time" in call.data)
def display_settings(message: types.Message): def edit_time(call):
list_time = {
(24 - 8) * 3600: "8:00 в день до напоминания",
(24 - 12) * 3600: "12:00 в день до напоминания",
(24 - 18) * 3600: "18:00 в день до напоминания",
0: "0:00 в день до напоминания",
(-8) * 3600: "8:00 в день напоминания",
(-12) * 3600: "12:00 в день напоминания",
(-18) * 3600: "18:00 в день напоминания",
}
if call.data[-1] == "#":
markup = types.InlineKeyboardMarkup()
for delta in list_time.keys():
markup.add(
types.InlineKeyboardButton(
list_time[delta],
callback_data=f"edit_time^{delta}",
)
)
bot.edit_message_text(
"⏰ Выберите время для уведомлений:",
call.message.chat.id,
call.message.message_id,
reply_markup=markup,
)
return
delta = int(call.data.split("^")[1])
db.update_user_settings(call.message.chat.id, "remind_delta", delta)
bot.edit_message_text(
f"Выбранное время: \n\n{list_time[delta]}",
call.message.chat.id,
call.message.message_id,
)
return return
@bot.message_handler(commands=["list"]) @bot.message_handler(commands=["settings", "setting", "edit"])
def display_settings(message: types.Message):
if not db.check_user(message.chat.id):
db.new_user(message)
settings_msg = "Изменить время отправки напоминания"
markup = types.InlineKeyboardMarkup()
markup.add(
types.InlineKeyboardButton(
"Изменить время",
callback_data="edit_time#",
)
)
send_message(message, settings_msg, markup)
return
@bot.message_handler(commands=["list", "lists", "l"])
def list_notes(message: types.Message, list: str = "Default", edit: bool = False): def list_notes(message: types.Message, list: str = "Default", edit: bool = False):
notes = db.get_notes(message.chat.id, list) notes = db.get_notes(message.chat.id, list)
@@ -202,15 +265,13 @@ def list_notes(message: types.Message, list: str = "Default", edit: bool = False
return return
list_notes = notes["notes"]
notes_msg = "⚡️ <u>Ваши напоминания</u>:\n\n" notes_msg = "⚡️ <u>Ваши напоминания</u>:\n\n"
for i in range(len(list_notes)): for i in range(len(notes)):
notes_msg += f"<b>{i + 1})</b> " notes_msg += f"<b>{i + 1})</b> "
if list_notes[i]["time_notif"]: if notes[i]["remind_at"]:
notes_msg += f" ⌚️ <b>{datetime.strptime(list_notes[i]['time_notif'], '%Y-%m-%d %H:%M:%S').strftime('%d %B %Y')}:</b>\n" notes_msg += f" ⌚️ <b>{notes[i]['remind_at'].strftime('%d %B %Y')}:</b>\n"
notes_msg += f"{list_notes[i]['text']}\n\n" notes_msg += f"{notes[i]['content']}\n\n"
markup = types.InlineKeyboardMarkup() markup = types.InlineKeyboardMarkup()
markup.add( markup.add(
@@ -228,6 +289,11 @@ def list_notes(message: types.Message, list: str = "Default", edit: bool = False
msg = send_message(message, notes_msg, markup) msg = send_message(message, notes_msg, markup)
reaction = types.ReactionTypeEmoji(random.choice(list_reactions))
bot.set_message_reaction(
message.chat.id, message.message_id, [reaction], is_big=True
)
old_msg_id = db.new_message(msg) old_msg_id = db.new_message(msg)
if old_msg_id: if old_msg_id:
@@ -242,14 +308,37 @@ def text_message(message: types.Message):
return # ignore messages from supergroups return # ignore messages from supergroups
if db.check_user(message.chat.id) is None: if not db.check_user(message.chat.id):
db.new_user(message) db.new_user(message)
message.text = message.text.replace(f"{bot_username}", "").strip()
if not message.text: if not message.text:
return
msg_text = message.text
msg_entities = message.entities
if not message.text.replace(f"{bot_username}", "").strip():
if not message.reply_to_message: if not message.reply_to_message:
return return
message.text = message.reply_to_message.text msg_text = message.reply_to_message.text
msg_entities = message.reply_to_message.entities
message = message.reply_to_message
if msg_entities:
text = msg_text
html_parts = []
last_idx = 0
for ent in msg_entities:
if ent.type == "text_link":
html_parts.append(text[last_idx : ent.offset])
link_text = text[ent.offset : ent.offset + ent.length]
html_parts.append(f'<a href="{ent.url}">{link_text}</a>')
last_idx = ent.offset + ent.length
html_parts.append(text[last_idx:])
msg_text = "".join(html_parts)
msg_text = msg_text.replace(f"{bot_username}", "").strip()
date_patterns = [ date_patterns = [
r"\b\d{1,2}\s(?:января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)\b", r"\b\d{1,2}\s(?:января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)\b",
@@ -298,7 +387,7 @@ def text_message(message: types.Message):
date_found_dt = None date_found_dt = None
for pattern in date_patterns: for pattern in date_patterns:
match = re.search(pattern, message.text, re.IGNORECASE) match = re.search(pattern, msg_text, re.IGNORECASE)
if match: if match:
date_found_dt = translate_date_to_datetime(match.group()) date_found_dt = translate_date_to_datetime(match.group())
@@ -310,10 +399,15 @@ def text_message(message: types.Message):
db.add_note( db.add_note(
message.chat.id, message.chat.id,
message.text, msg_text,
date_found_dt, date_found_dt,
) )
reaction = types.ReactionTypeEmoji(random.choice(list_reactions))
bot.set_message_reaction(
message.chat.id, message.message_id, [reaction], is_big=True
)
send_message(message, "📝 Напоминание добавлено:") send_message(message, "📝 Напоминание добавлено:")
list_notes(message) list_notes(message)
@@ -328,6 +422,8 @@ def send_message(
if not thread_id: if not thread_id:
thread_id = message.message_thread_id thread_id = message.message_thread_id
msg = None
try: try:
msg = bot.send_message( msg = bot.send_message(
chat_id=id, chat_id=id,
@@ -371,13 +467,13 @@ if __name__ == "__main__":
chat_id, list, ind_note = db.check_old_notes() chat_id, list, ind_note = db.check_old_notes()
if chat_id: if chat_id:
note = db.get_notes(chat_id, list)["notes"][ind_note] note = db.get_notes(chat_id, list)[ind_note]
db.delete_note(chat_id, ind_note, list) db.delete_note(chat_id, ind_note, list)
msg = bot.send_message( msg = bot.send_message(
chat_id, chat_id,
f"{note['text']} \n(Уведомление: {datetime.strptime(note['time_notif'], '%Y-%m-%d %H:%M:%S').strftime('%d %B %Y')})", f"{note['content']} \n(Уведомление: {note['remind_at'].strftime('%d %B %Y')})",
timeout=1, timeout=1,
) )