Skip to content

Commit d685d6f

Browse files
committed
upd
1 parent 4685a4b commit d685d6f

File tree

2 files changed

+95
-9
lines changed

2 files changed

+95
-9
lines changed

docs/4.updates.md

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ void update(fb::Update& u) {
5656
5757
> В примере с хэшем строка, указанная в `SH`, не существует в программе: вместо этого компилятор подставляет её хэш (число). А в `switch` мы подаём хэш пришедшей строки. Это позволяет максимально быстро, оптимально и очень удобно сравнивать строки в сценариях, когда приходящий текст может иметь известный набор значений. В данном случае - обработка query, очень типовая задача (определение кнопки клавиатуры, на которую нажал юзер).
5858
59+
Удобного получения хэша сообщения с кириллицей не предусмотрено, можно получить его так:
60+
61+
```cpp
62+
size_t hash = SH(u.message().text().decodeUnicode().c_str()); // раскодировать и передать в хэш-функцию
63+
```
64+
5965
### Личка с админом
6066
Телеграм бот - публичная штука, любой пользователь может найти вашего бота в поиске и взаимодействовать с ним. Чтобы ограничить круг лиц (админов), которые могут работать с ботом (или иметь дополнительные функции), достаточно вручную фильтровать обновления по id юзера. Несколько способов:
6167
```cpp
@@ -94,6 +100,7 @@ void update(fb::Update& u) {
94100
95101
### Переполнение стека
96102
При создании больших программ с большим количеством кода внутри обработчика обновлений на esp8266 можно столкнуться с исключением (перезагрузка МК) по причине `core panic` или `stack smashed`, это происходит по причине переполнения стека памяти (на esp32 он выделен в два раза больше и получить это исключение практически невозможно). Проблема особенно хорошо проявляется при скачивании файлов внутри обработчика обновлений и наличии большого количества другого кода. Для избежания случайных перезагрузок рекомендуется разделять обработчик на несколько функций, это также позволит лучше структурировать программу и разделять на файлы/блоки:
103+
97104
```cpp
98105
// обработка сообщений
99106
void uMessage(fb::Update& u) {
@@ -119,51 +126,125 @@ void setup() {
119126
}
120127
```
121128

129+
Также можно разбить функцию разбора обновлений на лямбды:
130+
131+
```cpp
132+
void update(fb::Update& u) {
133+
[&](){
134+
// блок 1
135+
}();
136+
137+
[&](){
138+
// блок 2
139+
}();
140+
}
141+
```
142+
143+
Или использовать встроенный макрос:
144+
145+
```cpp
146+
void update(fb::Update& u) {
147+
FB_SUB_BEGIN
148+
// блок 1
149+
150+
FB_SUB_NEXT
151+
// блок 2
152+
153+
FB_SUB_NEXT
154+
// блок 3
155+
156+
FB_SUB_END
157+
}
158+
```
159+
122160
## Разбор вручную
123161
Для работы напрямую с API Telegram вам понадобится [официальная документация](https://core.telegram.org/bots/api).
124162

125-
Класс `Update`, а также все вложенные классы (`User`, `Message`...) имеют доступ к `gson::Entry` пакета (документация [здесь](https://github.com/GyverLibs/GSON?tab=readme-ov-file#gsonentry)), который представляет собой распарсенный JSON пакет с хэшированными ключами. FastBot2 в свою очередь хранит хэши всех команд API Telegram (имеют префикс `tg_apih`). Поэтому для получения доступа ко всему содержимому нужно обратиться к объекту через квадратные скобки с хэшем. Например, для получения текста сообщения код будет такой:
163+
Класс `Update`, а также все вложенные классы (`User`, `Message`...) имеют доступ к `gson::Entry` пакета (документация [здесь](https://github.com/GyverLibs/GSON?tab=readme-ov-file#gsonentry)), который представляет собой распарсенный JSON пакет с хэшированными ключами. FastBot2 в свою очередь хранит хэши всех команд API Telegram (имеют префикс `tg_apih`).
164+
165+
Объект класса `Update` является JSON объектом, который содержит непосредственно данные обновления. То есть для апдейта типа `"message"` это будет его содержимое, например (ответ сервера Telegram):
166+
167+
```json
168+
{
169+
"ok": true,
170+
"result": [
171+
{
172+
"update_id": 1234653458,
173+
"message": { <- вот это Update
174+
"message_id": 178,
175+
"from": {
176+
},
177+
"chat": {
178+
},
179+
"text": "123321"
180+
}
181+
}
182+
]
183+
}
184+
```
185+
186+
Для получения доступа к содержимому нужно обратиться к объекту через квадратные скобки с хэшем. Например, для получения текста сообщения код будет такой:
187+
126188
```cpp
127189
void update(fb::Update& u) {
128-
Serial.println(u[tg_apih::message][tg_apih::text]);
190+
Serial.println(u[tg_apih::text]);
129191
// "изнутри" этот код аналогичен u.message().text()
130192
}
131193
```
132194
195+
Тип текущего обновления парсится библиотекой, его можно разобрать так:
196+
197+
```cpp
198+
void update(fb::Update& u) {
199+
switch (u.type()) {
200+
case fb::Update::Type::Message:
201+
break;
202+
203+
case fb::Update::Type::ChannelPost:
204+
break;
205+
206+
// и так далее
207+
}
208+
}
209+
```
210+
133211
Для проверки наличия в текущем обновлении или вложенном объекте нужно информации нужно использовать `has`, чтобы обезопасить программу от чтения несуществующих данных:
212+
134213
```cpp
135214
void update(fb::Update& u) {
136-
// если обновление содержит сообщение
137-
if (u.has[tg_apih::message]) {
215+
// если обновление содержит текст
216+
if (u.has[tg_apih::text]) {
138217
// то вывести текст сообщения
139-
Serial.println(u[tg_apih::message][tg_apih::text]);
218+
Serial.println(u[tg_apih::text]);
140219
}
141-
// по сути это аналог встроенного u.isMessage()
142220
}
143221
```
144222
145223
Также в целях отладки можно вывести содержимое любого JSON элемента с форматированием:
224+
146225
```cpp
147226
void update(fb::Update& u) {
148-
u[tg_apih::message].stringify(Serial);
227+
u[tg_apih::from].stringify(Serial);
149228
}
150229
```
151230

152231
Примечание: результат доступа к значению через `[]` также является типом `Text`, то есть доступны все его возможности:
232+
153233
```cpp
154234
void update(fb::Update& u) {
155235
// сравнение
156-
u[tg_apih::message][tg_apih::text] == "1234";
236+
u[tg_apih::text] == "1234";
157237

158238
// конвертация
159-
float v = u[tg_apih::message][tg_apih::text];
239+
float v = u[tg_apih::text];
160240

161241
// и так далее
162242
}
163243
```
164244
165245
### Комбинированный доступ
166246
Все подклассы внутри `Update` имеют доступ через `[]`, то есть доступ к данным можно комбинировать. Например получить текст сообщения вот так:
247+
167248
```cpp
168249
void update(fb::Update& u) {
169250
Serial.println(u.message()[tg_apih::text]);

src/bot_config.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
#define FB_ESP_BUILD 1
1919
#endif
2020

21+
//
22+
#define FB_SUB_BEGIN [&]() {
23+
#define FB_SUB_END }();
24+
#define FB_SUB_NEXT FB_SUB_END FB_SUB_BEGIN
25+
2126
// #define FB_USE_LOG Serial
2227

2328
// log

0 commit comments

Comments
 (0)