@textback/notification-widget
v2.0.1-103212
Published
TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.
Downloads
5,786
Readme
Установка виджета на сайт
Для установки виджета подписки на сайт, сначала добавьте к вашей странице:
<script src="//cdn.jsdelivr.net/npm/@textback/notification-widget@latest/build/index.js"></script>
Внимание Виджет больше не требует подключения дополнительного скрипта с полифиллом.
Для корректного отображение виджета на адаптивных сайтах на мобильных требуется добавить следующий мета-тег в секцию <head>
:
<meta name="viewport" content="width=device-width, initial-scale=1.0>
Затем вы можете вставить один или несколько виджетов:
<tb-notification-widget widget-id="YOUR_WIDGET_ID"></tb-notification-widget>
с необходимыми widget-id. YOUR_WIDGET_ID указан в консоли администратора Textback.
Если вы планируете использовать виджет в режиме "попап", то встраивайте виджет непосредственно внутри тега body, лучше сразу перед </body>
шаблона страницы, на которую добавляется виджет.
Если виджет будет использоваться в режиме "инлайн", то добавте виджет в том месте шаблона, в котором он должен отобразиться.
Дополнительные параметры можно передать через data-атрибуты:
<tb-notification-widget
widget-id="YOUR_WIDGET_ID"
data-user-id="USER_ID"
data-order-id="ORDER_ID">
</tb-notification-widget>
Чтобы передать secureContext, нужно использовать атрибут secure-context-token
:
<tb-notification-widget
widget-id="YOUR_WIDGET_ID"
secure-context-token="YOUR_TOKEN"
</tb-notification-widget>
Динамическая инициализация виджета
Если вам необходимо динамически проинициализировать виджет, например во всплывающем окне или при разработке Single Page Application вы можете использовать класс, который доступен стразу после загрузки скрипта виджета
var widgetContainer = document.querySelector('tb-notification-widget');
var options = {
widgetId: "YOUR_WIDGET_ID",
element: widgetContainer,
data: {userId: "USER_ID", orderId: "ORDER_ID"}
};
new TextBack.NotificationWidget(options)
где widgetContainer - корневой HTML элемент, в котором необходимо отобразить виджет, data - дополнительные параметры.
Чтобы изменить параметры после инициализации виджета повторно проинициализируйте виджет на элементе с новыми параметрами:
options.data.orderId = "NEW_ORDER_ID";
new TextBack.NotificationWidget(options)
Мгновенно отобразить popup-виджет
По умолчанию при инициализации виджета используются параметры тайминга из настроек - через сколько секунд отобразить виджет, сколько раз за сессию и т.д.
Если требуется отобразить виджет сразу, то можно воспользоваться разработанным для этого API.
Сначала нужно добавить виджет на страницу, указав атрибут only-manual
<tb-notification-widget widget-id="YOUR_WIDGET_ID" only-manual></tb-notification-widget>
Добавленный таким образом виджет будет скрыт и не будет показан автоматически.
Чтобы теперь отобразить виджет, нужно выполнить следующий код:
TextBack.NotificationWidget.getWidget('YOUR_WIDGET_ID').then(function(widget) {
widget.show();
});
Пример отображения виджета при нажатии на кнопку:
document.querySelector('#YOUR_BUTTON_ID').addEventListener('click', function() {
TextBack.NotificationWidget.getWidget('YOUR_WIDGET_ID').then(function(widget) {
widget.show();
});
});
Предпросмотр виджета
Релизован механизм, позволяющий задать JSON виджета динамически, не подгружая его по ID с нашего API. Для того, чтобы подписки работали в предпросомтре, необходимо, чтобы виджет был сохранен в БАЗУ и имел присвоенный ID.
Этот механизм внедрян для добавления функционала пред-просмотра виджета в нашем редакторе, но ижет быть использован сторонними разработчикми, для динамической генерации сообщения приветствия, однака надо иметь в виду, что ЭТО апи не финальное, и может изменится в любой момент, используйте на свой страх и риск.
Использование:
//получаем копию настроек виджета
var data = angular.copy(notificationWidgetJSON);
//override settings for preview purpose
//переопределяем некторыесвойства, сохраненные на сервере
//отображатся в виджете будет нвое значение.
data.displayOptions.onLeave = null;
data.displayOptions.timeoutDelay = 0;
data.displayOptions.onTimeout = "yes";
//к примеру vkApiId привязан к домену, на котром отображается виджет
data.vkApiId=TextBack.configuration.get('vkAppId');
//динамически создаем контейнер для виджета
var widgetContainerJq = $('<div></div>');
$('body').append(widgetContainerJq);
var widgetContainer = widgetContainerJq[0];
var options = {
apiPath: 'https://api.textback.io/api', //необязатльный параметр
element: widgetContainer,
widgetConfig: data
};
new TextBack.NotificationWidget(options)
Локализация
Все поддерживаемые языки находятся в переменной TextBack.NotificationWidget.locales
. Перевод затрагивает только статичные элементы виджета, значения которых не задаются в настройках виджета.
Чтобы применить нужный язык к виджету, передайте соответсвующий параметр lang
в тег виджета:
<tb-notification-widget widget-id="YOUR_WIDGET_ID" lang="ru">
</tb-notification-widget>
или
var widgetContainer = document.querySelector('tb-notification-widget');
var options = {
widgetId: "YOUR_WIDGET_ID",
element: widgetContainer,
lang: 'ru'
};
new TextBack.NotificationWidget(options)
Чтобы изменить существующий перевод, передайте новое значение для нужной переменной в TextBack.NotificationWidget.locales:
<script>TextBack.NotificationWidget.locales.ru.whatsappb = 'Узнать больше'</script>
Вы можете создать новый перевод для всех элементов виджета (это касается как виджета подписок, так и WhatsApp Hunter):
- В личном кабинете установите значение языка по умолчанию, чтобы аттрибут lang не передавался с нашего сервера;
- В теге виджета на странице установите аттрибут lang со значением языка (это будет название новой локализации - locales);
- Передайте значения для всех переменных в массиве после кода виджета. Для незаданных переменных будет использоваться язык по умолчанию - английский.
Важно! И для виджета подписок, и для WhatsApp Hunter перевод берется из TextBack.NotificationWidget.locales. Если на странице используются оба виджета и обоим нужно задать полную кастомную локализацию в рамках одного locales, значения переменных нужно объявлять в одном массиве. Если объявить переменные по отдельности, то использоваться будет последняя переменная - неполная.
Если для виджетов заданы разные lang, то объявите переменные для каждого виджета в отдельном массиве.
Пример перевода виджета подписок на французский
<script>
TextBack.NotificationWidget.locales.fr = {
facebook: "Facebook",
facebookExtended: "Abonnez-vous à Facebook",
telegram: "Telegram",
telegramExtended: "Abonnez-vous à Telegram",
viber: "Viber",
viberExtended: "Subscribe to Viber",
vkontakte: "VK",
vkontakteExtended: "Abonnez-vous à Viber",
whatsapp: "WhatsApp",
whatsappExtended: "Abonnez-vous à WhatsApp",
whatsappb: "WhatsApp",
whatsappbExtended: "Abonnez-vous à WhatsApp"
}
</script>
Список всех переменных
Виджет подписок (пример для английского языка)
facebook: "Facebook", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
facebookExtended: "Subscribe to Facebook", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
telegram: "Telegram", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
telegramExtended: "Subscribe to Telegram", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
viber: "Viber", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
viberExtended: "Subscribe to Viber", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
vkontakte: "VK", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" и "попап".
vkontakteExtended: "Subscribe to VK", //если выбран лендинг ВК и вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
whatsapp: "WhatsApp", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
whatsappExtended: "Subscribe to WhatsApp", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
whatsappb: "WhatsApp", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
whatsappbExtended: "Subscribe to WhatsApp", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
//NB: если не использовать лендинг ВК, то при выборе прямоугольных кнопок или попапа используется нативная кнопка, перевод которой пока не реализован
WhatsApp Hunter (пример для английского языка)
getAnswer: "Get an answer in ", //согласие на получение сообщений
enterNumber: "Enter your phone number", //placeholder в инпуте
sendMessage: "We'll send a message in 3-2-1 sec", //В процессе отправки сообщения
answerSuccessful: "We've answered you in WhatsApp. <br> Check your phone", //После успешной отправки
numberNotFound: "There is no such user in WhatsApp. <br> Are you from Mars?🤔", //Ошибка, формат номера некорректный
tryAgain: "Try another number", //Повтор ввода, если номер не найден
somethingWentWrong: "Oops! Something went wrong", //на 500 при отправке сообщения (например, канал не подключен)
errorTryAgain: "Try again", //Повтор ввода при ошибки 500
TextBack Widget SDK
TextBack Widget SDK предоставляет набор функций для управления подпиской.
SDK входит в состав виджета, но может быть подключен отдельно(см. ниже).
Преимущества SDK, в сравнении с виджетом подписок:
- SDK позволяет полностью настраивать внешний вид вашего UI, предоставляя только функции подписки пользователей.
- Файл с SDK имеет меньший размер, чем файл с виджетом подписок.
Как использовать SDK
Подключение
Добавить в код страницы
<script src="//cdn.jsdelivr.net/npm/@textback/notification-widget@latest/build/sdk.js"></script>
После этого на странице будет доступен объект TextBack.SDK
Использование
Приведенный ниже код будет подписывать пользователя в Telegram при клике на ссылку с id="MY_TG_BUTTON"
:
var config = {
widgetId: 'YOUR_WIDGET_ID'
};
TextBack.SDK.initWidget(config).then(
function(widget) {
document.getElementById('MY_TG_BUTTON').addEventListener('click', function(event) {
event.preventDefault();
widget.subscribe('tg');
})
}
);
ВАЖНО! Элемент с id="MY_TG_BUTTON"
должен присутствовать на странице во время исполнения скрипта.
Более подробное описание функции initWidget()
, состава полей объекта конфигурации и других функций SDK смотрите ниже.
SDK API
Примечание. В документации по SDK под "виджетом" подразумевается не "виджет подписок", упоминавшийся ранее, а объект, который содержит настройки и методы виджета. Таким образом "инициализация виджета" - это не отрисовка виджета на странице, а загрузка настроек с сервера и подготовка к работе.
Иными словами: "виджет" = "объект в приложении", "виджет подписок" = "объект в JavaScript" + "UI".
Глобальное пространство имен
SDK и виджет подписок доступны как свойства SDK
и NotificationWidget
глобального объекта TextBack
соответственно.
Для своей работы SDK использует полифиллы для метода window.fetch()
и объекта ES6 Promise
.
Также, для работы с каналами VKontakte, используется VK JS API, представленное глобальным объектом VK.
TextBack.SDK API
Объект TextBack.SDK
предоставляет API для инициализации виджетов и работы с ними.
Метод initWidget(config)
Инициализирует новый виджет по заданному объекту конфигурации.
Принимает
Объект config
со следующими полями:
- widgetId - (обязательный) идентификатор виджета. Если виджет с таким идентификатором уже есть, то виджет будет перезагружен;
- secureContextToken - строка;
- insecureContext - объект;
- apiPath - адрес сервера;
- overrideConfig - объект с настройками виджета. Если задан, то настройки виджета не будут загружаться с сервера, и для инициализации виджета будет использован данный объект;
- customData - произвольные пользовательские данные.
Возвращает Promise, который будет fulfilled объектом виджета.
Пример использования
var config = {
widgetId: 'YOUR_WIDGET_ID',
insecureContext: {
data: 'data'
}
};
TextBack.SDK.initWidget(config).then(
function(widget) {
console.log('Widget has been initialized.');
}
);
Метод getWidget(widgetId)
Принимает widgetId
- идентификатор виджета.
Возвращает Promise, возвращаемый функцией initWidget()
, соответствующий переданному идентификатору.
Пример использования
TextBack.SDK.getWidget('YOUR_WIDGET_ID').then(
function(widget) {
console.log('Widget has id = ' + widget.id);
}
)
Метод on(eventName, callback)
Вешает обработчик callback
на событие eventName
. При наступлении события в callback
первым аргументом будет передан объект события. Описание полей объекта события для различных событий см. ниже.
Поддерживаемые события
- 'widget.init' - успеная инициализация виджета. поля события:
- widgetId - идентификатор виджета
- 'subscribe.start' - вызвана функция подписки на канал. поля события:
- widgetId - идентификатор виджета
- channel - объект канала, на который осуществляется подписка
Возвращает
Функцию отписки обработчика callback
от события.
Пример использования
При инициализации первого виджета вывести в консоль сообщение.
const config = {
widgetId: 'YOUR_WIDGET_ID'
};
TextBack.SDK.initWidget(config);
const off = TextBack.SDK.on('widget.init', function(event) {
console.log('First widget with id = ' + event.widgetId + ' has been initilized');
off();
})
Метод deeplinkUpdater(String)
deeplinkUpdater :: String -> Promise -> Function
Ф-ция getDeeplinkUpdater() принимает идентефикатор виджета и возвращает Promise, содержащий ф-цию, позволяющую обновлять данные в insecureContext с помощью PATCH запроса.
Пример использования
Данный пример отправит в insecureContext данные на событие подписки.
TextBack.SDK.getDeeplinkUpdater('myWidgetId').then(f => {
let data = {
foo: 'foo',
bar: 'bar'
};
TextBack.SDK.on('subscribe.start', () => f(data));
});
Widget API
Объект Widget предоставляет функции для работы с конкретным виджетом.
Метод subscribe(channelType)
Инициализирует подписку пользователя на канал.
Принимает channelType - тип канала, на который следует осуществить подписку. Поддерживаются следующие коды каналов:
'facebook'
- Facebook'tg'
- Telegram'viber'
- Viber'vk'
- Vkontakte'whatsapp'
- WhatsApp'whatsappb'
- WhatsApp Business API'skype'
- Skype
Внимание!
- Мы настоятельно рекомендуем вызывать эту функцию непосредственно из обработчика клика на кнопку/ссылку, во избежание блокирования функции браузером.
Пример использования
var config = {
widgetId: 'YOUR_WIDGET_ID'
};
TextBack.SDK.initWidget(config).then(
function(widget) {
document.getElementById('MY_TG_BUTTON').addEventListener('click', function(event) {
event.preventDefault();
widget.subscribe('tg');
});
document.getElementById('MY_VK_BUTTON').addEventListener('click', function(event) {
event.preventDefault();
widget.subscribe('vk');
})
}
);
Метод getConfig()
Возвращает загруженный с сервера объект конфигурации виджета
Метод getChannels()
Возвращает объекты каналов виджета(см. Channel
ниже)
Метод getEnabledChannels()
Возвращает объекты каналов виджета, которые сейчас активны и инициализированны без ошибок.
Пример использования
var config = {
widgetId: 'YOUR_WIDGET_ID'
};
TextBack.SDK.initWidget(config).then(
function(widget) {
console.log('Total channels: ' + widget.getChannels().length);
console.log('Enabled channels: ' + widget.getEnabledChannels().length);
}
);
Channel API
Объекты Channel
предоставляют API конкретных каналов в виджете. Каждый канал реализует свою собственную функцию подписки пользователя.
Свойство hasError
Устанавливается в значение true
, если при инициализации канала произошла ошибка (например, если не удалось загрузить внешнюю библиотеку для канала VKontakte). Информация об ошибке будет выведена в консоль.
Каналы, для которых hasError == true
не вовзращаются при вызове метода getEnabledChannels()
у объекта виджета.
Метод subscribe()
Инициализирует процесс подписки пользователя на канал.
Пример использования
var config = {
widgetId: 'YOUR_WIDGET_ID'
};
TextBack.SDK.initWidget(config).then(
function(widget) {
document.getElementById('MY_BUTTON').addEventListener('click', function(event) {
event.preventDefault();
const channels = widget.getEnabledChannels();
if (channels.length > 0) {
channels[0].subscribe();
console.log('User has been subscribed on ' + channels[0].channel + ' channel');
} else {
console.log('No channels available for subscription');
}
});
}
);
Пример
Страница с двумя ссылками, подписывающими в Telegram и Vkontakte.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TextBack SDK Example</title>
</head>
<body>
<h1>TextBack SDK</h1>
<a href="" id="sign_tg">Telegram</a>
<a href="" id="sign_vk">Vkontakte</a>
<script src="//cdn.jsdelivr.net/npm/@textback/notification-widget@latest/build/sdk.js"></script>
<script type="text/javascript">
var config = {
widgetId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
};
var off = TextBack.SDK.on('widget.init', function(event) {
console.log('First widget has been initialized. ' + event.widgetId);
off();
});
TextBack.SDK.initWidget(config).then(function(widget) {
document.getElementById('sign_tg').addEventListener('click', function(event) {
event.preventDefault();
widget.subscribe('tg');
});
document.getElementById('sign_vk').addEventListener('click', function(event) {
event.preventDefault();
widget.subscribe('vk');
});
});
</script>
</body>
</html>
Разработка
В терминале перейдите в директорию исходного кода виджета и выполните команды:
npm run dev
PORT=8080 npm start
После этого тестовый стенд будет доступен локально по адресу http://localhost:8080/examples
Если переменная PORT не указана, по умолчанию будет использован порт 3000
После любых изменений кода обновите страницу браузера
Для проверки codestyle выполните
npm run test:lint
Тестирование
Для запуска тестов выполните
npm run build
npm run test:all
Тесты будут запущенны во всех браузерах, установленных на локальной машине.
Тестирование осуществляется с помощью https://github.com/DevExpress/testcafe
Все тесты запускаются из директории ./tests