max_bot_api 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +25 -6
- data/docs/02-listen-and-respond.md +1 -0
- data/docs/04-keyboard.md +5 -0
- data/docs/06-subscriptions.md +2 -0
- data/docs/api/methods.md +59 -0
- data/docs/api/objects.md +134 -0
- data/docs/api/overview.md +73 -0
- data/examples/keyboard.rb +4 -0
- data/examples/webhook_rack.rb +4 -0
- data/lib/max_bot_api/builders/keyboard_builder.rb +10 -0
- data/lib/max_bot_api/builders/message_builder.rb +16 -1
- data/lib/max_bot_api/client.rb +21 -0
- data/lib/max_bot_api/resources/chats.rb +19 -0
- data/lib/max_bot_api/resources/messages.rb +1 -0
- data/lib/max_bot_api/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97114d1ff6c7d35facca9459c0543540867c2d48c6235dd6bb204e47c31a75b3
|
|
4
|
+
data.tar.gz: e7dec618f4d73dae79c33e692478c9dc5c8b06fcc0d3f14949c1178083d15aa3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8fec44603bf0f56f43e865097608bc786a3549ffa6a754d87803eeb0ada8f6851a074d44469c1e9f9e8629d342af908d252d30e0c576a8d701649af7ffdb2022
|
|
7
|
+
data.tar.gz: 7ac3fe1abc5125e7e63d610506ddf100c77b47c40c5bfe5c50ead48eea04b14cd79fc8f2a86e8073ee82eaa8f85212fcf30b2adea1a8fdbdfd56a9ff9694a99c
|
data/README.md
CHANGED
|
@@ -33,10 +33,10 @@ client.messages.send(
|
|
|
33
33
|
|
|
34
34
|
## Features
|
|
35
35
|
|
|
36
|
-
-
|
|
36
|
+
- Broad API coverage: Bots, Chats, Messages, Subscriptions, Uploads, Debugs.
|
|
37
37
|
- Builder helpers for messages and keyboards.
|
|
38
38
|
- Long polling updates with retry and backoff.
|
|
39
|
-
- Webhook parsing
|
|
39
|
+
- Webhook parsing and secret validation helpers.
|
|
40
40
|
- Upload helpers for files, photos, audio, video.
|
|
41
41
|
|
|
42
42
|
## Configuration
|
|
@@ -54,11 +54,10 @@ Notes:
|
|
|
54
54
|
- The client uses `Authorization: <token>` (no `Bearer`).
|
|
55
55
|
- Every request includes `v=<version>` query param.
|
|
56
56
|
|
|
57
|
-
##
|
|
57
|
+
## Changelog
|
|
58
58
|
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- New helpers: `MessageBuilder#add_photo_by_token`, `KeyboardRowBuilder#add_message`.
|
|
59
|
+
- See `CHANGELOG.md` for version-by-version release notes.
|
|
60
|
+
- See `BREAKING_CHANGES_0.1.0_to_0.2.0.md` for the detailed `0.2.0` migration notes.
|
|
62
61
|
|
|
63
62
|
Example:
|
|
64
63
|
|
|
@@ -125,9 +124,29 @@ end
|
|
|
125
124
|
|
|
126
125
|
```ruby
|
|
127
126
|
body = request.body.read
|
|
127
|
+
halt 401 unless client.webhook_secret_valid?(headers: request.env, secret: ENV.fetch("WEBHOOK_SECRET"))
|
|
128
128
|
update = client.parse_webhook(body)
|
|
129
129
|
```
|
|
130
130
|
|
|
131
|
+
### Disable link previews
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
message = MaxBotApi::Builders::MessageBuilder.new
|
|
135
|
+
.set_chat(12345)
|
|
136
|
+
.set_text("https://max.ru")
|
|
137
|
+
.set_disable_link_preview(true)
|
|
138
|
+
|
|
139
|
+
client.messages.send(message)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Pin and unpin chat messages
|
|
143
|
+
|
|
144
|
+
```ruby
|
|
145
|
+
client.chats.pin_message(chat_id: 12345, message_id: "mid123")
|
|
146
|
+
client.chats.get_pinned_message(chat_id: 12345)
|
|
147
|
+
client.chats.unpin_message(chat_id: 12345)
|
|
148
|
+
```
|
|
149
|
+
|
|
131
150
|
## Builders
|
|
132
151
|
|
|
133
152
|
### Keyboard
|
data/docs/04-keyboard.md
CHANGED
|
@@ -20,6 +20,10 @@ keyboard
|
|
|
20
20
|
.add_callback("Picture", "positive", "picture")
|
|
21
21
|
.add_message("Continue")
|
|
22
22
|
|
|
23
|
+
keyboard
|
|
24
|
+
.add_row
|
|
25
|
+
.add_clipboard("Copy docs", "https://dev.max.ru/docs-api/methods/POST/messages")
|
|
26
|
+
|
|
23
27
|
message = MaxBotApi::Builders::MessageBuilder.new
|
|
24
28
|
.set_chat(12345)
|
|
25
29
|
.add_keyboard(keyboard)
|
|
@@ -36,3 +40,4 @@ client.messages.send(message)
|
|
|
36
40
|
- `add_geolocation(text, quick)`
|
|
37
41
|
- `add_open_app(text, app, payload, contact_id)`
|
|
38
42
|
- `add_message(text)`
|
|
43
|
+
- `add_clipboard(text, payload)`
|
data/docs/06-subscriptions.md
CHANGED
data/docs/api/methods.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Методы API
|
|
2
|
+
|
|
3
|
+
Источник: https://dev.max.ru/docs-api
|
|
4
|
+
|
|
5
|
+
Клиент: MaxBotApi Ruby (`lib/max_bot_api/`).
|
|
6
|
+
|
|
7
|
+
## bots
|
|
8
|
+
|
|
9
|
+
| Метод | Путь | Описание | Клиент |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| `GET` | `/me` | Получение информации о боте | да |
|
|
12
|
+
|
|
13
|
+
## chats
|
|
14
|
+
|
|
15
|
+
| Метод | Путь | Описание | Клиент |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
| `GET` | `/chats` | Получение списка всех групповых чатов | да |
|
|
18
|
+
| `DELETE` | `/chats/{chatId}` | Удаление группового чата | нет |
|
|
19
|
+
| `GET` | `/chats/{chatId}` | Получение информации о групповом чате | да |
|
|
20
|
+
| `PATCH` | `/chats/{chatId}` | Изменение информации о групповом чате | да |
|
|
21
|
+
| `POST` | `/chats/{chatId}/actions` | Отправка действия бота в групповой чат | да |
|
|
22
|
+
| `DELETE` | `/chats/{chatId}/members` | Удаление участника из группового чата | частично (нет block) |
|
|
23
|
+
| `GET` | `/chats/{chatId}/members` | Получение участников группового чата | да |
|
|
24
|
+
| `POST` | `/chats/{chatId}/members` | Добавление участников в групповой чат | да |
|
|
25
|
+
| `GET` | `/chats/{chatId}/members/admins` | Получение списка администраторов группового чата | да |
|
|
26
|
+
| `POST` | `/chats/{chatId}/members/admins` | Назначить администратора группового чата | нет |
|
|
27
|
+
| `DELETE` | `/chats/{chatId}/members/admins/{userId}` | Отменить права администратора в групповом чате | нет |
|
|
28
|
+
| `DELETE` | `/chats/{chatId}/members/me` | Удаление бота из группового чата | да |
|
|
29
|
+
| `GET` | `/chats/{chatId}/members/me` | Получение информации о членстве бота в групповом чате | да |
|
|
30
|
+
| `DELETE` | `/chats/{chatId}/pin` | Удаление закреплённого сообщения в групповом чате | да |
|
|
31
|
+
| `GET` | `/chats/{chatId}/pin` | Получение закреплённого сообщения в групповом чате | да |
|
|
32
|
+
| `PUT` | `/chats/{chatId}/pin` | Закрепление сообщения в групповом чате | да |
|
|
33
|
+
|
|
34
|
+
## subscriptions
|
|
35
|
+
|
|
36
|
+
| Метод | Путь | Описание | Клиент |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| `DELETE` | `/subscriptions` | Отписка от обновлений | да |
|
|
39
|
+
| `GET` | `/subscriptions` | Получение подписок | да |
|
|
40
|
+
| `POST` | `/subscriptions` | Подписка на обновления | да (есть version) |
|
|
41
|
+
| `GET` | `/updates` | Получение обновлений | да |
|
|
42
|
+
|
|
43
|
+
## upload
|
|
44
|
+
|
|
45
|
+
| Метод | Путь | Описание | Клиент |
|
|
46
|
+
| --- | --- | --- | --- |
|
|
47
|
+
| `POST` | `/uploads` | Загрузка файлов | да |
|
|
48
|
+
|
|
49
|
+
## messages
|
|
50
|
+
|
|
51
|
+
| Метод | Путь | Описание | Клиент |
|
|
52
|
+
| --- | --- | --- | --- |
|
|
53
|
+
| `POST` | `/answers` | Ответ на callback | да |
|
|
54
|
+
| `DELETE` | `/messages` | Удалить сообщение | да |
|
|
55
|
+
| `GET` | `/messages` | Получение сообщений | да |
|
|
56
|
+
| `POST` | `/messages` | Отправить сообщение | да |
|
|
57
|
+
| `PUT` | `/messages` | � едактировать сообщение | да |
|
|
58
|
+
| `GET` | `/messages/{messageId}` | Получить сообщение | да |
|
|
59
|
+
| `GET` | `/videos/{videoToken}` | Получить информацио о видео | нет |
|
data/docs/api/objects.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Объекты API
|
|
2
|
+
|
|
3
|
+
Источник: https://dev.max.ru/docs-api
|
|
4
|
+
|
|
5
|
+
Всего объектов: 126
|
|
6
|
+
|
|
7
|
+
| Объект | Краткое описание |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `ActionRequestBody` | |
|
|
10
|
+
| `Attachment` | Общая схема, представляющая вложение сообщения |
|
|
11
|
+
| `AttachmentPayload` | |
|
|
12
|
+
| `AttachmentRequest` | Запрос на прикрепление данных к сообщению |
|
|
13
|
+
| `AudioAttachment` | |
|
|
14
|
+
| `AudioAttachmentRequest` | Запрос на прикрепление аудио к сообщению. ДОЛЖЕН быть единственным вложением в сообщении |
|
|
15
|
+
| `BotAddedToChatUpdate` | Вы получите этот update, как только бот будет добавлен в чат |
|
|
16
|
+
| `BotCommand` | до 32 элементов<br/>Команды, поддерживаемые ботом |
|
|
17
|
+
| `BotInfo` | Объект включает общую информацию о боте, URL аватара и описание. Дополнительно содержит список команд, поддерживаемых… |
|
|
18
|
+
| `BotPatch` | |
|
|
19
|
+
| `BotRemovedFromChatUpdate` | Вы получите этот update, как только бот будет удалён из чата |
|
|
20
|
+
| `BotStartedUpdate` | Бот получает этот тип обновления, как только пользователь нажал кнопку `Start` |
|
|
21
|
+
| `BotStoppedUpdate` | Бот получает этот тип обновления, как только пользователь останавливает бота |
|
|
22
|
+
| `Button` | |
|
|
23
|
+
| `Callback` | Объект, отправленный боту, когда пользователь нажимает кнопку |
|
|
24
|
+
| `CallbackAnswer` | Отправьте этот объект, когда ваш бот хочет отреагировать на нажатие кнопки |
|
|
25
|
+
| `CallbackButton` | После нажатия на такую кнопку клиент отправляет на сервер полезную нагрузку, которая содержит |
|
|
26
|
+
| `Chat` | |
|
|
27
|
+
| `ChatAdmin` | |
|
|
28
|
+
| `ChatAdminPermission` | Права администратора чата |
|
|
29
|
+
| `ChatAdminsList` | |
|
|
30
|
+
| `ChatButton` | Кнопка, которая создает новый чат, как только первый пользователь на нее нажмёт. Бот будет добавлен в участники чата… |
|
|
31
|
+
| `ChatList` | |
|
|
32
|
+
| `ChatMember` | Объект включает общую информацию о пользователе или боте, URL аватара и описание (при наличии). Дополнительно содержит… |
|
|
33
|
+
| `ChatMembersList` | |
|
|
34
|
+
| `ChatPatch` | |
|
|
35
|
+
| `ChatStatus` | Статус чата для текущего бота |
|
|
36
|
+
| `ChatTitleChangedUpdate` | Бот получит это обновление, когда будет изменено название чата |
|
|
37
|
+
| `ChatType` | Тип чата: диалог, чат |
|
|
38
|
+
| `ContactAttachment` | |
|
|
39
|
+
| `ContactAttachmentPayload` | |
|
|
40
|
+
| `ContactAttachmentRequest` | Запрос на прикрепление карточки контакта к сообщению. ДОЛЖЕН быть единственным вложением в сообщении |
|
|
41
|
+
| `ContactAttachmentRequestPayload` | |
|
|
42
|
+
| `DataAttachment` | Attachment contains payload sent through `SendMessageButton` |
|
|
43
|
+
| `DialogClearedUpdate` | Бот получает этот тип обновления сразу после очистки истории диалога. |
|
|
44
|
+
| `DialogMutedUpdate` | Вы получите этот update, когда пользователь заглушит диалог с ботом |
|
|
45
|
+
| `DialogRemovedUpdate` | Вы получите этот update, когда пользователь удаляет чат |
|
|
46
|
+
| `DialogUnmutedUpdate` | Вы получите этот update, когда пользователь включит уведомления в диалоге с ботом |
|
|
47
|
+
| `EmphasizedMarkup` | Представляет *курсив* |
|
|
48
|
+
| `Error` | Сервер возвращает это, если возникло исключение при вашем запросе |
|
|
49
|
+
| `FailedUserDetails` | Подробное описание, почему пользователь не был добавлен в чат |
|
|
50
|
+
| `FileAttachment` | |
|
|
51
|
+
| `FileAttachmentPayload` | |
|
|
52
|
+
| `FileAttachmentRequest` | Запрос на прикрепление файла к сообщению. ДОЛЖЕН быть единственным вложением в сообщении |
|
|
53
|
+
| `GetPinnedMessageResult` | |
|
|
54
|
+
| `GetSubscriptionsResult` | Список всех WebHook подписок |
|
|
55
|
+
| `HeadingMarkup` | Представляет заголовок текста |
|
|
56
|
+
| `HighlightedMarkup` | Представляет выделенную часть текста |
|
|
57
|
+
| `Image` | Общая схема, описывающая объект изображения |
|
|
58
|
+
| `InlineKeyboardAttachment` | Кнопки в сообщении |
|
|
59
|
+
| `InlineKeyboardAttachmentRequest` | Запрос на прикрепление клавиатуры к сообщению |
|
|
60
|
+
| `InlineKeyboardAttachmentRequestPayload` | |
|
|
61
|
+
| `Intent` | Намерение кнопки |
|
|
62
|
+
| `Keyboard` | Клавиатура - это двумерный массив кнопок |
|
|
63
|
+
| `LinkButton` | После нажатия на такую кнопку пользователь переходит по ссылке, которую она содержит |
|
|
64
|
+
| `LinkMarkup` | Представляет ссылку в тексте |
|
|
65
|
+
| `LinkedMessage` | |
|
|
66
|
+
| `LocationAttachment` | |
|
|
67
|
+
| `LocationAttachmentRequest` | Запрос на прикрепление клавиатуры к сообщению |
|
|
68
|
+
| `MarkupElement` | |
|
|
69
|
+
| `MediaAttachmentPayload` | |
|
|
70
|
+
| `Message` | Сообщение в чате |
|
|
71
|
+
| `MessageBody` | Схема, представляющая тело сообщения |
|
|
72
|
+
| `MessageButton` | Кнопка для запуска мини-приложения |
|
|
73
|
+
| `MessageCallbackUpdate` | Вы получите этот `update` как только пользователь нажмёт кнопку |
|
|
74
|
+
| `MessageChatCreatedUpdate` | Бот получит это обновление, когда чат будет создан, как только первый пользователь нажмёт кнопку чата |
|
|
75
|
+
| `MessageCreatedUpdate` | ы получите этот `update`, как только сообщение будет создано |
|
|
76
|
+
| `MessageEditedUpdate` | Вы получите этот `update`, как только сообщение будет отредактировано |
|
|
77
|
+
| `MessageLinkType` | Тип связанного сообщения |
|
|
78
|
+
| `MessageList` | Пагинированный список сообщений |
|
|
79
|
+
| `MessageRemovedUpdate` | Вы получите этот `update`, как только сообщение будет удалено |
|
|
80
|
+
| `MessageStat` | Статистика сообщения |
|
|
81
|
+
| `ModifyMembersResult` | � езультат запроса на изменение списка участников |
|
|
82
|
+
| `MonospacedMarkup` | Представляет `моноширинный` или блок ```код``` в тексте |
|
|
83
|
+
| `NewMessageBody` | |
|
|
84
|
+
| `NewMessageLink` | |
|
|
85
|
+
| `OpenAppButton` | Кнопка для запуска мини-приложения |
|
|
86
|
+
| `PhotoAttachment` | Вложение изображения |
|
|
87
|
+
| `PhotoAttachmentPayload` | |
|
|
88
|
+
| `PhotoAttachmentRequest` | |
|
|
89
|
+
| `PhotoAttachmentRequestPayload` | Запрос на прикрепление изображения (все поля являются взаимоисключающими) |
|
|
90
|
+
| `PhotoToken` | |
|
|
91
|
+
| `PhotoTokens` | Это информация, которую вы получите, как только изображение будет загружено |
|
|
92
|
+
| `PinMessageBody` | |
|
|
93
|
+
| `Recipient` | Новый получатель сообщения. Может быть пользователем или чатом |
|
|
94
|
+
| `ReplyButton` | After pressing this type of button client will send a message on behalf of user with given payload |
|
|
95
|
+
| `ReplyKeyboardAttachment` | Custom reply keyboard in message |
|
|
96
|
+
| `ReplyKeyboardAttachmentRequest` | Request to attach reply keyboard to message |
|
|
97
|
+
| `RequestContactButton` | AПосле нажатия на такую кнопку клиент отправляет новое сообщение с вложением текущего контакта пользователя |
|
|
98
|
+
| `RequestGeoLocationButton` | После нажатия на такую кнопку клиент отправляет новое сообщение с вложением текущего географического положения… |
|
|
99
|
+
| `SendContactButton` | AПосле нажатия на такую кнопку клиент отправляет новое сообщение с вложением текущего контакта пользователя |
|
|
100
|
+
| `SendGeoLocationButton` | После нажатия на такую кнопку клиент отправляет новое сообщение с вложением текущего географического положения… |
|
|
101
|
+
| `SendMessageButton` | After pressing this type of button client will send a message on behalf of user with given payload |
|
|
102
|
+
| `SendMessageResult` | |
|
|
103
|
+
| `SenderAction` | Действие, отправляемое участникам чата. Возможные значения: - `"typing_on"` — Бот набирает сообщение. -… |
|
|
104
|
+
| `ShareAttachment` | |
|
|
105
|
+
| `ShareAttachmentPayload` | Полезная нагрузка запроса ShareAttachmentRequest |
|
|
106
|
+
| `ShareAttachmentRequest` | Запрос на прикрепление предпросмотра медиафайла по внешнему URL |
|
|
107
|
+
| `SimpleQueryResult` | Простой ответ на запрос |
|
|
108
|
+
| `StickerAttachment` | |
|
|
109
|
+
| `StickerAttachmentPayload` | |
|
|
110
|
+
| `StickerAttachmentRequest` | Запрос на прикрепление стикера. ДОЛЖЕН быть единственным вложением в сообщении |
|
|
111
|
+
| `StickerAttachmentRequestPayload` | |
|
|
112
|
+
| `StrikethroughMarkup` | Представляет ~зачекрнутый~ текст |
|
|
113
|
+
| `StrongMarkup` | Представляет **жирный** текст |
|
|
114
|
+
| `Subscription` | Схема для описания подписки на WebHook |
|
|
115
|
+
| `SubscriptionRequestBody` | Запрос на настройку подписки WebHook |
|
|
116
|
+
| `TextFormat` | Формат текста сообщения |
|
|
117
|
+
| `UnderlineMarkup` | Представляет <ins>подчеркнутый</ins> текст |
|
|
118
|
+
| `Update` | Объект`Update` представляет различные типы событий, произошедших в чате. См. его наследников > Чтобы получать события… |
|
|
119
|
+
| `UpdateList` | Список всех обновлений в чатах, в которых ваш бот участвовал |
|
|
120
|
+
| `UploadEndpoint` | Точка доступа, куда следует загружать ваши бинарные файлы |
|
|
121
|
+
| `UploadType` | Тип загружаемого файла Поддерживаемые форматы: - `image`: JPG, JPEG, PNG, GIF, TIFF, BMP, HEIC - `video`: MP4, MOV,… |
|
|
122
|
+
| `UploadedInfo` | Это информация, которую вы получите, как только аудио/видео будет загружено |
|
|
123
|
+
| `User` | Объект, описывающий один из вариантов наследования: - [`User`](/docs-api/objects/User) — объект содержит общую… |
|
|
124
|
+
| `UserAddedToChatUpdate` | Вы получите это обновление, когда пользователь будет добавлен в чат, где бот является администратором |
|
|
125
|
+
| `UserIdsList` | |
|
|
126
|
+
| `UserMentionMarkup` | Представляет упоминание пользователя в тексте. Упоминание может быть как по имени пользователя, так и по ID, если у… |
|
|
127
|
+
| `UserRemovedFromChatUpdate` | Вы получите это обновление, когда пользователь будет удалён из чата, где бот является администратором |
|
|
128
|
+
| `UserWithPhoto` | Объект с общей информацией о пользователе или боте, дополнительно содержит URL аватара и описание |
|
|
129
|
+
| `VideoAttachment` | |
|
|
130
|
+
| `VideoAttachmentDetails` | |
|
|
131
|
+
| `VideoAttachmentRequest` | Запрос на прикрепление видео к сообщению |
|
|
132
|
+
| `VideoThumbnail` | |
|
|
133
|
+
| `VideoUrls` | |
|
|
134
|
+
| `bigint` | |
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Обзор API MAX
|
|
2
|
+
|
|
3
|
+
Источник: https://dev.max.ru/docs-api
|
|
4
|
+
|
|
5
|
+
## Что такое API MAX
|
|
6
|
+
|
|
7
|
+
API MAX — это интерфейс для взаимодействия ботов с платформой через HTTPS-запросы к `platform-api.max.ru`. Он позволяет получать данные и выполнять действия (получение, создание, редактирование, удаление ресурсов).
|
|
8
|
+
|
|
9
|
+
## HTTP методы
|
|
10
|
+
|
|
11
|
+
- `GET` — получить ресурсы
|
|
12
|
+
- `POST` — создать ресурсы (например, отправить сообщения)
|
|
13
|
+
- `PUT` — редактировать ресурсы
|
|
14
|
+
- `DELETE` — удалить ресурсы
|
|
15
|
+
- `PATCH` — исправить ресурсы
|
|
16
|
+
|
|
17
|
+
Параметры передаются в пути, query-строке или теле запроса.
|
|
18
|
+
|
|
19
|
+
## Авторизация
|
|
20
|
+
|
|
21
|
+
Передавайте токен в заголовке:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Authorization: <token>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Передача токена через query-параметры не поддерживается.
|
|
28
|
+
|
|
29
|
+
## Ответы и коды ошибок
|
|
30
|
+
|
|
31
|
+
Сервер возвращает JSON и HTTP-код:
|
|
32
|
+
|
|
33
|
+
- `200` — успешная операция
|
|
34
|
+
- `400` — недействительный запрос
|
|
35
|
+
- `401` — ошибка аутентификации
|
|
36
|
+
- `404` — ресурс не найден
|
|
37
|
+
- `405` — метод не допускается
|
|
38
|
+
- `429` — превышено количество запросов
|
|
39
|
+
- `503` — сервис недоступен
|
|
40
|
+
|
|
41
|
+
## Рекомендации по получению обновлений
|
|
42
|
+
|
|
43
|
+
- Long Polling — для разработки и тестирования
|
|
44
|
+
- Webhook — для production-окружения
|
|
45
|
+
|
|
46
|
+
Ограничение по нагрузке: до **30 rps** на `platform-api.max.ru`.
|
|
47
|
+
|
|
48
|
+
## Клавиатуры
|
|
49
|
+
|
|
50
|
+
Поддерживаются inline-клавиатуры с ограничениями:
|
|
51
|
+
|
|
52
|
+
- до `210` кнопок
|
|
53
|
+
- до `30` рядов
|
|
54
|
+
- до `7` кнопок в ряду (до `3` для кнопок `link`, `open_app`, `request_geo_location`, `request_contact`)
|
|
55
|
+
- для `link` максимальный размер ссылки — `2048` символов
|
|
56
|
+
|
|
57
|
+
Основные типы кнопок:
|
|
58
|
+
|
|
59
|
+
- `callback` — событие `message_callback`
|
|
60
|
+
- `link` — ссылка
|
|
61
|
+
- `request_contact` — запрос контакта
|
|
62
|
+
- `request_geo_location` — запрос геолокации
|
|
63
|
+
- `open_app` — открытие мини-приложения
|
|
64
|
+
- `message` — отправка текста
|
|
65
|
+
|
|
66
|
+
## Форматирование текста
|
|
67
|
+
|
|
68
|
+
Поддерживаются `markdown` и `html` в поле `format` объекта `NewMessageBody`.
|
|
69
|
+
|
|
70
|
+
- Markdown: `*курсив*`, `**жирный**`, `~~зачерк~~`, `++подчерк++`, `` `code` ``
|
|
71
|
+
- HTML: `<i>`, `<b>`, `<del>`, `<ins>`, `<pre>/<code>`, `<a href="...">`
|
|
72
|
+
|
|
73
|
+
Для упоминаний используйте `max://user/user_id` и полное имя пользователя.
|
data/examples/keyboard.rb
CHANGED
|
@@ -17,6 +17,10 @@ keyboard
|
|
|
17
17
|
.add_callback('Audio', 'negative', 'audio')
|
|
18
18
|
.add_message('Continue')
|
|
19
19
|
|
|
20
|
+
keyboard
|
|
21
|
+
.add_row
|
|
22
|
+
.add_clipboard('Copy docs', 'https://dev.max.ru/docs-api/methods/POST/messages')
|
|
23
|
+
|
|
20
24
|
message = MaxBotApi::Builders::MessageBuilder.new
|
|
21
25
|
.set_chat(chat_id)
|
|
22
26
|
.add_keyboard(keyboard)
|
data/examples/webhook_rack.rb
CHANGED
|
@@ -8,6 +8,10 @@ client = MaxBotApi::Client.new(token: ENV.fetch('TOKEN'))
|
|
|
8
8
|
app = lambda do |env|
|
|
9
9
|
req = Rack::Request.new(env)
|
|
10
10
|
if req.post? && req.path == '/webhook'
|
|
11
|
+
unless client.webhook_secret_valid?(headers: env, secret: ENV.fetch('WEBHOOK_SECRET'))
|
|
12
|
+
return [401, { 'Content-Type' => 'text/plain' }, ['secret not allowed']]
|
|
13
|
+
end
|
|
14
|
+
|
|
11
15
|
update = client.parse_webhook(req.body.read)
|
|
12
16
|
|
|
13
17
|
if update[:update_type] == 'message_created'
|
|
@@ -94,6 +94,16 @@ module MaxBotApi
|
|
|
94
94
|
add_button(button)
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
+
# Add a clipboard button.
|
|
98
|
+
def add_clipboard(text, payload)
|
|
99
|
+
button = {
|
|
100
|
+
type: 'clipboard',
|
|
101
|
+
text: text,
|
|
102
|
+
payload: payload
|
|
103
|
+
}
|
|
104
|
+
add_button(button)
|
|
105
|
+
end
|
|
106
|
+
|
|
97
107
|
# Build row payload.
|
|
98
108
|
def build
|
|
99
109
|
@cols
|
|
@@ -7,7 +7,7 @@ module MaxBotApi
|
|
|
7
7
|
FORMAT_HTML = 'html'
|
|
8
8
|
FORMAT_MARKDOWN = 'markdown'
|
|
9
9
|
|
|
10
|
-
attr_reader :user_id, :chat_id, :reset
|
|
10
|
+
attr_reader :user_id, :chat_id, :reset, :disable_link_preview
|
|
11
11
|
|
|
12
12
|
# Create a builder from an existing hash payload.
|
|
13
13
|
# @param hash [Hash]
|
|
@@ -19,6 +19,9 @@ module MaxBotApi
|
|
|
19
19
|
builder.set_user(hash[:user_id] || hash['user_id']) if hash.key?(:user_id) || hash.key?('user_id')
|
|
20
20
|
builder.set_chat(hash[:chat_id] || hash['chat_id']) if hash.key?(:chat_id) || hash.key?('chat_id')
|
|
21
21
|
builder.set_reset(hash[:reset] || hash['reset']) if hash.key?(:reset) || hash.key?('reset')
|
|
22
|
+
if hash.key?(:disable_link_preview) || hash.key?('disable_link_preview')
|
|
23
|
+
builder.set_disable_link_preview(hash[:disable_link_preview] || hash['disable_link_preview'])
|
|
24
|
+
end
|
|
22
25
|
|
|
23
26
|
payload = hash[:message] || hash['message'] || hash
|
|
24
27
|
builder.apply_payload(payload)
|
|
@@ -30,6 +33,7 @@ module MaxBotApi
|
|
|
30
33
|
@user_id = nil
|
|
31
34
|
@chat_id = nil
|
|
32
35
|
@reset = false
|
|
36
|
+
@disable_link_preview = false
|
|
33
37
|
@message = {
|
|
34
38
|
attachments: []
|
|
35
39
|
}
|
|
@@ -53,6 +57,12 @@ module MaxBotApi
|
|
|
53
57
|
self
|
|
54
58
|
end
|
|
55
59
|
|
|
60
|
+
# Toggle link previews in sent messages.
|
|
61
|
+
def set_disable_link_preview(disable_link_preview)
|
|
62
|
+
@disable_link_preview = !!disable_link_preview
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
56
66
|
# Set message text.
|
|
57
67
|
def set_text(text)
|
|
58
68
|
@message[:text] = text
|
|
@@ -177,6 +187,11 @@ module MaxBotApi
|
|
|
177
187
|
@reset
|
|
178
188
|
end
|
|
179
189
|
|
|
190
|
+
# Whether link previews are disabled for message delivery.
|
|
191
|
+
def disable_link_preview?
|
|
192
|
+
@disable_link_preview
|
|
193
|
+
end
|
|
194
|
+
|
|
180
195
|
# Return the message payload hash.
|
|
181
196
|
def to_h
|
|
182
197
|
@message
|
data/lib/max_bot_api/client.rb
CHANGED
|
@@ -9,6 +9,8 @@ module MaxBotApi
|
|
|
9
9
|
DEFAULT_BASE_URL = 'https://platform-api.max.ru/'
|
|
10
10
|
# Default API version appended as query param.
|
|
11
11
|
DEFAULT_VERSION = '1.2.5'
|
|
12
|
+
# Webhook secret header name.
|
|
13
|
+
SECRET_HEADER = 'X-Max-Bot-Api-Secret'
|
|
12
14
|
# Default pause between update polling loops.
|
|
13
15
|
DEFAULT_PAUSE = 1
|
|
14
16
|
# Default limit for updates requests.
|
|
@@ -131,6 +133,13 @@ module MaxBotApi
|
|
|
131
133
|
Updates::Parser.parse_update(body.to_s, debug: debug)
|
|
132
134
|
end
|
|
133
135
|
|
|
136
|
+
# Validates the webhook secret header against the expected secret.
|
|
137
|
+
# @param headers [Hash]
|
|
138
|
+
# @param secret [String]
|
|
139
|
+
def webhook_secret_valid?(headers:, secret:)
|
|
140
|
+
header_value(headers, SECRET_HEADER) == secret.to_s
|
|
141
|
+
end
|
|
142
|
+
|
|
134
143
|
# Perform an HTTP request.
|
|
135
144
|
# @param method [Symbol]
|
|
136
145
|
# @param path [String]
|
|
@@ -192,6 +201,18 @@ module MaxBotApi
|
|
|
192
201
|
body.values.any? { |value| value.is_a?(Faraday::Multipart::FilePart) }
|
|
193
202
|
end
|
|
194
203
|
|
|
204
|
+
def header_value(headers, name)
|
|
205
|
+
target = name.to_s.downcase
|
|
206
|
+
|
|
207
|
+
headers.each do |key, value|
|
|
208
|
+
normalized = key.to_s.downcase.tr('_', '-')
|
|
209
|
+
normalized = normalized.sub(/\Ahttp-/, '')
|
|
210
|
+
return value if normalized == target
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
nil
|
|
214
|
+
end
|
|
215
|
+
|
|
195
216
|
def handle_response(response)
|
|
196
217
|
return parse_body(response) if response.status == 200
|
|
197
218
|
|
|
@@ -86,6 +86,25 @@ module MaxBotApi
|
|
|
86
86
|
def send_action(chat_id:, action:)
|
|
87
87
|
@client.request(:post, "chats/#{chat_id}/actions", body: { action: action })
|
|
88
88
|
end
|
|
89
|
+
|
|
90
|
+
# Pin a message in chat.
|
|
91
|
+
# @param chat_id [Integer]
|
|
92
|
+
# @param message_id [String]
|
|
93
|
+
def pin_message(chat_id:, message_id:)
|
|
94
|
+
@client.request(:put, "chats/#{chat_id}/pin", body: { message_id: message_id })
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Fetch the currently pinned message.
|
|
98
|
+
# @param chat_id [Integer]
|
|
99
|
+
def get_pinned_message(chat_id:)
|
|
100
|
+
@client.request(:get, "chats/#{chat_id}/pin")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Remove the currently pinned message.
|
|
104
|
+
# @param chat_id [Integer]
|
|
105
|
+
def unpin_message(chat_id:)
|
|
106
|
+
@client.request(:delete, "chats/#{chat_id}/pin")
|
|
107
|
+
end
|
|
89
108
|
end
|
|
90
109
|
end
|
|
91
110
|
end
|
|
@@ -110,6 +110,7 @@ module MaxBotApi
|
|
|
110
110
|
query = {}
|
|
111
111
|
query['chat_id'] = message.chat_id if message.chat_id && message.chat_id.to_i != 0
|
|
112
112
|
query['user_id'] = message.user_id if message.user_id && message.user_id.to_i != 0
|
|
113
|
+
query['disable_link_preview'] = 'true' if message.disable_link_preview?
|
|
113
114
|
|
|
114
115
|
response = @client.request(:post, 'messages', query: query, body: message_payload(message),
|
|
115
116
|
reset: message.reset?)
|
data/lib/max_bot_api/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: max_bot_api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ChatGPT Codex
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2026-
|
|
12
|
+
date: 2026-06-05 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: base64
|
|
@@ -95,6 +95,9 @@ files:
|
|
|
95
95
|
- docs/04-keyboard.md
|
|
96
96
|
- docs/05-uploads.md
|
|
97
97
|
- docs/06-subscriptions.md
|
|
98
|
+
- docs/api/methods.md
|
|
99
|
+
- docs/api/objects.md
|
|
100
|
+
- docs/api/overview.md
|
|
98
101
|
- examples/attachments.rb
|
|
99
102
|
- examples/basic_send.rb
|
|
100
103
|
- examples/keyboard.rb
|