npm package: @sigmamessaging/otp-widget
Description: OTP widget.
Latest version: 1.7.0

# Виджет OTP

<p align="center">
  <img src="https://sigmasms.ru/wp-content/uploads/2023/01/logo.svg" alt="Sigma Messaging" />
</p>
<p align="center">
  <img src="https://img.shields.io/npm/v/@sigmamessaging/otp-widget.svg" alt="NPM Version" />
  <img src="https://img.shields.io/npm/dt/@sigmamessaging/otp-widget.svg" alt="Downloads Total" />
  <img src="https://img.shields.io/npm/dw/@sigmamessaging/otp-widget.svg" alt="Downloads Week" />
</p>

## Обзор

Виджет OTP - позволяет пользователям подтверждать свои номера телефонов с помощью одноразового пароля (OTP).

## Интеграция

Следуйте этим простым шагам, чтобы интегрировать виджет OTP на вашу веб-страницу:

> **Внимание!** Для полноценной работы виджета OTP недостаточно просто подключить и настроить сам виджет на вашей веб-странице. Необходимо также развернуть [SIGMA OTP NodeJS SDK](https://www.npmjs.com/package/@sigmamessaging/otp-sdk) на вашем Backend и настроить проксирование запросов через `nginx` (или другой reverse proxy). Это обеспечит корректную маршрутизацию запросов между виджетом и SDK.

**Рекомендуемая схема интеграции:**

1. Разверните и настройте ***SIGMA OTP NodeJS SDK*** на вашем сервере.
2. Настройте `nginx` для проксирования API-запросов от виджета к SDK.
3. Следуйте инструкциям ниже для подключения виджета на вашу веб-страницу.

Подробнее о настройке SDK смотрите в документации по [SIGMA OTP NodeJS SDK](https://www.npmjs.com/package/@sigmamessaging/otp-sdk).

### Подключение скрипта виджета

Добавьте следующий код в секцию `<body>` вашего HTML-файла. Это подключит виджет на вашу страницу:

```html
<script type="module" src="https://unpkg.com/@sigmamessaging/otp-widget@latest/otp-widget.umd.js"></script>
```

### Подключение шрифта

В процессе инициализации виджета в `<head>` вашего сайта будет добавлен `<link>` для подключения шрифта **Rubik** с толщинами `400` и `500`. Это необходимо для корректного отображения визуальной составляющей виджета.

Пример подключения шрифта:

```html
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;500&display=swap">
```

### Настройка параметров виджета

Перед добавлением виджета на страницу, настройте его параметры. Виджет считывает параметры из переменной `OTP_WIDGETS` находящемся в глобальной переменной `window`. `OTP_WIDGETS` это массив, так как вы можете использовать несколько виджетов на одной странице. Каждый объект в массиве представляет отдельный виджет.

Пример настройки:

```html
<script>
  window.OTP_WIDGETS = [
    {
      widgetId: 'your-widget-id', // Уникальный идентификатор вашего виджета
      containerId: 'otp-widget', // (Необязательно) ID контейнера для виджета. По умолчанию: 'otp-widget'
      prefix: '', // (Необязательно) Префикс для маршрута в API запросах
      locale: 'ru', // (Необязательно) Локаль виджета. По умолчанию: 'ru'
      autofocus: true, // (Необязательно) Включить авто-фокус на поле ввода. По умолчанию: true
      theme: 'light', // (Необязательно) Тема виджета. По умолчанию: 'light'
      sitekey: 'your-site-key' // (Необязательно) Сайт-ключ для интеграции капчи
    }
  ];
</script>
```

### Капча

Если вы хотите использовать капчу в виджете, добавьте параметр `sitekey` с вашим ключом сайта. Поддерживаются следующие провайдеры капчи:

- **reCAPTCHA v2** - от Google
- **SmartCaptcha** - от Яндекса
- **Turnstile** - от Cloudflare

При использовании капчи, виджет автоматически добавит соответствующий скрипт в `<head>` вашего HTML-документа. Вам не нужно беспокоиться о подключении скрипта капчи вручную. Элемент капчи будет встроен в body вашего HTML-документа с абсолютным позиционированием, чтобы не мешать остальному контенту страницы. Капча будет запрашиваться перед отправкой кода при вводе номера телефона, и пользователь должен будет пройти проверку, если провайдер капчи посчитает запрос подозрительным.

### Добавление контейнера для виджета

Создайте HTML-элемент с ID, который вы указали в параметре `containerId` (по умолчанию `otp-widget`).

Пример контейнера:

```html
<div id="otp-widget"></div>
```

### Итоговый пример HTML

Ваш итоговый HTML-файл должен выглядеть примерно так:

```html
<!DOCTYPE html>
<html lang="ru">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Rubik:wght@400;500&display=swap">
  <title>Интеграция виджета OTP</title>
</head>

<body>
  <!-- Подключение виджета -->
  <script type="module" src="https://unpkg.com/@sigmamessaging/otp-widget@latest/otp-widget.umd.js"></script>

  <!-- Настройка виджета -->
  <script>
    window.OTP_WIDGETS = [
      {
        widgetId: 'your-widget-id', // Укажите ваш уникальный идентификатор
        locale: 'ru', // Локаль виджета
        autofocus: true // Авто-фокус на поле ввода
      }
    ];
  </script>

  <!-- Контейнер для виджета -->
  <div id="otp-widget"></div>
</body>

</html>
```

## Несколько виджетов на одной странице

Если вы хотите использовать несколько виджетов на одной странице, просто добавьте дополнительные объекты в массив `window.OTP_WIDGETS`. Каждый объект должен иметь уникальный `widgetId` и `containerId`.

Пример с двумя виджетами:

```html
<!-- Настройка виджетов -->
<script>
  window.OTP_WIDGETS = [
    {
      widgetId: 'widget-1',
      containerId: 'otp-widget-1',
      locale: 'ru',
      autofocus: true,
      theme: 'light'
    },
    {
      widgetId: 'widget-2',
      containerId: 'otp-widget-2',
      locale: 'en',
      autofocus: false,
      theme: 'dark'
    }
  ];
</script>

<!-- Контейнеры для виджетов -->
<div id="otp-widget-1"></div>
<div id="otp-widget-2"></div>
```

### Что произойдет с `<div id="otp-widget"></div>`?

После подключения скрипта и настройки параметров виджета, элемент `<div id="otp-widget"></div>` будет заменен на кастомный элемент `<otp-widget></otp-widget>`. Этот элемент содержит весь функционал виджета OTP.

#### Поиск контейнера

Скрипт использует нативную функцию `document.getElementById()` для поиска элемента с ID, указанным в параметре `containerId` (по умолчанию `otp-widget`). Будет найдено **первое вхождение** элемента с таким ID, и именно оно будет заменено на виджет.

> Убедитесь, что ID контейнера уникален на вашей странице, чтобы избежать случайной замены другого содержимого.

## Конфигурация

| Поле          | Тип     | Обязательно | По умолчанию | Описание                                              |
| ------------- | ------- | ----------- | ------------ | ----------------------------------------------------- |
| `widgetId`    | string  | Да          |              | Уникальный идентификатор виджета.                     |
| `containerId` | string  | Нет         | `otp-widget` | ID HTML элемента, для инициализации виджета.          |
| `prefix`      | string  | Нет         |              | Префикс для маршрута в API запросах.                  |
| `locale`      | string  | Нет         | `ru`         | Локаль виджета. Возможные варианты: `ru`, `en`, `es`. |
| `autofocus`   | boolean | Нет         | `true`       | Включить авто-фокус на поле ввода.                    |
| `theme`       | string  | Нет         | `light`      | Тема виджета. Возможные варианты: `light`, `dark`.    |

### Префикс для API запросов

`prefix` - это префикс, который будет добавлен к URL-адресу API запросов. Например, если вы хотите использовать кастомный маршрут для API, вы можете указать его здесь. Если не указано, будет использоваться стандартный маршрут.
Пример использования префикса:

```html
<script>
  window.OTP_WIDGETS = [
    {
      widgetId: 'your-widget-id',
      prefix: 'custom-prefix', // Пример уникального префикса
    }
  ];
</script>
```

В этом случае все API запросы будут отправляться на адрес `https://example.com/custom-prefix/...`.

## Эмитируемые события

Виджет эмитирует несколько событий, которые можно отслеживать для различных действий:

- `code:send`

Эмитируется при отправке кода. Детали события содержат объект со следующими свойствами:

```JavaScript
{
  requestId: string, // ID текущего запроса
  recipient: string // Номер телефона
}
```

- `code:check`

Эмитируется при проверке кода. Детали события содержат объект со следующими свойствами:

```JavaScript
{
  requestId: string, // ID текущего запроса
  recipient: string, // Номер телефона
  status: boolean // Статус проверки кода
}
```

Пример отслеживания событий:

```JavaScript
// Получаем элемент виджета по ID контейнера
const otpWidget = document.getElementById(containerId);

// Пример отслеживания события отправки кода
otpWidget.addEventListener('code:send', (event) => {
  console.log('Код отправлен:', event.detail[0]);
  /*
  {
    requestId: '123456',
    recipient: '+79991234567'
  }
   */
});

// Пример отслеживания события проверки кода
otpWidget.addEventListener('code:check', (event) => {
  console.log('Код проверен:', event.detail[0]);
  /*
  {
    requestId: '123456',
    recipient: '+79991234567',
    status: true
  }
   */
});
```