README.md

maxbot

Crates.io Documentation License: MIT

Rust-библиотека для создания ботов на платформе MAX
API: https://dev.max.ru/docs-api

Библиотека предоставляет удобный, асинхронный и типобезопасный интерфейс ко всем методам API MAX: отправка сообщений (с разбиением длинного текста), загрузка файлов, управление чатами и участниками, inline-клавиатуры, обработка callback-запросов, webhook/long polling, диспетчер событий и многое другое.

Важно: API MAX доступен только для российских юридических лиц и индивидуальных предпринимателей. Для получения токена бота обратитесь к документации MAX https://business.max.ru/self.


📦 Установка

Добавьте в Cargo.toml:

[dependencies]
maxbot = "2.0"
tokio = { version = "1", features = ["full"] }

🚀 Быстрый старт

1. Пропишите полученный токен доступа к боту

export MAXBOT_TOKEN="ваш_токен"

2. Создайте клиент работы с MAX

use maxbot::MaxClient;

let client = MaxClient::from_env().expect("Токен не найден");

Перед началом работы убедитесь, что бот активен и токен корректен.

let me = client.get_me().await?;
println!("is_bot: {}", me.user.is_bot);

3. Узнайте идентификатор своей группы (chat_id)

Для отправки сообщений в группу необходимо знать её числовой идентификатор chat_id.
Важное обновление: с июня 2026 года метод GET /chats больше не поддерживается.
Получить chat_id можно только через события, которые приходят при добавлении бота в чат или при старте бота.

Алгоритм получения chat_id:

  1. Создайте подписку на события (см. раздел «Webhook» или используйте Long Polling).
  2. Подпишитесь на события bot_added и/или bot_startedupdate_types).
  3. При получении события сохраните chat_id из поля события.
  4. Используйте сохранённый chat_id для всех вызовов API.

Вот минимальный пример бота, который при добавлении в чат выводит его chat_id и сохраняет его:

use maxbot::{Dispatcher, MaxClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let bot = MaxClient::from_env().expect("MAXBOT_TOKEN not set");
    let mut dp = Dispatcher::new(bot);

    // Обработчик добавления бота в чат — получаем chat_id
    dp.on_bot_added(|ctx| async move {
        if let Some(chat_id) = ctx.chat_id() {
            println!("Бот добавлен в чат с ID: {}", chat_id);
            // Здесь можно сохранить chat_id в БД или файл
            ctx.reply_text(&format!("Привет! Мой ID в этом чате: {}", chat_id)).await?;
        }
        Ok(())
    });

    // Также можно обработать команду /start, чтобы получить chat_id в личке
    dp.on_command("/start", |ctx| async move {
        if let Some(chat_id) = ctx.chat_id() {
            ctx.reply_text(&format!("Ваш chat_id: {}", chat_id)).await?;
        } else {
            ctx.reply_text("Не удалось определить chat_id").await?;
        }
        Ok(())
    });

    println!("Бот запущен. Нажмите Ctrl+C для остановки.");
    dp.start_polling().await;
    Ok(())
}

Если вы используете Webhook, обработка событий аналогична – в обработчике BotAdded или BotStarted вы получите chat_id.

Важно: Задача сбора, хранения и поддержки идентификаторов теперь лежит на разработчике. Вы можете использовать любое хранилище (файл, SQLite, PostgreSQL, Redis и т.д.).

4. Отправьте простое сообщение через построитель

use maxbot::{MaxClient, SendMessageParamsBuilder};

let mids = client.send_message_builder(
    SendMessageParamsBuilder::new()
        .text("Привет, чат!")
        .chat_id(chat_id)
).await?;
println!("Сообщение отправлено, ID: {:?}", mids);

5. Можно использовать диспетчер для обработки событий

use maxbot::{Dispatcher, MaxClient, SendMessageParamsBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let bot = MaxClient::from_env().expect("MAXBOT_TOKEN not set");
    let mut dp = Dispatcher::new(bot);

    dp.on_command("/start", |ctx| async move {
        ctx.reply_markdown("Привет! Я эхо-бот. Отправь мне любое сообщение.").await?;
        Ok(())
    });

    dp.on_message(|ctx| async move {
        if let Some(text) = ctx.text() {
            ctx.reply_text(text).await?;
        }
        Ok(())
    });

    dp.start_polling().await;
    Ok(())
}

6. Отправьте сообщение с inline-клавиатурой и обработайте нажатие

use maxbot::{
    MaxClient, SendMessageParamsBuilder, Attachment,
    InlineKeyboardBuilder, InlineKeyboardButton, GetUpdatesParams,
};

// Отправка сообщения с клавиатурой
let keyboard = InlineKeyboardBuilder::new()
    .button(InlineKeyboardButton::link("е1.ru", "https://www.e1.ru"))
    .button(InlineKeyboardButton::callback("Щёлк!", "my_payload"))
    .button(InlineKeyboardButton::clipboard("Скопировать код", "SECRET"))
    .build()?;

let mids = client.send_message_builder(
    SendMessageParamsBuilder::new()
        .text("Выбери действие:")
        .chat_id(chat_id)
        .attachment(Attachment::inline_keyboard(keyboard))
).await?;

// Ожидание callback
let params = GetUpdatesParams {
    marker: None,
    limit: Some(10),
    timeout: Some(30),
    types: vec!["message_callback".to_string()],
};
let (updates, _) = client.get_updates(params).await?;
for update in updates {
    if let Some(cb) = update.callback {
        // Ответ на нажатие: заменяем сообщение и показываем уведомление
        client.answer_callback_query(&cb.callback_id, new_message_json, Some("Нажато!")).await?;
    }
}

7. Отправка файла (изображения, видео, аудио, документа)

use maxbot::{Attachment, SendMessageParamsBuilder};

// Из локального файла
let builder = SendMessageParamsBuilder::new()
    .text("Вот изображение")
    .chat_id(chat_id)
    .attachment(Attachment::image_local("cat.jpg"));

// Или по прямому URL
let builder = SendMessageParamsBuilder::new()
    .text("Картинка по ссылке")
    .chat_id(chat_id)
    .attachment(Attachment::image_url("https://example.com/image.jpg"));

client.send_message_builder(builder).await?;

8. Настройка прокси

Библиотека поддерживает использование прокси-сервера, что полезно для обхода блокировок МАКС в других странах или использования корпоративных шлюзов.

Установка прокси для всех экземпляров MaxClient:

maxbot::set_global_proxy(Some("http://user:pass@proxy.example.com:8080"));
// или отключить:
maxbot::set_global_proxy(None);

Если вам нужно определить прокси только для конкретного клиента, используйте метод set_proxy:

let mut client = MaxClient::from_env().unwrap();
client.set_proxy(Some("socks5://127.0.0.1:1080"));

Поддерживаются схемы http://, https://, socks5://. Формат строки прокси соответствует reqwest::Proxy::all().

9. 🔒 Настройка SSL-сертификатов

С 25 мая 2026 года API MAX требует использования сертификата, выпущенного Минцифры России. Если ваш сервер не доверяет этому сертификату (например, из-за устаревшего списка корневых сертификатов), вы можете временно отключить проверку SSL-сертификатов.

Важно: Отключение проверки SSL снижает безопасность соединения. Используйте этот способ только для отладки или пока не сможете обновить сертификаты на вашей системе.

Глобальное отключение (для всех клиентов)

use maxbot::set_global_ignore_ssl_errors;

set_global_ignore_ssl_errors(true);
let client = MaxClient::from_env()?; // будет использовать игнорирование SSL

Локальное отключение (для конкретного клиента)

let mut client = MaxClient::new("token");
client.set_ignore_ssl_errors(true); // только для этого клиента

Если вы хотите вернуться к стандартной проверке, вызовите те же методы с false.


Обратите внимание: базовый URL API изменён на https://platform-api2.max.ru. Библиотека использует его по умолчанию. Если вам нужен старый адрес, используйте:

set_global_base_url("https://platform-api.max.ru");
// или client.set_base_url("https://platform-api.max.ru")

🍃 Простые методы отправки

Для самых частых задач есть удобные сокращённые методы (типаж MaxClientSimpleExt):

use maxbot::{MaxClient, MaxClientSimpleExt};

let client = MaxClient::from_env().unwrap();
let chat_id = 123456789;

// Простой текст
client.send_plain_text_to_chat(chat_id, "Привет!").await?;

// Markdown
client.send_markdown_to_chat(chat_id, "**bold** и *italic*").await?;

// HTML
client.send_html_to_chat(chat_id, "<b>bold</b> и <i>italic</i>").await?;

// Изображение с подписью
client.send_image_to_chat(chat_id, "cat.jpg".as_ref(), Some("Кот")).await?;

// Видео
client.send_video_to_chat(chat_id, "video.mp4".as_ref(), None).await?;

// Стикер
client.send_sticker_to_chat(chat_id, "154ed15bb").await?;

// Геолокация
client.send_location_to_chat(chat_id, 55.7558, 37.6176).await?;

// Клавиатура
let kb = InlineKeyboardBuilder::new()
    .button(InlineKeyboardButton::callback("Нажми", "data"))
    .build()?;
client.send_keyboard_to_chat(chat_id, "Выбери:", kb).await?;

📎 Inline‑клавиатура

Библиотека поддерживает два подхода к построению клавиатур:

  • Явное управление строками – методы row(), button(), buttons(), new_row().
  • Автоматическое распределениеpush_button() и push_buttons().

Автоматическое распределение соблюдает ограничения MAX:

  • до 7 обычных кнопок (callback, message, clipboard) в строке,
  • до 3 кнопок в строке, если среди них есть хотя бы одна специальная (link, open_app, request_contact, request_geo_location).

При превышении ограничения автоматически создаётся новая строка.

use maxbot::{InlineKeyboardBuilder, InlineKeyboardButton};

let keyboard = InlineKeyboardBuilder::new()
    .push_button(InlineKeyboardButton::callback("Да", "yes"))
    .push_button(InlineKeyboardButton::callback("Нет", "no"))
    .push_button(InlineKeyboardButton::callback("Возможно", "maybe"))
    .push_button(InlineKeyboardButton::link("Помощь", "https://xn--90aivcdt6dxbc.xn--p1ai/")) // Новая строка
    .push_button(InlineKeyboardButton::callback("Настройки", "settings"))                     // Добавится в ту же новую строку
    .build()?;

🔒 Проксирование запросов через nginx (безопасное хранение токенов)

По умолчанию библиотека обращается напрямую к API MAX (https://platform-api2.max.ru), и токен бота передаётся в заголовке Authorization каждого запроса. Это означает, что любой разработчик, имеющий доступ к исходному коду или переменным окружения, может увидеть токен.

Проблема: Токен бота — секретная информация. Если вы не хотите раскрывать его всем разработчикам или хранить в файлах конфигурации, можно развернуть собственный прокси-сервер (например, на базе nginx), который будет:

  • Принимать запросы от ботов с базовой HTTP-аутентификацией (логин/пароль).
  • Подменять заголовок Authorization на реальный токен бота MAX.
  • Проксировать запросы к API MAX.

Преимущества:

  • Разработчики работают только со своим личным логином/паролем, не зная токен бота.
  • При увольнении сотрудника или при завершении им работы над проектом достаточно удалить его учётную запись на прокси-сервере.
  • Токен бота хранится только на сервере с nginx.

Пример настройки nginx

Предположим, вы хотите использовать домен https://max.my-russian-company.ru как прокси.

  1. Добавьте пользователей в файл .htpasswd:
htpasswd /etc/nginx/.htpasswd ivanov.i
htpasswd /etc/nginx/.htpasswd petrov.p
  1. Создайте конфигурацию nginx (например, /etc/nginx/sites-available/max-proxy):
# Соответствие имён пользователей из .htpasswd токенам бота
map $remote_user $backend_token {
    default      "";
    "ivanov.i"   "реальный_токен_бота_1";
    "petrov.p"   "реальный_токен_бота_2";
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name max.my-russian-company.ru;

    ssl_certificate /etc/letsencrypt/live/my-russian-company.ru-0001/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-russian-company.ru-0001/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    auth_basic "Restricted access";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass https://platform-api2.max.ru;
        proxy_ssl_verify off;

        proxy_set_header Host platform-api2.max.ru;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Authorization "$backend_token";

        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}
  1. Активируйте конфигурацию и перезапустите nginx:
ln -s /etc/nginx/sites-available/max-proxy /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx

Использование в коде

В вашем приложении нужно указать библиотеке использовать собственный базовый URL (адрес вашего прокси-сервера) и передавать логин/пароль через стандартный заголовок Authorization: Basic .... Библиотека maxbot позволяет это сделать:

use maxbot::{MaxClient, set_global_base_url};

// 1. Устанавливаем глобальный базовый URL (все клиенты будут использовать прокси)
set_global_base_url("https://max.my-russian-company.ru");

// 2. Создаём клиент с токеном базовой авторизации HTTP
let client = MaxClient::new("Basic aXZhbm92Lmk6bXlfc2VjcmV0X3Bhc3N3b3JkMQ==");

// 3. Все дальнейшие вызовы автоматически используют прокси.
let me = client.get_me().await?;

Важно: В этом режиме токен бота нигде в коде не фигурирует — он остаётся только на сервере nginx. Разработчики используют свои личные учётные данные.

Если вам нужно переопределить базовый URL только для конкретного клиента, используйте метод set_base_url:

let mut client = MaxClient::new("Basic cGV0cm92LnA6bXlfc2VjcmV0X3Bhc3N3b3JkMg==");
client.set_base_url("https://max.my-russian-company.ru");

📚 Полная документация API

Все методы сгруппированы в impl MaxClient:

Модуль Методы
bot get_me() – информация о боте
chats get_chat (получение чата по ID), update_chat, delete_chat, leave_chat, get_chat_members, get_chat_members_by_ids, get_chat_admins, add_chat_admin, add_chat_admins, remove_chat_admin, remove_chat_admins, add_chat_members, remove_chat_member, get_bot_member, send_chat_action, get_pinned_message, pin_message, unpin_message
Примечание: метод get_chats (получение списка всех чатов) устарел и удалён с июня 2026. Используйте подписки для получения событий с chat_id.
messages send_messagesend_message_builder), forward_message, delete_message, delete_messages, get_messages, edit_message, edit_multimessage
simple send_plain_text_to_chat, send_markdown_to_chat, send_html_to_chat, send_image_to_chat, send_video_to_chat, send_audio_to_chat, send_file_to_chat, send_sticker_to_chat, send_location_to_chat, send_contact_to_chat, send_share_to_chat, send_keyboard_to_chat, send_plain_text_to_user, send_markdown_to_user, send_html_to_user, send_image_to_user, send_video_to_user, send_audio_to_user, send_file_to_user, send_sticker_to_user, send_location_to_user, send_contact_to_user, send_share_to_user, send_keyboard_to_user
videos get_video_info, download_video
uploads upload_file – загрузка файла и получение токена
updates get_updates, answer_callback_query
subscriptions get_subscriptions, create_subscription, delete_subscription

Все методы асинхронны, используют reqwest и автоматически соблюдают лимит 30 запросов в секунду (rate limiting). Длинные тексты разбиваются на фрагменты до 4000 символов с сохранением целостности слов и предложений.


📡 Обработка событий (Dispatcher)

Dispatcher позволяет регистрировать обработчики для всех типов событий, поддерживаемых API MAX. Ниже приведена полная таблица соответствия:

Событие (из документации MAX) Фильтр в библиотеке Метод регистрации Описание
message_created Message on_message Новое сообщение или публикация
message_edited EditedMessage on_edited_message Редактирование сообщения
message_removed MessageRemoved on_message_removed Удаление сообщения
message_callback Callback on_callback Нажатие на inline-кнопку
bot_started BotStarted on_bot_started Пользователь начал/возобновил диалог с ботом
bot_stopped BotStopped on_bot_stopped Пользователь остановил бота в настройках
bot_added BotAdded on_bot_added Бот добавлен в чат или канал
bot_removed BotRemoved on_bot_removed Бот удалён из чата или канала
user_added UserAdded on_user_added Пользователь добавлен в чат/канал
user_removed UserRemoved on_user_removed Пользователь удалён/покинул чат/канал
chat_title_changed ChatTitleChanged on_chat_title_changed Изменено название чата или канала
dialog_cleared DialogCleared on_dialog_cleared Очистка истории диалога с ботом
dialog_muted DialogMuted on_dialog_muted Отключение уведомлений в диалоге
dialog_unmuted DialogUnmuted on_dialog_unmuted Включение уведомлений в диалоге
dialog_removed DialogRemoved on_dialog_removed Удаление диалога с ботом
Произвольная команда (например, /start) Command(String) on_command Фильтр по тексту команды
Конкретный payload callback’а CallbackPayload(String) on_callback_payload Фильтр по полезной нагрузке кнопки
Любое событие Any on Обработчик всех событий
Пользовательский фильтр Custom on_filter Произвольный фильтр

Пример обработки всех типов событий

use maxbot::{Dispatcher, MaxClient};

let bot = MaxClient::from_env()?;
let mut dp = Dispatcher::new(bot);

// Новое сообщение
dp.on_message(|ctx| async move {
    println!("Новое сообщение от {}", ctx.user_id().unwrap_or(0));
    Ok(())
});

// Редактирование
dp.on_edited_message(|ctx| async move {
    println!("Сообщение отредактировано");
    Ok(())
});

// Удаление сообщения
dp.on_message_removed(|ctx| async move {
    println!("Сообщение удалено");
    Ok(())
});

// Callback
dp.on_callback(|ctx| async move {
    let payload = ctx.update.callback().unwrap().payload;
    println!("Нажата кнопка с payload: {}", payload);
    Ok(())
});

// Бот добавлен в чат – сохраняем chat_id
dp.on_bot_added(|ctx| async move {
    let chat_id = ctx.chat_id().unwrap();
    println!("Бот добавлен в чат {}", chat_id);
    // Сохраняем chat_id в хранилище
    Ok(())
});

// Бот удалён из чата – удаляем chat_id
dp.on_bot_removed(|ctx| async move {
    let chat_id = ctx.chat_id().unwrap();
    println!("Бот удалён из чата {}", chat_id);
    // Удаляем chat_id из хранилища
    Ok(())
});

// Пользователь добавлен
dp.on_user_added(|ctx| async move {
    println!("Пользователь добавлен в чат {}", ctx.chat_id().unwrap());
    Ok(())
});

// Пользователь удалён
dp.on_user_removed(|ctx| async move {
    println!("Пользователь удалён из чата {}", ctx.chat_id().unwrap());
    Ok(())
});

// Изменение названия
dp.on_chat_title_changed(|ctx| async move {
    if let Some(chat_id) = ctx.chat_id() {
        println!("Название чата {} изменено", chat_id);
    }
    Ok(())
});

// События диалога (личные сообщения)
dp.on_bot_stopped(|ctx| async move {
    println!("Бот остановлен пользователем {}", ctx.user_id().unwrap());
    Ok(())
});

dp.on_dialog_cleared(|ctx| async move {
    println!("Диалог очищен пользователем {}", ctx.user_id().unwrap());
    Ok(())
});

dp.on_dialog_muted(|ctx| async move {
    println!("Уведомления отключены в диалоге с {}", ctx.user_id().unwrap());
    Ok(())
});

dp.on_dialog_unmuted(|ctx| async move {
    println!("Уведомления включены в диалоге с {}", ctx.user_id().unwrap());
    Ok(())
});

dp.on_dialog_removed(|ctx| async move {
    println!("Диалог удалён пользователем {}", ctx.user_id().unwrap());
    Ok(())
});

dp.start_polling().await;

🧪 Примеры

Полные примеры в папке examples/:

  • check-bot.rs – проверка работоспособности бота (выводит true или false)
  • me-demo.rs – информация о боте
  • echo-bot.rs – простой эхо-бот
  • dispatcher-task.rs - демонстрация периодических задач
  • fruits-bot.rs – демонстрация бота с обработкой нажатия на кнопки
  • webhook-bot.rs – пример webhook-бота на Actix-web
  • video-info-bot.rs – демонстрация бота с получением информации о видео
  • subscription-chat-collector.rs – сбор chat_id через подписки
  • get-chat-demo.rs – получение информации о групповом чате по известному ID
  • update-chat-demo.rs – изменение информации о групповом чате (название, иконка, закрепление сообщения)
  • delete-chat-demo.rs – удаление группового чата (с обработкой ошибок)
  • leave-chat-demo.rs – выход бота из чата (с фиктивным ID и обработкой ошибки)
  • get-bot-member-demo.rs – информация о членстве бота в групповом чате (права, дата вступления и т.д.)
  • get-chat-members-demo.rs – получение списка участников чата (постранично или по ID)
  • get-chat-admins-demo.rs – получение списка администраторов чата с правами
  • add-chat-admin-demo.rs – назначение одного или нескольких администраторов
  • remove-chat-admin-demo.rs – снятие прав администратора с пользователей
  • get-messages-demo.rs – получение истории сообщений чата (если доступно)
  • send-text-demo.rs – отправка простого текста
  • send-long-text-demo.rs – разбиение длинного текста
  • send-picture-demo.rs – отправка изображения
  • send-picture-only-demo.rs – отправка изображения без текста
  • send-video-demo.rs – отправка видео
  • send-audio-demo.rs – отправка аудио
  • send-file-any-demo.rs – отправка произвольного файла
  • upload-file-demo.rs – предварительная загрузка файла и использование токена
  • get-video-info-demo.rs – получение метаданных видео
  • send-inline-keyboard-demo.rs – сообщение с клавиатурой
  • combined-attachments-demo.rs – все типы вложений (стикер, контакт, гео, ссылка, клавиатура)
  • send-chat-actions-demo.rs – демонстрация отправки действий бота (набор текста, отправка медиа и т.д.)
  • pin-message-demo.rs – закрепление и открепление сообщения
  • forward-demo.rs – пересылка сообщения
  • delete-messages-demo.rs – отправка и удаление
  • edit-message-demo.rs – редактирование сообщения
  • full-demo.rs – комплексная демонстрация большинства возможностей
  • stress-test.rs – стресс-тест ограничения RPS (отправка сообщений до ошибки 429)

Запуск примера:

export MAXBOT_TOKEN="ваш_токен"
export CHAT_ID=-123456789
cargo run --example stress-test -- 10

Для webhook-бота:

cargo run --example webhook-bot --features webhook

🌐 Webhook и подписки

Создание подписки

Для получения обновлений через Webhook необходимо создать подписку:

use maxbot::MaxClient;

let client = MaxClient::from_env()?;
client.create_subscription(
    "https://my-server.com/webhook",
    vec!["message_created".to_string(), "bot_added".to_string()],
    Some("my_secret")
).await?;
  • URL должен быть HTTPS (порт 443 рекомендуется).
  • Сертификат должен быть от доверенного центра (самоподписанные и HTTP больше не принимаются с 25 мая 2026).

Запуск webhook-сервера

use maxbot::{Dispatcher, MaxClient, webhook::WebhookServer};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let bot = MaxClient::from_env().unwrap();
    let mut dp = Dispatcher::new(bot);

    dp.on_message(|ctx| async move {
        ctx.reply_text("Hello from webhook!").await?;
        Ok(())
    });

    WebhookServer::new(dp)
        .secret("my_secret") // должен совпадать с переданным в create_subscription
        .path("/webhook")
        .serve("0.0.0.0:8443") // за прокси, который реализует HTTPS
        .await
}

Получение chat_id через подписки

Для получения идентификаторов чатов, в которые добавлен бот, необходимо:

  1. Создать подписку с update_types, включающими "bot_added" и/или "bot_started".
  2. В обработчике события BotAdded или BotStarted извлечь chat_id.
  3. Сохранить chat_id в своём хранилище (БД, файл, память).
  4. Использовать сохранённые ID для вызовов API.

Пример:

use maxbot::{Dispatcher, MaxClient};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let bot = MaxClient::from_env()?;
    let mut dp = Dispatcher::new(bot);

    dp.on_bot_added(|ctx| async move {
        if let Some(chat_id) = ctx.chat_id() {
            println!("Новый чат: {}", chat_id);
            // Здесь можно сохранить chat_id
        }
        Ok(())
    });

    // Также можно обрабатывать bot_started
    dp.on_bot_started(|ctx| async move {
        if let Some(chat_id) = ctx.chat_id() {
            println!("Бот запущен в чате: {}", chat_id);
        }
        Ok(())
    });

    dp.start_polling().await;
    Ok(())
}

✅ Что уже реализовано

  •  Базовая HTTP-обёртка с rate limiting (30 RPS)
  •  Получение информации о боте (/me)
  •  Управление чатами: получение по ID, обновление (название, иконка, закрепление, уведомления), удаление, выход
  •  Управление участниками: получение списка (постранично и по ID), добавление, удаление
  •  Полное управление администраторами: получение списка, добавление (одного или нескольких с правами и псевдонимом), снятие прав (одного или нескольких)
  •  Отправка сообщений (текст, markdown, html, reply)
  •  Разбиение длинного текста на фрагменты (сохранение целостности слов/предложений)
  •  Отправка файлов (изображения, видео, аудио, документы) — из файла, по токену или по прямому URL
  •  Предварительная загрузка файлов и повторное использование токенов
  •  Получение информации о видео (/videos/{token})
  •  Пересылка сообщений
  •  Удаление сообщений (одиночное и массовое)
  •  Получение истории сообщений чата (/messages)
  •  Редактирование сообщений (одиночных и многофрагментных)
  •  Закрепление/открепление сообщений
  •  Отправка действий бота в чате (typing_on, sending_photo, …)
  •  Long polling (/updates) и диспетчер событий (с фильтрами, on_command, on_message, on_callback и т.д.)
  •  Обработчики старта (on_start) для инициализации перед long polling
  •  Периодические задачи (task) с настраиваемым интервалом
  •  Ответ на callback-запросы (inline-кнопки) – замена сообщения и уведомления
  •  Webhook-подписки (создание, удаление, список) + готовый сервер на Actix-web (параметр сборки webhook)
  •  Удобные Builder’ы для параметров сообщений и клавиатур
  •  Кнопка clipboard (копирование в буфер обмена без callback)
  •  Автоматическое распределение кнопок в inline-клавиатуре с соблюдением ограничений MAX (методы push_button, push_buttons)
  •  Проверка клавиатуры при сборке (максимум строк, кнопок в строке, общее количество)
  •  Простые методы отправки (типаж MaxClientSimpleExt)
  •  Поддержка всех типов вложений: стикеры, контакты, геолокация, share, файлы, изображения, видео, аудио
  •  Полная поддержка всех событий API MAX (BotAdded, BotRemoved, UserAdded, UserRemoved, ChatTitleChanged и др.)

📄 Лицензия

Проект распространяется под лицензией MIT.


🤝 Вклад

Принимаются pull request’ы. Для крупных изменений сначала откройте issue для обсуждения.


🌐 Полезные ссылки

Описание
Конвейеры
0 успешных
0 с ошибкой
Разработчики