> For the complete documentation index, see [llms.txt](https://docs.graspil.com/ru/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.graspil.com/ru/app/website-script.md).

# Скрипт для сайта

## Что это такое?

Скрипт для сайта — это небольшой JS-код, который вы устанавливаете на свой сайт (лендинг, магазин, блог — что угодно). Он позволяет:

1. **Автоматически передавать UTM-метки посетителя сайта в бот.** Если пользователь пришёл на сайт по рекламе с метками `utm_source`, `utm_medium` и т.д., а затем запустил вашего бота с этого же сайта — все эти метки будут привязаны к нему в Graspil, и вы увидите полный путь пользователя от клика по рекламе до общения с ботом.
2. **Определять геолокацию пользователя** (по IP, до запуска бота).
3. **Передавать любые свои дополнительные параметры**, которые вы хотите привязать к пользователю (например, ID из вашей CRM, `client_id` из Google Analytics или Яндекс.Метрики, ID товара, который смотрел пользователь, и т.д.).
4. **Авторизовывать пользователя в боте без кодов и смс** — скрипт сам передаёт данные о посетителе через специальный токен, который прилетает в бот в параметре `start` при запуске.

{% hint style="info" %}
Раздел с текстом ссылки для установки скрипта и вашим ключом находится в личном кабинете: [Расширение для сайта](https://app.graspil.com/code4-site)
{% endhint %}

## Как это работает?

1. Вы устанавливаете код на сайт (см. ниже).
2. Каждому посетителю сайта присваивается уникальный токен. К этому токену привязываются все собранные данные: UTM-метки, геолокация, ваши дополнительные поля.
3. Скрипт находит на странице ссылки на вашего бота (`https://t.me/ваш_бот` или `tg://resolve?domain=ваш_бот`) и автоматически подставляет туда этот токен в параметр `start` (или `startapp` — для ссылок на Mini App).
4. Когда пользователь нажимает на такую ссылку и запускает бота, Graspil видит токен в параметре `start` и подгружает к пользователю все ранее собранные данные.

{% hint style="warning" %}
Скрипт находит и обрабатывает **только ссылки на бота, название которого совпадает с названием бота, подключённого у вас в платформе** (раздел [Мои боты](https://app.graspil.com/bots)). Если название бота в ссылке не совпадает — ссылка не будет обработана. Проверьте название бота в разделе "Мои боты" → "Редактировать", если ссылки не работают.
{% endhint %}

## Установка

Добавьте код ниже в любое место на странице (лучше — в `<head>` или в начало `<body>`, до всех ссылок на бота):

```html
<script>
  (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({key:i});
  var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src="https://s.graspil.com?l="+l;
  f.parentNode.insertBefore(j,f);})(window,document,"script","graspil","ВАШ_КЛЮЧ");
</script>
```

Свой ключ (`ВАШ_КЛЮЧ`) вы можете скопировать в личном кабинете, в разделе [Расширение для сайта](https://app.graspil.com/code4-site) — там уже готовый код с подставленным ключом.

Больше ничего делать не нужно — в базовом режиме скрипт сам найдёт ссылки на бота на странице и подставит токен.

## Какие ссылки на бота обрабатываются автоматически

| Тип ссылки                                 | Пример                                        | Куда подставляется токен |
| ------------------------------------------ | --------------------------------------------- | ------------------------ |
| Обычная ссылка на бота                     | `https://t.me/graspil_bot`                    | `?start=токен`           |
| Ссылка на Mini App (по пути)               | `https://t.me/graspil_bot/app`                | `?startapp=токен`        |
| Deep link (открытие в приложении Telegram) | `tg://resolve?domain=graspil_bot`             | `&start=токен`           |
| Deep link на Mini App                      | `tg://resolve?domain=graspil_bot&appname=app` | `&startapp=токен`        |

{% hint style="warning" %}
Значение параметра `start` (или `startapp`) в ссылке будет заменено на токен. Если у ссылки на бота уже были свои параметры (например `?ref=abc`) — они будут удалены и заменены на токен. Если для вашего бота это критично — напишите нам в поддержку.
{% endhint %}

{% hint style="info" %}
Скрипт ищет только ссылки `https://t.me/...` и `tg://resolve...`. Ссылки вида `http://t.me/...` (без `https`) или `https://telegram.me/...` не распознаются.
{% endhint %}

## Что делает бот с этим токеном?

Токен, который скрипт подставляет в `start`, — это тот же самый параметр `start`, который Telegram передаёт вашему боту при запуске. Подробнее о том, как параметр `start` устроен и обрабатывается в Graspil, читайте в разделе [Обработка параметров start (UTM)](/ru/app/start-utm.md).

Если вам нужно получить данные, привязанные к токену (UTM-метки, геолокацию, ваши дополнительные поля), напрямую через API — используйте метод [Получение данных по стартовому токену](/ru/api/get-data-by-start-token.md).

## Настройка скрипта

По умолчанию скрипту достаточно только ключа `key`. Но вы можете передать дополнительные настройки, добавив их в объект вместе с ключом:

```html
<script>
  (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({key:i, autoBot: false, initialDelay: 500});
  var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src="https://s.graspil.com?l="+l;
  f.parentNode.insertBefore(j,f);})(window,document,"script","graspil","ВАШ_КЛЮЧ");
</script>
```

<table><thead><tr><th width="180">Параметр</th><th width="150">Тип</th><th>Описание</th></tr></thead><tbody><tr><td><code>key</code></td><td>строка</td><td>Обязательный. Ваш ключ из личного кабинета.</td></tr><tr><td><code>autoBot</code></td><td>boolean</td><td>По умолчанию <code>true</code>. Если поставить <code>false</code> — скрипт <strong>не будет</strong> автоматически искать и подставлять токен в ссылки на бота. В этом случае нужно вызывать <code>window.graspil.submit()</code> вручную (см. ниже). Полезно, если вы хотите сами контролировать момент подстановки токена.</td></tr><tr><td><code>initialDelay</code></td><td>число (мс)</td><td>По умолчанию <code>1000</code>. Через сколько миллисекунд после загрузки скрипта выполнить первую автоматическую проверку ссылок на странице.</td></tr><tr><td><code>fields</code></td><td>объект</td><td>Дополнительные поля, которые нужно привязать к пользователю сразу при загрузке страницы, например <code>fields: {crm_id: '12345'}</code>. Эквивалентно вызову <code>addField()</code> для каждого поля (см. ниже).</td></tr><tr><td><code>yandex_client_id</code></td><td>boolean или строка</td><td>Если задать <code>true</code>, скрипт попытается собрать ClientID Яндекс.Метрики (из куки <code>_ym_uid</code> или через <code>ym()</code>) и передаст его как поле <code>yandex_client_id</code>. Если задать строку — под этим именем поле и будет сохранено.</td></tr><tr><td><code>google_client_id</code></td><td>boolean или строка</td><td>То же самое, но для Google Analytics (ClientID из куки <code>_ga</code>).</td></tr><tr><td><code>yandex_counter</code> / <code>ym_id</code></td><td>число/строка</td><td>Номер счётчика Яндекс.Метрики. Нужен, если куки <code>_ym_uid</code> ещё нет на момент загрузки страницы — тогда скрипт запросит ClientID через <code>ym(counterId, 'getClientID', ...)</code>.</td></tr></tbody></table>

## Переименование глобальной переменной (если `window.graspil` уже занят)

По умолчанию скрипт работает через глобальную переменную `window.graspil` — именно в неё вы кладёте конфиг (`w[l]=w[l]||[]`, где `l` в сниппете равен `"graspil"`), и через неё же потом доступны методы `addField`/`submit`/`getChannelLink`.

Если на вашем сайте уже есть свой скрипт с именем `graspil` (конфликт имён — редкий, но встречающийся случай), это имя можно поменять. За него отвечает четвёртый аргумент вызова в самом сниппете:

```html
<script>
  (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({key:i});
  var f=d.getElementsByTagName(s)[0],j=d.createElement(s);j.async=true;j.src="https://s.graspil.com?l="+l;
  f.parentNode.insertBefore(j,f);})(window,document,"script","myQueueName","ВАШ_КЛЮЧ");
</script>
```

Здесь `"graspil"` заменён на `"myQueueName"` (можно указать любое имя, не занятое на вашей странице). После этого весь конфиг и все методы будут жить не в `window.graspil`, а в `window.myQueueName` — то есть вместо `window.graspil.addField(...)`, `window.graspil.submit(...)` и `window.graspil.getChannelLink(...)` используйте `window.myQueueName.addField(...)` и так далее.

{% hint style="warning" %}
Меняйте имя, только если у вас реальный конфликт. В подавляющем большинстве случаев ничего менять не нужно — оставляйте `"graspil"` как есть.
{% endhint %}

{% hint style="info" %}
Если редактируете сниппет вручную — не убирайте часть `?l="+l` в строке с `j.src`. Именно через неё скрипт узнаёт, под каким именем вы решили его разместить. Без этой части скрипт продолжит использовать `window.graspil`, даже если вы поменяли имя в четвёртом аргументе.
{% endhint %}

## Ручное управление скриптом (JS API)

После загрузки скрипта у вас появляется объект `window.graspil` с несколькими методами. Их можно вызывать в любой момент из своего JS-кода на странице.

### `window.graspil.addField(name, value)`

Добавляет своё поле, которое будет привязано к пользователю при следующей отправке данных на сервер (при автоматической обработке или при вызове `submit()`).

```js
window.graspil.addField('crm_id', '12345')
window.graspil.addField('product_viewed', 'sku-9981')
```

{% hint style="info" %}
Поля, добавленные через `addField`, живут только в рамках текущей загрузки страницы — при переходе на новую страницу их нужно добавлять заново (или сразу передавать через `fields` в конфиге, если они не меняются).
{% endhint %}

### `window.graspil.submit(applyToLinks, callback)`

Запускает поиск и обработку ссылок на бота вручную, вне зависимости от `autoBot`. Полезно, если:

* вы отключили автоматический режим (`autoBot: false`) и хотите сами решать, когда подставлять токен;
* ссылки на бота появляются на странице динамически (например, после клика по кнопке) и вы хотите обработать их сразу, не дожидаясь автоматической проверки;
* вам нужен сам токен в JS-коде, а не только подставленный в ссылку (см. пример ниже).

| Аргумент       | Тип     | По умолчанию | Описание                                                                                                                  |
| -------------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `applyToLinks` | boolean | `true`       | Если `false` — токен **не будет** подставлен в ссылки на странице, вы получите его только в `callback`.                   |
| `callback`     | функция | `null`       | Вызывается с объектом вида `{ 'https://t.me/bot?...': 'токен' }` — по одному значению на каждую найденную ссылку на бота. |

**Пример: просто получить токен, не трогая ссылки на странице**

```js
window.graspil.submit(false, function (tokensByLink) {
    // tokensByLink = { 'https://t.me/graspil_bot': 'bai38kal' }
    for (const link in tokensByLink) {
        console.log('Токен для', link, '=', tokensByLink[link])
    }
})
```

**Пример: вручную обработать ссылки, добавленные на страницу после клика**

```js
document.getElementById('show-bot-link').addEventListener('click', function () {
    // ...здесь вы добавили в DOM новую ссылку <a href="https://t.me/graspil_bot">...
    window.graspil.submit() // найдёт новую ссылку и подставит в неё токен
})
```

### `window.graspil.getChannelLink(channelName)`

Собирает ссылку на канал/бот через сокращатель `tlin.cc`, автоматически добавляя в неё все собранные на сайте параметры (UTM-метки и ваши дополнительные поля). Возвращает `Promise` со строкой-ссылкой.

```js
window.graspil.getChannelLink('mychannel').then(function (link) {
    // link = 'https://tlin.cc/mychannel?source=google&medium=cpc'
    document.getElementById('channel-link').href = link
})
```

Про сами ссылки с переадресацией читайте в разделе [Лендинги c переадресацией](/ru/app/landings.md).

## Как получить токен без JS (просто посмотреть на странице)

Если вам не нужно ничего программировать, а нужно только чтобы ссылки на бота на сайте автоматически получали токен — ничего делать не нужно, скрипт в базовом режиме (`autoBot: true`, включён по умолчанию) сделает это сам. Токен появится в атрибуте `href` у ссылки на бота — можно посмотреть через "Инструменты разработчика" в браузере (F12 → Elements → найти ссылку).

## Технические детали и ограничения

* Скрипт хранит данные о выданных токенах в `sessionStorage` браузера — это значит, что при открытии сайта в новой вкладке или после закрытия браузера токен будет запрошен заново. Между вкладками токены не переиспользуются.
* Скрипт ничего не пишет в cookie. Он может только **читать** куки `_ym_uid` (Яндекс.Метрика) и `_ga` (Google Analytics), если включены соответствующие настройки.
* Ищутся только обычные `<a href="...">` ссылки, присутствующие в DOM. Ссылки, которые генерируются нестандартным способом (например, только через `onclick`) или находятся внутри Shadow DOM, не находятся автоматически — используйте `window.graspil.submit()` вручную после их появления.
* Если скрипт временно недоступен или произошла ошибка сети — сайт продолжит работать как обычно, ошибка просто запишется в консоль браузера и не повлияет на остальной функционал страницы.
* На одностраничных сайтах (SPA) скрипт сам отслеживает смену адреса (через `pushState`/`replaceState`) и повторно проверяет ссылки на новой "странице" — ничего дополнительно настраивать не нужно.

## FAQ

<details>

<summary>Ссылки на бота на сайте не меняются, токен не подставляется — что не так?</summary>

Самая частая причина — название бота в ссылке не совпадает с названием бота, подключённого в вашем аккаунте Graspil. Проверьте название бота в разделе [Мои боты](https://app.graspil.com/bots) → выберите бота → "Редактировать", и сравните с тем, что указано в ссылке (`https://t.me/ИМЯ_БОТА`).

Также убедитесь, что:

* скрипт установлен на странице и загружается без ошибок (проверьте вкладку Network в инструментах разработчика);
* ссылка на бота начинается именно с `https://t.me/` или `tg://resolve` — другие варианты (`http://`, `telegram.me`) не поддерживаются.

</details>

<details>

<summary>Можно ли использовать скрипт вместе с другими своими параметрами в ссылке на бота (например ?ref=abc)?</summary>

Нет, при подстановке токена скрипт удаляет остальные параметры ссылки и оставляет только `start`/`startapp` со значением токена. Все нужные данные (в том числе ваш `ref`) стоит передавать через `window.graspil.addField()` — тогда они будут привязаны к тому же токену и доступны через API получения данных по токену.

</details>

<details>

<summary>Как отключить автоматическую подстановку токена в ссылки?</summary>

Добавьте `autoBot: false` в конфиг при инициализации скрипта (см. раздел "Настройка скрипта") и вызывайте `window.graspil.submit()` вручную, когда это нужно.

</details>

<details>

<summary>Работает ли скрипт с несколькими ботами на одном сайте?</summary>

Да, скрипт обрабатывает все найденные на странице ссылки на ботов, подключённые к вашему аккаунту, независимо от их количества.

</details>
