Увидел в телеграме одного бота - Dialog Spy Bot, и мне стало интересно как это реализовать
Немного о боте из примера
Бот с примера отправляет уведомления об удалении/редактировании сообщений из лички. Данным ботом я не стал пользоваться, так как необходимо дать доступ к чтению сообщений на своем аккаунте, а также с помощью него можно выкачивать все медиа и файлы из диалогов, поэтому не рискуем и сделаем все сами
Как это работает?
Пользователям с Телеграм Премиум доступна функция подключения бизнес-ботов к своему аккаунту, чтобы допустим сразу отвечать заказчикам и клиентам. Бот с бизнес-модом получает и обрабатывает сообщения пользователя, в реальном времени замечает изменения и удаления. Этого достаточно, чтобы реализовать то зачем мы здесь собрались
Почему не стоит реализовывать это без Business mode (через сессии)?
Кратко - у telegram api есть много ограничений, в том числе и floodwait (ограничение на запросы по времени). Также если будет много запросов к их апи - можно получить бан аккаунта. Клиенты вроде ayugram работают не через api (это чисто клиентская часть, удаленные сообщения сохраняются локально), поэтому их не стоит сравнивать с данным методом. А еще такие клиенты не сохраняют удаленные сообщения пока вы оффлайн, в отличии от нашего бота
Итог. Что у нас получилось?
Теперь нам приходит в бота удаление и редактирование сообщений из любой личной переписки с нами, и не нужно никаких сторонних клиентов телеграм
Немного о боте из примера
Бот с примера отправляет уведомления об удалении/редактировании сообщений из лички. Данным ботом я не стал пользоваться, так как необходимо дать доступ к чтению сообщений на своем аккаунте, а также с помощью него можно выкачивать все медиа и файлы из диалогов, поэтому не рискуем и сделаем все сами
Как это работает?
Пользователям с Телеграм Премиум доступна функция подключения бизнес-ботов к своему аккаунту, чтобы допустим сразу отвечать заказчикам и клиентам. Бот с бизнес-модом получает и обрабатывает сообщения пользователя, в реальном времени замечает изменения и удаления. Этого достаточно, чтобы реализовать то зачем мы здесь собрались
Почему не стоит реализовывать это без Business mode (через сессии)?
Кратко - у telegram api есть много ограничений, в том числе и floodwait (ограничение на запросы по времени). Также если будет много запросов к их апи - можно получить бан аккаунта. Клиенты вроде ayugram работают не через api (это чисто клиентская часть, удаленные сообщения сохраняются локально), поэтому их не стоит сравнивать с данным методом. А еще такие клиенты не сохраняют удаленные сообщения пока вы оффлайн, в отличии от нашего бота
Переходим в https://t.me/BotFather и отправляем команду /newbot, затем пишем название вашего бота и юзернейм

После этого пишем /mybots и выбираем только что созданного бота, переходим в "Bot Settings". Далее находим "Business Mode" и включаем его



Мы включили бизнес-мод в нашем боте. Не забываем прописать /start, чтобы он мог нам писать

После этого пишем /mybots и выбираем только что созданного бота, переходим в "Bot Settings". Далее находим "Business Mode" и включаем его



Мы включили бизнес-мод в нашем боте. Не забываем прописать /start, чтобы он мог нам писать
Заходим на сайт https://www.python.org/downloads/ и скачиваем python, выбирайте любой из свежих версий. Прямая ссылка на установку для windows: https://www.python.org/ftp/python/3.14.2/python-3.14.2-amd64.exe. Поставьте галочку "add to path" когда откроется установочное окно
После установки открываем командную строку (win + r, затем в поле ввода пишем "cmd") и вставляем команду:
pip install pyTelegramBotAPI
Код
После установки открываем командную строку (win + r, затем в поле ввода пишем "cmd") и вставляем команду:
pip install pyTelegramBotAPI
Код
Код:
pip install pyTelegramBotAPI
Теперь создаем папку где вам удобно, а в нем файл с расширением .py и вставляем этот код:
import asyncio
from datetime import datetime
from telebot.async_telebot import AsyncTeleBot
from telebot.types import BusinessMessagesDeleted
from html import escape
TOKEN = "Токен"
OWNER_ID = 00000000 # твой Telegram ID
bot = AsyncTeleBot(TOKEN, parse_mode="HTML")
MESSAGES = {}
def base_record(msg):
return {
"user": msg.from_user.first_name if msg.from_user else "Пользователь",
"type": msg.content_type,
"timestamp": datetime.now().isoformat(timespec="seconds"),
}
@bot.business_message_handler(content_types=[
"text", "photo", "voice", "video",
"video_note", "animation", "sticker"
])
async def handle_message(msg):
key = (msg.chat.id, msg.message_id)
record = base_record(msg)
if msg.content_type == "text":
record["content"] = msg.text
elif msg.content_type == "photo":
record["file_id"] = msg.photo[-1].file_id
record["caption"] = msg.caption
elif msg.content_type == "video":
record["file_id"] = msg.video.file_id
record["caption"] = msg.caption
elif msg.content_type == "animation":
record["file_id"] = msg.animation.file_id
record["caption"] = msg.caption
elif msg.content_type == "video_note":
record["file_id"] = msg.video_note.file_id
elif msg.content_type == "voice":
record["file_id"] = msg.voice.file_id
elif msg.content_type == "sticker":
record["file_id"] = msg.sticker.file_id
MESSAGES[key] = record
@bot.edited_business_message_handler(content_types=["text"])
async def handle_edit(msg):
key = (msg.chat.id, msg.message_id)
old_record = MESSAGES.get(key)
if old_record and old_record.get("type") == "text":
user = old_record.get("user")
old_text = escape(old_record.get("content", ""))
new_text = escape(msg.text or "")
await bot.send_message(
OWNER_ID,
f"<b> {user} изменил(а) сообщение:</b>\n\n"
f"<b>Было:</b>\n<blockquote>{old_text}</blockquote>\n\n"
f"<b>Стало:</b>\n<blockquote>{new_text}</blockquote>"
)
MESSAGES[key] = {
"user": msg.from_user.first_name if msg.from_user else "Пользователь",
"type": "text",
"content": msg.text
}
@bot.deleted_business_messages_handler()
async def handle_delete(event: BusinessMessagesDeleted):
chat = event.chat
for msg_id in event.message_ids:
key = (chat.id, msg_id)
record = MESSAGES.pop(key, None)
if not record:
continue
user = record.get("user", "Пользователь")
msg_type = record.get("type")
file_id = record.get("file_id")
if msg_type == "text":
text = escape(record.get("content", ""))
await bot.send_message(
OWNER_ID,
f"<b> {user} удалил(а) сообщение:</b>\n\n"
f"<blockquote>{text}</blockquote>"
)
elif msg_type == "photo":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) фото:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) фото</b>"
await bot.send_photo(OWNER_ID, file_id, caption=caption)
elif msg_type == "video":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) видео:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) видео</b>"
await bot.send_video(OWNER_ID, file_id, caption=caption)
elif msg_type == "animation":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) GIF:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) GIF</b>"
await bot.send_animation(OWNER_ID, file_id, caption=caption)
elif msg_type == "video_note":
await bot.send_video_note(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) видеосообщение</b>"
)
elif msg_type == "voice":
await bot.send_voice(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) голосовое сообщение</b>"
)
elif msg_type == "sticker":
await bot.send_sticker(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) стикер</b>"
)
async def main():
print("Бот запущен")
await bot.infinity_polling(
allowed_updates=[
"business_message",
"edited_business_message",
"deleted_business_messages"
],
skip_pending=True
)
if __name__ == "__main__":
asyncio.run(main())
Python
В коде на 7 и 8 строке обязательно заполняем поля. В 7 строку вставляем токен нашего бота, в 8 строку вставляем ваш user id телеграм (свой айди можете узнать в этом телеграм боте - @UserInfeBot).
После этого в поле с директорией папки пишем cmd (чтобы в ручную не идти в директорию через cd)

В консоли пишем "python main.py" (вместо main.py у вас может быть другое название файла, смотря как назвали). Если увидели "Бот запущен" - вы успешно запустили бота

import asyncio
from datetime import datetime
from telebot.async_telebot import AsyncTeleBot
from telebot.types import BusinessMessagesDeleted
from html import escape
TOKEN = "Токен"
OWNER_ID = 00000000 # твой Telegram ID
bot = AsyncTeleBot(TOKEN, parse_mode="HTML")
MESSAGES = {}
def base_record(msg):
return {
"user": msg.from_user.first_name if msg.from_user else "Пользователь",
"type": msg.content_type,
"timestamp": datetime.now().isoformat(timespec="seconds"),
}
@bot.business_message_handler(content_types=[
"text", "photo", "voice", "video",
"video_note", "animation", "sticker"
])
async def handle_message(msg):
key = (msg.chat.id, msg.message_id)
record = base_record(msg)
if msg.content_type == "text":
record["content"] = msg.text
elif msg.content_type == "photo":
record["file_id"] = msg.photo[-1].file_id
record["caption"] = msg.caption
elif msg.content_type == "video":
record["file_id"] = msg.video.file_id
record["caption"] = msg.caption
elif msg.content_type == "animation":
record["file_id"] = msg.animation.file_id
record["caption"] = msg.caption
elif msg.content_type == "video_note":
record["file_id"] = msg.video_note.file_id
elif msg.content_type == "voice":
record["file_id"] = msg.voice.file_id
elif msg.content_type == "sticker":
record["file_id"] = msg.sticker.file_id
MESSAGES[key] = record
@bot.edited_business_message_handler(content_types=["text"])
async def handle_edit(msg):
key = (msg.chat.id, msg.message_id)
old_record = MESSAGES.get(key)
if old_record and old_record.get("type") == "text":
user = old_record.get("user")
old_text = escape(old_record.get("content", ""))
new_text = escape(msg.text or "")
await bot.send_message(
OWNER_ID,
f"<b> {user} изменил(а) сообщение:</b>\n\n"
f"<b>Было:</b>\n<blockquote>{old_text}</blockquote>\n\n"
f"<b>Стало:</b>\n<blockquote>{new_text}</blockquote>"
)
MESSAGES[key] = {
"user": msg.from_user.first_name if msg.from_user else "Пользователь",
"type": "text",
"content": msg.text
}
@bot.deleted_business_messages_handler()
async def handle_delete(event: BusinessMessagesDeleted):
chat = event.chat
for msg_id in event.message_ids:
key = (chat.id, msg_id)
record = MESSAGES.pop(key, None)
if not record:
continue
user = record.get("user", "Пользователь")
msg_type = record.get("type")
file_id = record.get("file_id")
if msg_type == "text":
text = escape(record.get("content", ""))
await bot.send_message(
OWNER_ID,
f"<b> {user} удалил(а) сообщение:</b>\n\n"
f"<blockquote>{text}</blockquote>"
)
elif msg_type == "photo":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) фото:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) фото</b>"
await bot.send_photo(OWNER_ID, file_id, caption=caption)
elif msg_type == "video":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) видео:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) видео</b>"
await bot.send_video(OWNER_ID, file_id, caption=caption)
elif msg_type == "animation":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) GIF:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) GIF</b>"
await bot.send_animation(OWNER_ID, file_id, caption=caption)
elif msg_type == "video_note":
await bot.send_video_note(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) видеосообщение</b>"
)
elif msg_type == "voice":
await bot.send_voice(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) голосовое сообщение</b>"
)
elif msg_type == "sticker":
await bot.send_sticker(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) стикер</b>"
)
async def main():
print("Бот запущен")
await bot.infinity_polling(
allowed_updates=[
"business_message",
"edited_business_message",
"deleted_business_messages"
],
skip_pending=True
)
if __name__ == "__main__":
asyncio.run(main())
Python
Код:
import asyncio
from datetime import datetime
from telebot.async_telebot import AsyncTeleBot
from telebot.types import BusinessMessagesDeleted
from html import escape
TOKEN = "Токен"
OWNER_ID = 00000000 # твой Telegram ID
bot = AsyncTeleBot(TOKEN, parse_mode="HTML")
MESSAGES = {}
def base_record(msg):
return {
"user": msg.from_user.first_name if msg.from_user else "Пользователь",
"type": msg.content_type,
"timestamp": datetime.now().isoformat(timespec="seconds"),
}
@bot.business_message_handler(content_types=[
"text", "photo", "voice", "video",
"video_note", "animation", "sticker"
])
async def handle_message(msg):
key = (msg.chat.id, msg.message_id)
record = base_record(msg)
if msg.content_type == "text":
record["content"] = msg.text
elif msg.content_type == "photo":
record["file_id"] = msg.photo[-1].file_id
record["caption"] = msg.caption
elif msg.content_type == "video":
record["file_id"] = msg.video.file_id
record["caption"] = msg.caption
elif msg.content_type == "animation":
record["file_id"] = msg.animation.file_id
record["caption"] = msg.caption
elif msg.content_type == "video_note":
record["file_id"] = msg.video_note.file_id
elif msg.content_type == "voice":
record["file_id"] = msg.voice.file_id
elif msg.content_type == "sticker":
record["file_id"] = msg.sticker.file_id
MESSAGES[key] = record
@bot.edited_business_message_handler(content_types=["text"])
async def handle_edit(msg):
key = (msg.chat.id, msg.message_id)
old_record = MESSAGES.get(key)
if old_record and old_record.get("type") == "text":
user = old_record.get("user")
old_text = escape(old_record.get("content", ""))
new_text = escape(msg.text or "")
await bot.send_message(
OWNER_ID,
f"<b> {user} изменил(а) сообщение:</b>\n\n"
f"<b>Было:</b>\n<blockquote>{old_text}</blockquote>\n\n"
f"<b>Стало:</b>\n<blockquote>{new_text}</blockquote>"
)
MESSAGES[key] = {
"user": msg.from_user.first_name if msg.from_user else "Пользователь",
"type": "text",
"content": msg.text
}
@bot.deleted_business_messages_handler()
async def handle_delete(event: BusinessMessagesDeleted):
chat = event.chat
for msg_id in event.message_ids:
key = (chat.id, msg_id)
record = MESSAGES.pop(key, None)
if not record:
continue
user = record.get("user", "Пользователь")
msg_type = record.get("type")
file_id = record.get("file_id")
if msg_type == "text":
text = escape(record.get("content", ""))
await bot.send_message(
OWNER_ID,
f"<b> {user} удалил(а) сообщение:</b>\n\n"
f"<blockquote>{text}</blockquote>"
)
elif msg_type == "photo":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) фото:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) фото</b>"
await bot.send_photo(OWNER_ID, file_id, caption=caption)
elif msg_type == "video":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) видео:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) видео</b>"
await bot.send_video(OWNER_ID, file_id, caption=caption)
elif msg_type == "animation":
caption_text = record.get("caption")
if caption_text:
caption = (
f" <b>{user} удалил(а) GIF:</b>\n\n"
f"<blockquote>{escape(caption_text)}</blockquote>"
)
else:
caption = f" <b>{user} удалил(а) GIF</b>"
await bot.send_animation(OWNER_ID, file_id, caption=caption)
elif msg_type == "video_note":
await bot.send_video_note(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) видеосообщение</b>"
)
elif msg_type == "voice":
await bot.send_voice(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) голосовое сообщение</b>"
)
elif msg_type == "sticker":
await bot.send_sticker(OWNER_ID, file_id)
await bot.send_message(
OWNER_ID,
f" <b>{user} удалил(а) стикер</b>"
)
async def main():
print("Бот запущен")
await bot.infinity_polling(
allowed_updates=[
"business_message",
"edited_business_message",
"deleted_business_messages"
],
skip_pending=True
)
if __name__ == "__main__":
asyncio.run(main())
После этого в поле с директорией папки пишем cmd (чтобы в ручную не идти в директорию через cd)

В консоли пишем "python main.py" (вместо main.py у вас может быть другое название файла, смотря как назвали). Если увидели "Бот запущен" - вы успешно запустили бота

Итог. Что у нас получилось?
Теперь нам приходит в бота удаление и редактирование сообщений из любой личной переписки с нами, и не нужно никаких сторонних клиентов телеграм





Комментарии 0