> For the complete documentation index, see [llms.txt](https://docs.fstrk.io/knowledge_base/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fstrk.io/knowledge_base/intagrations/mobilnoe-prilozhenie.md).

# Мобильное приложение

Если ваше мобильное приложение должно поддерживать переписку с оператором или ботом, не нужно разрабатывать чат с нуля. Виджет Fasttrack встраивается в нативное приложение через стандартный компонент `WebView`: приложение открывает обычную HTML-страницу со скриптом виджета, а дальше всё работает само. В этой статье — как настроить страницу, передать идентификатор пользователя и подготовить приложение к работе на Android и iOS.

***

### Предварительные требования

Прежде чем начать, убедитесь, что у вас есть:

* Доступ к личному кабинету Fasttrack с правами на просмотр настроек виджета.
* Созданный виджет в разделе [**Маркетинг → Виджет**](https://my.fstrk.io/campaigns/widget).
* UUID виджета — уникальный идентификатор вида `4bb3a79e-8075-4244-9440-cd266790cf1c`. Где взять: откройте нужный виджет → вкладка **«Общие»** → блок **«Скрипт для мобильного приложения (WebView)»**. Там же готовый сниппет с кнопкой «Копировать».

<figure><img src="/files/RQKDZ2eVJsLMF6ZTsJQ3" alt=""><figcaption></figcaption></figure>

* Для мобильного разработчика: доступ к исходному коду приложения и возможность добавить или изменить компонент `WebView`.

***

### Пошаговая инструкция

#### Шаг 1. Получите скрипт виджета в админке

1. Перейдите в [**Маркетинг → Виджет**](https://my.fstrk.io/campaigns/widget) и выберите нужный виджет.
2. Откройте вкладку **«Общие»** и найдите блок **«Скрипт для мобильного приложения (WebView)»**.

   <figure><img src="/files/Y52JxO65h0au4YNYoL7q" alt=""><figcaption></figcaption></figure>
3. Нажмите **«Копировать»** — вы получите готовый тег `<script>` с вашим UUID.

***

#### Шаг 2. Создайте HTML-страницу для WebView

Создайте на вашем сервере (или в ресурсах приложения) HTML-файл и вставьте скопированный скрипт. Минимально рабочий вариант:

```html
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, viewport-fit=cover">
  <style>
    html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
  </style>
</head>
<body>
  <script async
    src="https://cdn.fstrk.io/widget3-cdn/<UUID-ВИДЖЕТА>.js"
    data-webview></script>
</body>
</html>
```

Замените `<UUID-ВИДЖЕТА>` на ваш UUID из предыдущего шага, либо вставьте скопированный скрипт из предыдущего пункта.

> **Важно:** Атрибут `data-webview` обязателен. Именно он переключает виджет в режим «только чат» — полноэкранный, без кнопки запуска, без обложки и без кнопки закрытия. Без этого атрибута откроется обычный виджет для сайта, который не подходит для встраивания в приложение.

***

#### Шаг 3. Передайте идентификатор пользователя (рекомендуется)

Чтобы пользователь при повторном открытии приложения — или на другом устройстве — видел свою прежнюю переписку, передайте его стабильный идентификатор в значении атрибута `data-webview`:

```html
<script async
  src="https://cdn.fstrk.io/widget3-cdn/<UUID-ВИДЖЕТА>.js"
  data-webview="a3f1c9e2-7b4d-4f8a-9c11-2e6d5b8a1f30"></script>
```

Если значение не передать, виджет сгенерирует временный идентификатор и сохранит его в `localStorage` WebView. Переписка сохранится, пока пользователь не очистит кэш приложения — но при переустановке или на другом устройстве будет потеряна.

**Требования к идентификатору**

Идентификатор должен быть:

* **Стабильным** — одним и тем же для одного пользователя при каждом входе.
* **Неугадываемым** — UUID или криптографический хэш. Не используйте телефон, e-mail, порядковый номер или любое другое предсказуемое значение.

Виджет проверяет только публичный ключ (он зашит в бандл), но не личность пользователя. Если идентификатор предсказуем, посторонний может подобрать чужой и прочитать его переписку.

✅ Правильно: `data-webview="a3f1c9e2-7b4d-4f8a-9c11-2e6d5b8a1f30"`\
❌ Неправильно: `data-webview="42"`, `data-webview="+79991234567"`

***

#### Шаг 4. Передайте данные пользователя для оператора (необязательно)

Если вы хотите, чтобы оператор в чат-центре видел имя и контакты клиента, а не безликий «Web site user», добавьте атрибуты `data-user-*`:

```html
<script async
  src="https://cdn.fstrk.io/widget3-cdn/<UUID-ВИДЖЕТА>.js"
  data-webview="a3f1c9e2-7b4d-4f8a-9c11-2e6d5b8a1f30"
  data-user-name="Иван Петров"
  data-user-phone="+79991234567"
  data-user-email="ivan@example.com"></script>
```

| Атрибут           | Что передаёт            |
| ----------------- | ----------------------- |
| `data-user-name`  | Имя пользователя        |
| `data-user-phone` | Номер телефона          |
| `data-user-email` | Адрес электронной почты |

Все три атрибута необязательны — передавайте только те, что доступны в вашем приложении.

***

#### Шаг 5. Настройте WebView в нативном приложении

**Android**

В Android `WebView` JavaScript и DOM Storage отключены по умолчанию. Включите их явно:

```kotlin
webView.settings.javaScriptEnabled = true
webView.settings.domStorageEnabled = true
webView.loadUrl("https://your-domain.com/chat.html")
```

Также реализуйте `WebChromeClient.onShowFileChooser()` — иначе кнопка прикрепления файлов в чате будет молча не работать. Без этого метода Android `WebView` не умеет открывать системный выбор файлов.

```kotlin
private var fileCallback: ValueCallback<Array<Uri>>? = null
private val REQ_FILE = 1001

webView.webChromeClient = object : WebChromeClient() {
    override fun onShowFileChooser(
        view: WebView?,
        callback: ValueCallback<Array<Uri>>?,
        params: FileChooserParams?
    ): Boolean {
        fileCallback?.onReceiveValue(null)
        fileCallback = callback
        return try {
            startActivityForResult(params!!.createIntent(), REQ_FILE)
            true
        } catch (e: Exception) {
            fileCallback = null
            false
        }
    }
}

override fun onActivityResult(req: Int, res: Int, data: Intent?) {
    super.onActivityResult(req, res, data)
    if (req == REQ_FILE) {
        fileCallback?.onReceiveValue(
            WebChromeClient.FileChooserParams.parseResult(res, data)
        )
        fileCallback = null
    }
}
```

> **Важно:** Если ваши пользователи могут отправлять фото с камеры прямо из чата, добавьте в `AndroidManifest.xml` разрешение `android.permission.CAMERA`. Для выбора уже существующих файлов из галереи разрешений не нужно.

**iOS**

На iOS используйте `WKWebView` — JavaScript и хранилище включены в нём по умолчанию, дополнительная настройка не требуется. Системный пикер файлов также открывается автоматически.

```swift
let webView = WKWebView(frame: view.bounds)
view.addSubview(webView)

let url = URL(string: "https://your-domain.com/chat.html")!
webView.load(URLRequest(url: url))
```

***

#### Шаг 6. Полный пример HTML-страницы

Итоговая страница с передачей идентификатора и данных пользователя:

```html
<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, viewport-fit=cover">
  <style>
    html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
  </style>
</head>
<body>
  <script async
    src="https://cdn.fstrk.io/widget3-cdn/4bb3a79e-8075-4244-9440-cd266790cf1c.js"
    data-webview="a3f1c9e2-7b4d-4f8a-9c11-2e6d5b8a1f30"
    data-user-name="Иван Петров"
    data-user-phone="+79991234567"
    data-user-email="ivan@example.com"></script>
</body>
</html>
```

***

### Как работает режим WebView — отличия от обычного виджета

|                     | Режим WebView (мобильное приложение) | Обычный виджет на сайте     |
| ------------------- | ------------------------------------ | --------------------------- |
| Запуск              | Сразу открыт полноэкранный чат       | Кнопка-launcher или обложка |
| Кнопка закрытия (×) | Нет                                  | Есть                        |
| Переход на обложку  | Нет                                  | Есть                        |
| Размер              | Весь экран                           | Плавающее окно              |

Закрытие чата — это скрытие или закрытие `WebView` средствами нативного приложения. Виджет сам закрыться не может — в этом смысл режима «киоска».

> **Важно:** Виджет не обращается к серверам Fasttrack при открытии страницы — только загружает JS-бандл с CDN. Подключение к чату (авторизация, WebSocket, история сообщений) происходит после первого действия пользователя. Это снижает расход трафика и ускоряет загрузку.

***

### Ограничения и подводные камни

**Минимальная ширина окна** — 320 px. Если `WebView` уже — виджет отобразится некорректно. Убедитесь, что у `html` и `body` нет внешних отступов и выставлен `height: 100%`.

**Смена пользователя на лету невозможна.** Идентификатор из `data-webview` читается один раз при загрузке страницы. Если нужно переключить учётную запись (например, после выхода из профиля) — перезагрузите страницу в `WebView` с новым значением атрибута.

**Анонимная сессия ненадёжна.** Без `data-webview` переписка хранится только в `localStorage` конкретного `WebView`. Очистка кэша, переустановка приложения или вход с другого устройства — и история теряется.

**Разные оформления для разных сценариев.** Цвета, заголовок, аватар и другие параметры внешнего вида задаются в админке и «запекаются» в бандл — настраивать их со стороны HTML не нужно и нельзя. Если вам нужны разные темы (например, для разных брендов или разделов приложения) — создайте отдельные виджеты с разными UUID.

> **Осторожно:** Не используйте предсказуемые идентификаторы пользователей. Виджет не проверяет личность — только публичный ключ. Утечка предсказуемого идентификатора позволит получить доступ к чужой переписке.

***

### Чеклист для самопроверки

* [ ] UUID виджета скопирован из вкладки «Общие» → «Скрипт для мобильного приложения (WebView)» — не из раздела для сайта.
* [ ] В теге `<script>` присутствует атрибут `data-webview` (пустой или со значением).
* [ ] Идентификатор пользователя в `data-webview` стабильный и неугадываемый (UUID или хэш, не телефон и не порядковый номер).
* [ ] На Android включены `javaScriptEnabled = true`, `domStorageEnabled = true` и реализован `onShowFileChooser()`.
* [ ] Стили `html, body { margin: 0; padding: 0; height: 100%; }` присутствуют на странице, ширина `WebView` не менее 320 px.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fstrk.io/knowledge_base/intagrations/mobilnoe-prilozhenie.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
