|
|
@ -9,13 +9,12 @@ from sqlalchemy import create_engine |
|
|
|
from sqlalchemy import Column, Integer, String, DateTime |
|
|
|
from sqlalchemy import Column, Integer, String, DateTime |
|
|
|
from sqlalchemy.orm import declarative_base, sessionmaker |
|
|
|
from sqlalchemy.orm import declarative_base, sessionmaker |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
DELAY_TIME = 1 |
|
|
|
DELAY_TIME = 1 |
|
|
|
DELAY_TIME_Q = 3 |
|
|
|
DELAY_TIME_Q = 3 |
|
|
|
CHAT_ID = "@gorgorod_information" |
|
|
|
CHAT_ID = -1001612776177 |
|
|
|
ALLOWED_USERS = [106693654, 7063133] |
|
|
|
ALLOWED_USERS = [106693654, 7063133] |
|
|
|
ADMINS = [106693654, 7063133] |
|
|
|
ADMINS = [106693654, 7063133, 4978608] |
|
|
|
API_TOKEN = os.getenv("TELEGRAM_API_TOKEN") |
|
|
|
API_TOKEN = os.getenv("TELEGRAM_API_TOKEN") |
|
|
|
bot = Bot(token=API_TOKEN) |
|
|
|
bot = Bot(token=API_TOKEN) |
|
|
|
dp = Dispatcher(bot) |
|
|
|
dp = Dispatcher(bot) |
|
|
@ -56,9 +55,29 @@ class Token(Base): |
|
|
|
return False |
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
def __repr__(self): |
|
|
|
def __repr__(self): |
|
|
|
|
|
|
|
"""Базовое представление класса.""" |
|
|
|
return f"{self.id}: {self.token} | {self.expire}" |
|
|
|
return f"{self.id}: {self.token} | {self.expire}" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Messages_to_delete(Base): |
|
|
|
|
|
|
|
"""Сообщения, которые нужно будет удалить.""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
__tablename__ = "messages_to_delete" |
|
|
|
|
|
|
|
id = Column(Integer, primary_key=True) |
|
|
|
|
|
|
|
message_id = Column(Integer, nullable=False) |
|
|
|
|
|
|
|
deletion_date = Column(DateTime, nullable=False) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deletion_needed(self) -> bool: |
|
|
|
|
|
|
|
"""Нужно ли удалить это сообщение. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Мы могли пропустить удаление из-за перезапуска. |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
if datetime.now() > self.deletion_date: |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def auth(func): |
|
|
|
def auth(func): |
|
|
|
async def wrapper(message): |
|
|
|
async def wrapper(message): |
|
|
|
users_list: Allowed_user = ( |
|
|
|
users_list: Allowed_user = ( |
|
|
@ -77,10 +96,18 @@ def auth(func): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def clean_up(message_id: int, delay_min: int): |
|
|
|
async def clean_up(message_id: int, delay_min: int): |
|
|
|
|
|
|
|
exp = datetime.now() + timedelta(minutes=delay_min) |
|
|
|
|
|
|
|
msg: Messages_to_delete = Messages_to_delete( |
|
|
|
|
|
|
|
message_id=message_id, deletion_date=exp |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
session.add(msg) |
|
|
|
|
|
|
|
session.commit() |
|
|
|
|
|
|
|
|
|
|
|
await asyncio.sleep(delay_min * 60) |
|
|
|
await asyncio.sleep(delay_min * 60) |
|
|
|
try: |
|
|
|
try: |
|
|
|
await bot.delete_message(chat_id=CHAT_ID, message_id=message_id) |
|
|
|
await bot.delete_message(chat_id=CHAT_ID, message_id=message_id) |
|
|
|
|
|
|
|
session.delete(msg) |
|
|
|
|
|
|
|
session.commit() |
|
|
|
except MessageToDeleteNotFound: |
|
|
|
except MessageToDeleteNotFound: |
|
|
|
print("Ошибка удаления сообщения") |
|
|
|
print("Ошибка удаления сообщения") |
|
|
|
|
|
|
|
|
|
|
@ -88,8 +115,10 @@ async def clean_up(message_id: int, delay_min: int): |
|
|
|
@dp.message_handler(commands=["start", "help"]) |
|
|
|
@dp.message_handler(commands=["start", "help"]) |
|
|
|
@auth |
|
|
|
@auth |
|
|
|
async def send_welcome(message: types.Message): |
|
|
|
async def send_welcome(message: types.Message): |
|
|
|
|
|
|
|
|
|
|
|
await message.reply( |
|
|
|
await message.reply( |
|
|
|
"Бот для отправки новостей\n\n" "/mes для отправки сообщения\n", reply=False |
|
|
|
"Бот для взаимодействия с группой\n\n" "/q - для отправки вопроса\n", |
|
|
|
|
|
|
|
reply=False, |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -109,7 +138,7 @@ async def send_to_chanel(message: types.Message): |
|
|
|
await clean_up(message_id=result.message_id, delay_min=DELAY_TIME) |
|
|
|
await clean_up(message_id=result.message_id, delay_min=DELAY_TIME) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dp.message_handler(commands=["question"]) |
|
|
|
@dp.message_handler(commands=["q"]) |
|
|
|
@auth |
|
|
|
@auth |
|
|
|
async def send_question(message: types.Message): |
|
|
|
async def send_question(message: types.Message): |
|
|
|
"""Отправить вопрос через бота. |
|
|
|
"""Отправить вопрос через бота. |
|
|
@ -118,12 +147,17 @@ async def send_question(message: types.Message): |
|
|
|
DELAY_TIME_Q минут. |
|
|
|
DELAY_TIME_Q минут. |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
|
""" |
|
|
|
if len(message.text) == len("/question"): |
|
|
|
if len(message.text) == len("/q"): |
|
|
|
await message.reply("Пишешь пусто - делаешь грустно (мне)", reply=False) |
|
|
|
await message.reply( |
|
|
|
|
|
|
|
"Пишешь пусто - делаешь грустно (мне)" |
|
|
|
|
|
|
|
"\nПосле /q надо написать вопрос, вот так:" |
|
|
|
|
|
|
|
"\n\n/q как доехать до Баррикадной?", |
|
|
|
|
|
|
|
reply=False, |
|
|
|
|
|
|
|
) |
|
|
|
return |
|
|
|
return |
|
|
|
|
|
|
|
|
|
|
|
deletion_time = message.date + timedelta(minutes=DELAY_TIME_Q) |
|
|
|
deletion_time = message.date + timedelta(minutes=DELAY_TIME_Q) |
|
|
|
out_text = f"*Внимание, вопрос!*\n\n{message.text[10:]}\n\nБудет удалено в *{deletion_time}*" |
|
|
|
out_text = f"*Внимание, вопрос!*\n\n{message.text[3:]}\n\nБудет удалено в *{deletion_time}*" |
|
|
|
result = await bot.send_message( |
|
|
|
result = await bot.send_message( |
|
|
|
chat_id=CHAT_ID, |
|
|
|
chat_id=CHAT_ID, |
|
|
|
text=out_text, |
|
|
|
text=out_text, |
|
|
@ -148,7 +182,7 @@ async def get_invite(message: types.Message): |
|
|
|
session.commit() |
|
|
|
session.commit() |
|
|
|
|
|
|
|
|
|
|
|
await message.reply( |
|
|
|
await message.reply( |
|
|
|
f"Твой токен: *{token}* \nБудет действителен 5 минут", |
|
|
|
f"Новый токен: *{token}* \nБудет действителен 5 минут\n\nЧтобы вступить в чат напиши боту [@GorgorodBot](https://t.me/GorgorodBot)\n`/add_me {token}`", |
|
|
|
reply=False, |
|
|
|
reply=False, |
|
|
|
parse_mode="Markdown", |
|
|
|
parse_mode="Markdown", |
|
|
|
) |
|
|
|
) |
|
|
@ -192,11 +226,40 @@ async def add_me(message: types.Message): |
|
|
|
reply=False, |
|
|
|
reply=False, |
|
|
|
parse_mode="Markdown", |
|
|
|
parse_mode="Markdown", |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
await asyncio.sleep(10) |
|
|
|
|
|
|
|
with open("welcome_msg.txt", "r") as f: |
|
|
|
|
|
|
|
msg = f.read() |
|
|
|
|
|
|
|
await message.reply(msg, reply=False, parse_mode="Markdown") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dp.message_handler(commands=["wlc"]) |
|
|
|
|
|
|
|
@auth |
|
|
|
|
|
|
|
async def wlc(message: types.Message): |
|
|
|
|
|
|
|
with open("welcome_msg.txt", "r") as f: |
|
|
|
|
|
|
|
msg = f.read() |
|
|
|
|
|
|
|
await message.reply( |
|
|
|
|
|
|
|
msg, reply=False, parse_mode="Markdown", disable_web_page_preview=True |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# https://stackoverflow.com/questions/67637631/create-a-background-process-using-aiogram |
|
|
|
|
|
|
|
async def messages_cleanup() -> None: |
|
|
|
|
|
|
|
msg_list = session.query(Messages_to_delete).order_by(Messages_to_delete.id).all() |
|
|
|
|
|
|
|
while True: |
|
|
|
|
|
|
|
for m in msg_list: |
|
|
|
|
|
|
|
if m.deletion_needed: |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
await bot.delete_message(chat_id=CHAT_ID, message_id=m.message_id) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except MessageToDeleteNotFound: |
|
|
|
|
|
|
|
print("Ошибка удаления сообщения") |
|
|
|
|
|
|
|
await asyncio.sleep(600) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def on_startup(dispatcher: Dispatcher) -> None: |
|
|
|
|
|
|
|
asyncio.create_task(messages_cleanup()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
if __name__ == "__main__": |
|
|
|
# инициализация бд |
|
|
|
|
|
|
|
Base.metadata.create_all(engine) |
|
|
|
Base.metadata.create_all(engine) |
|
|
|
# print(session.query(Token).order_by(Token.id).all()) |
|
|
|
executor.start_polling(dp, skip_updates=True, on_startup=on_startup) |
|
|
|
# проверить, все ли сообщения удалены |
|
|
|
|
|
|
|
executor.start_polling(dp, skip_updates=True) |
|
|
|
|
|
|
|