Для установки виджета подписки на сайт, сначала добавьте к вашей странице:
<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)
По умолчанию при инициализации виджета используются параметры тайминга из настроек - через сколько секунд отобразить виджет, сколько раз за сессию и т.д.
Если требуется отобразить виджет сразу, то можно воспользоваться разработанным для этого 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 предоставляет набор функций для управления подпиской.
SDK входит в состав виджета, но может быть подключен отдельно(см. ниже).
Преимущества SDK, в сравнении с виджетом подписок:
- SDK позволяет полностью настраивать внешний вид вашего UI, предоставляя только функции подписки пользователей.
- Файл с 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 под "виджетом" подразумевается не "виджет подписок", упоминавшийся ранее, а объект, который содержит настройки и методы виджета. Таким образом "инициализация виджета" - это не отрисовка виджета на странице, а загрузка настроек с сервера и подготовка к работе.
Иными словами: "виджет" = "объект в приложении", "виджет подписок" = "объект в JavaScript" + "UI".
SDK и виджет подписок доступны как свойства SDK
и NotificationWidget
глобального объекта TextBack
соответственно.
Для своей работы SDK использует полифиллы для метода window.fetch()
и объекта ES6 Promise
.
Также, для работы с каналами VKontakte, используется VK JS API, представленное глобальным объектом VK.
Объект TextBack.SDK
предоставляет API для инициализации виджетов и работы с ними.
Инициализирует новый виджет по заданному объекту конфигурации.
Принимает
Объект 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.');
}
);
Принимает widgetId
- идентификатор виджета.
Возвращает Promise, возвращаемый функцией initWidget()
, соответствующий переданному идентификатору.
TextBack.SDK.getWidget('YOUR_WIDGET_ID').then(
function(widget) {
console.log('Widget has id = ' + widget.id);
}
)
Вешает обработчик 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();
})
Ф-ция 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 предоставляет функции для работы с конкретным виджетом.
Инициализирует подписку пользователя на канал.
Принимает 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');
})
}
);
Возвращает загруженный с сервера объект конфигурации виджета
Возвращает объекты каналов виджета(см. Channel
ниже)
Возвращает объекты каналов виджета, которые сейчас активны и инициализированны без ошибок.
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 конкретных каналов в виджете. Каждый канал реализует свою собственную функцию подписки пользователя.
Устанавливается в значение true
, если при инициализации канала произошла ошибка (например, если не удалось загрузить внешнюю библиотеку для канала VKontakte). Информация об ошибке будет выведена в консоль.
Каналы, для которых hasError == true
не вовзращаются при вызове метода getEnabledChannels()
у объекта виджета.
Инициализирует процесс подписки пользователя на канал.
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