April 30, 2024

Создаём бота, который сохраняет удалённые сообщения. + бонус

EDIT 15.02.2025: за последние несколько дней мне написало много людей. Я хочу сказать, что я обновил бота, он теперь работает с фото, видео и с другими вложениями и ещё он теперь работает на node.js + mongodb, пост вы можете прочитать у меня в канале, связаться со мной тут: @codeheroo



Всем привет. Недавно в телеграме появилась возможность добавить чатбота в аккаунт. Мы создадим такого бота. Он будет сохранять все удалённые сообщения в чатах 1 на 1.

  1. Создаём бота в телеграме.
  2. Пишем код.
  3. Подключаем бота к нашему аккаунту.
  4. Проверяем и радуемся.

Создаём бота в ботфазере.

Переходим в телеграме сюда https://t.me/BotFather и создаём бота.

ботфазер даст вам апи токен, сохраните его, мы будем его использовать.

Пишем код для бота.

Я буду писать на C# с использованием библиотеки TelegramBots.

пишем вот это в начало

using Telegram.Bot;

Инициализурем бота, заменяем {YOUR_ACCESS_TOKEN_HERE} на ваш апи токен

var botClient = new TelegramBotClient("{YOUR_ACCESS_TOKEN_HERE}");

время - деньги, копируем кучу кода из их библиотеки, не забываем её прочитать, если вкратце, то это бот, который отвечает на сообщения у них, но мы удалим ту часть, что отправляет сообщение и будет обычный бот, который получает обновления от телеграма

using Telegram.Bot;
using Telegram.Bot.Polling;
using Telegram.Bot.Types.Enums;
using Telegram.Bot.Exceptions;
using Telegram.Bot.Types;

namespace BusinessBot
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            

            var botClient = new TelegramBotClient("{YOUR_ACCESS_TOKEN_HERE}");

            using CancellationTokenSource cts = new();

            // StartReceiving does not block the caller thread. Receiving is done on the ThreadPool.
            ReceiverOptions receiverOptions = new()
            {
                AllowedUpdates = Array.Empty<UpdateType>() // receive all update types except ChatMember related updates
            };

            botClient.StartReceiving(
                updateHandler: HandleUpdateAsync,
                pollingErrorHandler: HandlePollingErrorAsync,
                receiverOptions: receiverOptions,
                cancellationToken: cts.Token
            );

            var me = await botClient.GetMeAsync();

            Console.WriteLine(quot;Start listening for @{me.Username}");
            Console.ReadLine();

            // Send cancellation request to stop bot
            cts.Cancel();

            async Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
            {
                // Only process Message updates: https://core.telegram.org/bots/api#message
                if (update.Message is not { } message)
                    return;
                // Only process text messages
                if (message.Text is not { } messageText)
                    return;

                var chatId = message.Chat.Id;

                Console.WriteLine(quot;Received a '{messageText}' message in chat {chatId}.");

                // Echo received message text
                Message sentMessage = await botClient.SendTextMessageAsync(
                    chatId: chatId,
                    text: "You said:\n" + messageText,
                    cancellationToken: cancellationToken);
            }

            Task HandlePollingErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken)
            {
                var ErrorMessage = exception switch
                {
                    ApiRequestException apiRequestException
                        => quot;Telegram API Error:\n[{apiRequestException.ErrorCode}]\n{apiRequestException.Message}",
                    _ => exception.ToString()
                };

                Console.WriteLine(ErrorMessage);
                return Task.CompletedTask;
            }
        }

    }
}

О, я тут увидел, можно ещё сделать, чтобы оно изменённые сообщения сохраняло, мне такое надо. (напишу в заголовке статьи бонус, это бонус)

оу, а тут получается нужно сохранять все сообщения т.к. телеграм при удалении даёт только айди изменённых и удалённых сообщений.

ну ладно, сделаем базу данных тогда

идём на супабазе (supabase.com), создаём бесплатную базу данных

создаём подключение

string connectionString = quot;тут ваша строка";
NpgsqlConnection connection = new(connectionString);
connection.Open();

создаём таблицу в супабазе и пишем код для обработки подключения и отключения от бота

if (update.BusinessConnection != null)
{
    if (update.BusinessConnection.IsEnabled)
    {
        Console.WriteLine(quot;Connection established! {update.BusinessConnection.UserChatId.ToString()}");
        Message sentMessage = await botClient.SendTextMessageAsync(
            chatId: update.BusinessConnection.UserChatId,
            text: "Connection established!",
            cancellationToken: cancellationToken);
        cmd.CommandText = quot;INSERT INTO connections(user_chat_id) SELECT '{update.BusinessConnection.UserChatId.ToString()}' WHERE NOT EXISTS (SELECT user_chat_id FROM connections WHERE user_chat_id = '{update.BusinessConnection.UserChatId.ToString()}')";
        await cmd.ExecuteNonQueryAsync();
    }
    else
    {
        Console.WriteLine(quot;Connection removed! {update.BusinessConnection.UserChatId.ToString()}");
        Message sentMessage = await botClient.SendTextMessageAsync(
            chatId: update.BusinessConnection.UserChatId,
            text: "Connection removed!",
            cancellationToken: cancellationToken);
        cmd.CommandText = quot;DELETE from connections WHERE user_chat_id = '{update.BusinessConnection.UserChatId.ToString()}'";
        await cmd.ExecuteNonQueryAsync();
    }
    
}

пишем код для сохранения новых сообщений в бд

создаём таблицу для сообщений

потом добавлю ещё полей, но сейчас лень это делать)))

и пишем код для обработки удалений и изменений

if (update.DeletedBusinessMessages != null)
{
    await using var command0 = new NpgsqlCommand(quot;SELECT user_chat_id from connections where id = '{update.DeletedBusinessMessages.BusinessConnectionId}'", connection);
    await using var reader0 = await command0.ExecuteReaderAsync();
    await reader0.ReadAsync();
    string id = reader0.GetString(0);
    await reader0.CloseAsync();
    Console.WriteLine("New deleted message!");

    foreach (int message_id in update.DeletedBusinessMessages.MessageIds)
    {
        await using var command1 = new NpgsqlCommand(quot;SELECT text from messages where message_id = '{message_id}'", connection);
        await using var reader1 = await command1.ExecuteReaderAsync();
        await reader1.ReadAsync();
        Message sentMessage = await botClient.SendTextMessageAsync(
            chatId: id,
            text: quot;Message deleted!\nChat: {update.DeletedBusinessMessages.Chat.Id}\nText: {reader1.GetString(0)}",
            cancellationToken: cancellationToken);
    }
}

if (update.EditedBusinessMessage != null)
{
    await using var command0 = new NpgsqlCommand(quot;SELECT user_chat_id from connections where id = '{update.EditedBusinessMessage.BusinessConnectionId}'", connection);
    await using var reader0 = await command0.ExecuteReaderAsync();
    await reader0.ReadAsync();
    string id = reader0.GetString(0);
    await reader0.CloseAsync();
    Console.WriteLine("New edited message!");

    foreach (int message_id in update.DeletedBusinessMessages.MessageIds)
    {
        await using var command1 = new NpgsqlCommand(quot;SELECT text from messages where message_id = '{message_id}'", connection);
        await using var reader1 = await command1.ExecuteReaderAsync();
        await reader1.ReadAsync();
        Message sentMessage = await botClient.SendTextMessageAsync(
            chatId: id,
            text: quot;Message edited!\nChat: {update.DeletedBusinessMessages.Chat.Id}\nText: {reader1.GetString(0)}",
            cancellationToken: cancellationToken);
    }
}

проверяем и радуемся

этот бот: https://t.me/CodeherooBusinessBot

Ссылка на гитхаб: https://github.com/codeheroo/businessbot/
Мой канал: https://t.me/codeherooo