- Добавлена полная интеграция с Telegram Mini App (динамическая загрузка SDK) - Отдельный компактный дизайн для Telegram Mini App - Добавлен loader при инициализации (предотвращает мелькание SMS-авторизации) - Улучшена навигация: кнопки "Назад" и "К списку заявок" теперь сохраняют авторизацию - Telegram Mini App: кнопка "Выход" просто закрывает приложение - Telegram Mini App: заявки "В работе" скрыты из списка - Веб-версия: для заявок "В работе" добавлена кнопка "Просмотреть в Telegram" (ссылка на @klientprav_bot) - Telegram Mini App: кнопки действий в черновиках расположены вертикально - Веб-версия: убрано отображение номера телефона в приветствии - Исправлена проблема с возвратом к списку черновиков (не требует повторной SMS-авторизации) - Заблокировано удаление и редактирование заявок со статусом "В работе" - Добавлена документация по Telegram Mini App интеграции
164 lines
3.9 KiB
Markdown
164 lines
3.9 KiB
Markdown
# Настройка HTTP Request для Browserless Function API
|
||
|
||
## Готовые настройки для HTTP Request ноды
|
||
|
||
### Method
|
||
`POST`
|
||
|
||
### URL
|
||
```
|
||
http://147.45.146.17:3000/function?token=9ahhnpjkchxtcho9
|
||
```
|
||
|
||
### Headers
|
||
```json
|
||
{
|
||
"Content-Type": "application/javascript"
|
||
}
|
||
```
|
||
|
||
### Body (Raw)
|
||
**Content Type:** `application/javascript`
|
||
|
||
**Body:**
|
||
```javascript
|
||
export default async function ({ page }) {
|
||
const html = `{{ $json.html }}`;
|
||
|
||
if (!html) {
|
||
throw new Error('❌ HTML не передан');
|
||
}
|
||
|
||
// универсальный sleep
|
||
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
||
|
||
await page.setViewport({ width: 1240, height: 1754 });
|
||
|
||
// Загружаем HTML напрямую
|
||
await page.setContent(html, {
|
||
waitUntil: ['load', 'domcontentloaded', 'networkidle0'],
|
||
});
|
||
|
||
// Даём браузеру применить стили
|
||
await sleep(300);
|
||
|
||
const pdfBuffer = await page.pdf({
|
||
format: 'A4',
|
||
printBackground: true,
|
||
margin: {
|
||
top: '20mm',
|
||
right: '15mm',
|
||
bottom: '20mm',
|
||
left: '15mm',
|
||
},
|
||
});
|
||
|
||
return {
|
||
status: 'success',
|
||
pdf_base64: pdfBuffer.toString('base64'),
|
||
size_bytes: pdfBuffer.length,
|
||
};
|
||
}
|
||
```
|
||
|
||
### Options
|
||
- **Timeout:** `40000` (40 секунд)
|
||
|
||
### Response Format
|
||
`JSON` (Browserless вернёт JSON с `pdf_base64`)
|
||
|
||
---
|
||
|
||
## Вариант с html_base64
|
||
|
||
Если у вас HTML в base64, используйте этот вариант:
|
||
|
||
```javascript
|
||
export default async function ({ page }) {
|
||
// Получаем HTML из base64
|
||
const htmlBase64 = `{{ $json.html_base64 }}`;
|
||
const html = Buffer.from(htmlBase64, 'base64').toString('utf8');
|
||
|
||
if (!html) {
|
||
throw new Error('❌ HTML не передан');
|
||
}
|
||
|
||
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
||
|
||
await page.setViewport({ width: 1240, height: 1754 });
|
||
|
||
await page.setContent(html, {
|
||
waitUntil: ['load', 'domcontentloaded', 'networkidle0'],
|
||
});
|
||
|
||
await sleep(300);
|
||
|
||
const pdfBuffer = await page.pdf({
|
||
format: 'A4',
|
||
printBackground: true,
|
||
margin: {
|
||
top: '20mm',
|
||
right: '15mm',
|
||
bottom: '20mm',
|
||
left: '15mm',
|
||
},
|
||
});
|
||
|
||
return {
|
||
status: 'success',
|
||
pdf_base64: pdfBuffer.toString('base64'),
|
||
size_bytes: pdfBuffer.length,
|
||
};
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Полный Workflow
|
||
|
||
```
|
||
[Code: Process Flights Data] ← Генерирует HTML
|
||
↓
|
||
[HTTP Request: Browserless Function] ← Используйте настройки выше
|
||
↓
|
||
[Code: Extract PDF Base64] ← Если нужно обработать ответ
|
||
```
|
||
|
||
---
|
||
|
||
## Code Node: Extract PDF Base64 (опционально)
|
||
|
||
Если Browserless уже вернул `pdf_base64` в JSON, можно просто передать дальше:
|
||
|
||
```javascript
|
||
const response = $input.first().json;
|
||
|
||
return [{
|
||
json: {
|
||
pdf_base64: response.pdf_base64,
|
||
pdf_size_bytes: response.size_bytes,
|
||
pdf_size_mb: (response.size_bytes / (1024 * 1024)).toFixed(2),
|
||
status: response.status,
|
||
success: true
|
||
}
|
||
}];
|
||
```
|
||
|
||
---
|
||
|
||
## Преимущества этого подхода
|
||
|
||
✅ **Прямая работа с HTML** - не нужно конвертировать в data URL
|
||
✅ **Полный контроль** - можете добавить любую логику в функцию
|
||
✅ **Готовый base64** - Browserless сразу возвращает base64 PDF
|
||
✅ **Надёжность** - sleep даёт время браузеру применить стили
|
||
|
||
---
|
||
|
||
## Отладка
|
||
|
||
Если получаете ошибки:
|
||
- **"HTML не передан"** → Проверьте, что предыдущая нода вернула `html` или `html_base64`
|
||
- **Timeout** → Увеличьте timeout в Options до 60000 (60 секунд)
|
||
- **Пустой PDF** → Увеличьте sleep до 500-1000ms
|