@textback/notification-widget 2.0.1-84986 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. package/.eslintrc.js +291 -291
  2. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  3. package/.idea/misc.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/notificationwidget.iml +9 -0
  6. package/.idea/vcs.xml +6 -0
  7. package/build/index.js +3 -3
  8. package/build/sdk.js +2 -2
  9. package/package.json +70 -70
  10. package/promote_tag.sh +1 -1
  11. package/readme.md +569 -569
  12. package/server.js +1 -1
  13. package/src/libraries/ai.1.0.11.js +4088 -4088
  14. package/src/libraries/localization/locales/index.js +8 -8
  15. package/src/libraries/localization/text.js +9 -9
  16. package/src/libraries/t.js +82 -82
  17. package/src/sdk/channels/channel.js +30 -30
  18. package/src/sdk/channels/facebook.js +13 -13
  19. package/src/sdk/channels/skype.js +12 -12
  20. package/src/sdk/channels/telegram.js +18 -18
  21. package/src/sdk/channels/viber.js +12 -12
  22. package/src/sdk/channels/vk-modal/vk-modal.html +17 -17
  23. package/src/sdk/channels/vk-modal/vk-modal.js +25 -25
  24. package/src/sdk/channels/vk-modal/vk-modal.scss +116 -116
  25. package/src/sdk/channels/vk.js +195 -195
  26. package/src/sdk/events/observer.js +46 -46
  27. package/src/sdk/index.js +5 -5
  28. package/src/sdk/sdk.js +67 -67
  29. package/src/sdk/utils/apiErrorHandler.js +11 -11
  30. package/src/sdk/utils/appInsights.js +88 -88
  31. package/src/sdk/utils/browserInfo.js +8 -8
  32. package/src/sdk/utils/constants.js +17 -17
  33. package/src/sdk/utils/cookies.js +67 -67
  34. package/src/sdk/utils/find.js +7 -7
  35. package/src/sdk/utils/loadConfig.js +20 -20
  36. package/src/sdk/utils/loadDeepLink.js +48 -48
  37. package/src/sdk/utils/loadScript.js +25 -25
  38. package/src/sdk/utils/loadSubscriptions.js +6 -6
  39. package/src/sdk/utils/parseQueryString.js +33 -33
  40. package/src/sdk/utils/windowHelper.js +25 -25
  41. package/src/sdk/widget/widget.js +192 -192
  42. package/src/widget/components/tb-notification-button/index.js +34 -34
  43. package/src/widget/components/tb-notification-button/styles.scss +657 -657
  44. package/src/widget/components/tb-notification-widget/normalize.scss +395 -395
  45. package/src/widget/components/tb-nw-wahunter/styles.scss +471 -471
  46. package/src/widget/config.js +5 -5
  47. package/src/widget/icons/icon_chat_window.svg +1 -1
  48. package/src/widget/icons/icon_close.svg +1 -1
  49. package/src/widget/icons/icon_facebook.svg +7 -7
  50. package/src/widget/icons/icon_facebook_circle.svg +7 -7
  51. package/src/widget/icons/icon_instagram_circle.svg +95 -95
  52. package/src/widget/icons/icon_skype.svg +44 -44
  53. package/src/widget/icons/icon_skype_circle.svg +46 -46
  54. package/src/widget/icons/icon_skype_new.svg +113 -113
  55. package/src/widget/icons/icon_tg.svg +25 -25
  56. package/src/widget/icons/icon_tg_circle.svg +17 -17
  57. package/src/widget/icons/icon_viber.svg +75 -75
  58. package/src/widget/icons/icon_viber_circle.svg +67 -67
  59. package/src/widget/icons/icon_viber_new.svg +102 -102
  60. package/src/widget/icons/icon_vk.svg +14 -14
  61. package/src/widget/icons/icon_vk_circle.svg +16 -16
  62. package/src/widget/icons/icon_whatsapp.svg +147 -147
  63. package/src/widget/icons/icon_whatsapp_circle.svg +3 -3
  64. package/src/widget/icons/icon_whatsapp_new.svg +127 -127
  65. package/src/widget/icons/icon_whatsappb.svg +147 -147
  66. package/src/widget/icons/icon_whatsappb_circle.svg +3 -3
  67. package/src/widget/icons/icon_whatsappb_new.svg +127 -127
  68. package/src/widget/icons/paper-plane-arrow.svg +3 -3
  69. package/src/widget/icons/tb-logo.svg +21 -21
  70. package/src/widget/index.js +28 -28
  71. package/src/widget/locales/cs.js +42 -42
  72. package/src/widget/locales/en.js +42 -42
  73. package/src/widget/locales/ro.js +41 -41
  74. package/src/widget/utils/cookiesEx.js +41 -41
  75. package/src/widget/utils/stringifyAttributes.js +19 -19
  76. package/src/widget/utils/widgetsStorage.js +28 -28
  77. package/src/widget/widget.entry.js +3 -3
  78. package/tests/gf.html +35 -35
  79. package/tests/gf.js +21 -21
  80. package/tests/index.js +61 -61
  81. package/views/examples.ejs +3 -3
  82. package/views/sdk.html +274 -274
  83. package/webpack.common.js +72 -72
  84. package/webpack.dev.js +15 -15
  85. package/webpack.prod.js +10 -10
package/readme.md CHANGED
@@ -1,569 +1,569 @@
1
- # Установка виджета на сайт
2
-
3
- Для установки виджета подписки на сайт, сначала добавьте к вашей странице:
4
-
5
- ```
6
- <script src="//unpkg.com/@textback/notification-widget@latest/build/index.js"></script>
7
- ```
8
- **Внимание** Виджет больше не требует подключения дополнительного скрипта с полифиллом.
9
-
10
- Для корректного отображение виджета на адаптивных сайтах на мобильных требуется добавить следующий мета-тег в секцию `<head>`:
11
- ```html
12
- <meta name="viewport" content="width=device-width, initial-scale=1.0>
13
- ```
14
-
15
- Затем вы можете вставить один или несколько виджетов:
16
-
17
- ```
18
- <tb-notification-widget widget-id="YOUR_WIDGET_ID"></tb-notification-widget>
19
- ```
20
-
21
- с необходимыми widget-id. YOUR_WIDGET_ID указан в консоли администратора Textback.
22
-
23
- Если вы планируете использовать виджет в режиме "попап", то встраивайте виджет непосредственно внутри тега body, лучше сразу перед `</body>` шаблона страницы, на которую добавляется виджет.
24
-
25
- Если виджет будет использоваться в режиме "инлайн", то добавте виджет в том месте шаблона, в котором он должен отобразиться.
26
-
27
- Дополнительные параметры можно передать через data-атрибуты:
28
-
29
- ```
30
- <tb-notification-widget
31
- widget-id="YOUR_WIDGET_ID"
32
- data-user-id="USER_ID"
33
- data-order-id="ORDER_ID">
34
- </tb-notification-widget>
35
- ```
36
-
37
- Чтобы передать secureContext, нужно использовать атрибут `secure-context-token`:
38
- ```html
39
- <tb-notification-widget
40
- widget-id="YOUR_WIDGET_ID"
41
- secure-context-token="YOUR_TOKEN"
42
- </tb-notification-widget>
43
- ```
44
-
45
- ## Динамическая инициализация виджета
46
-
47
- Если вам необходимо динамически проинициализировать виджет, например во всплывающем окне или при разработке Single Page Application
48
- вы можете использовать класс, который доступен стразу после загрузки скрипта виджета
49
-
50
- ```
51
- var widgetContainer = document.querySelector('tb-notification-widget');
52
-
53
- var options = {
54
- widgetId: "YOUR_WIDGET_ID",
55
- element: widgetContainer,
56
- data: {userId: "USER_ID", orderId: "ORDER_ID"}
57
- };
58
-
59
- new TextBack.NotificationWidget(options)
60
- ```
61
-
62
- где widgetContainer - корневой HTML элемент, в котором необходимо отобразить виджет, data - дополнительные параметры.
63
-
64
- Чтобы изменить параметры после инициализации виджета повторно проинициализируйте виджет на элементе с новыми параметрами:
65
-
66
- ```
67
- options.data.orderId = "NEW_ORDER_ID";
68
-
69
- new TextBack.NotificationWidget(options)
70
- ```
71
-
72
- ### Мгновенно отобразить popup-виджет
73
- По умолчанию при инициализации виджета используются параметры тайминга из настроек - через сколько секунд отобразить виджет, сколько раз за сессию и т.д.
74
-
75
- Если требуется отобразить виджет сразу, то можно воспользоваться разработанным для этого API.
76
-
77
- Сначала нужно добавить виджет на страницу, указав атрибут ```only-manual```
78
- ```html
79
- <tb-notification-widget widget-id="YOUR_WIDGET_ID" only-manual></tb-notification-widget>
80
- ```
81
- Добавленный таким образом виджет будет скрыт и не будет показан автоматически.
82
-
83
- Чтобы теперь отобразить виджет, нужно выполнить следующий код:
84
- ```javascript
85
- TextBack.NotificationWidget.getWidget('YOUR_WIDGET_ID').then(function(widget) {
86
- widget.show();
87
- });
88
- ```
89
-
90
- Пример отображения виджета при нажатии на кнопку:
91
- ```javascript
92
- document.querySelector('#YOUR_BUTTON_ID').addEventListener('click', function() {
93
- TextBack.NotificationWidget.getWidget('YOUR_WIDGET_ID').then(function(widget) {
94
- widget.show();
95
- });
96
- });
97
- ```
98
-
99
- ### Предпросмотр виджета
100
- Релизован механизм, позволяющий задать JSON виджета динамически, не
101
- подгружая его по ID с нашего **API**. Для того, чтобы подписки работали
102
- в предпросомтре, необходимо, чтобы виджет был сохранен в БАЗУ
103
- и имел присвоенный ID.
104
-
105
- ---
106
- Этот механизм внедрян для добавления функционала пред-просмотра виджета
107
- в нашем редакторе, но ижет быть использован сторонними разработчикми,
108
- для динамической генерации сообщения приветствия, однака надо
109
- иметь в виду, что **ЭТО апи не финальное, и может изменится в любой момент**,
110
- используйте на свой страх и риск.
111
-
112
- ---
113
-
114
- Использование:
115
-
116
- ```javascript
117
- //получаем копию настроек виджета
118
- var data = angular.copy(notificationWidgetJSON);
119
-
120
-
121
- //override settings for preview purpose
122
- //переопределяем некторыесвойства, сохраненные на сервере
123
- //отображатся в виджете будет нвое значение.
124
- data.displayOptions.onLeave = null;
125
- data.displayOptions.timeoutDelay = 0;
126
- data.displayOptions.onTimeout = "yes";
127
-
128
- //к примеру vkApiId привязан к домену, на котром отображается виджет
129
- data.vkApiId=TextBack.configuration.get('vkAppId');
130
-
131
-
132
-
133
- //динамически создаем контейнер для виджета
134
- var widgetContainerJq = $('<div></div>');
135
- $('body').append(widgetContainerJq);
136
-
137
- var widgetContainer = widgetContainerJq[0];
138
-
139
-
140
- var options = {
141
- apiPath: 'https://api.textback.io/api', //необязатльный параметр
142
- element: widgetContainer,
143
- widgetConfig: data
144
- };
145
-
146
- new TextBack.NotificationWidget(options)
147
- ```
148
-
149
- # Локализация
150
-
151
- Все поддерживаемые языки находятся в переменной `TextBack.NotificationWidget.locales`. Перевод затрагивает только статичные элементы виджета, значения которых не задаются в настройках виджета.
152
-
153
- Чтобы применить нужный язык к виджету, передайте соответсвующий параметр `lang` в тег виджета:
154
-
155
- ```
156
- <tb-notification-widget widget-id="YOUR_WIDGET_ID" lang="ru">
157
- </tb-notification-widget>
158
- ```
159
-
160
- или
161
-
162
- ```
163
- var widgetContainer = document.querySelector('tb-notification-widget');
164
-
165
- var options = {
166
- widgetId: "YOUR_WIDGET_ID",
167
- element: widgetContainer,
168
- lang: 'ru'
169
- };
170
-
171
- new TextBack.NotificationWidget(options)
172
- ```
173
-
174
- Чтобы изменить существующий перевод, передайте новое значение для нужной переменной в **TextBack.NotificationWidget.locales**:
175
-
176
- ```
177
- <script>TextBack.NotificationWidget.locales.ru.whatsappb = 'Узнать больше'</script>
178
- ```
179
-
180
- Вы можете создать новый перевод для всех элементов виджета (это касается как виджета подписок, так и WhatsApp Hunter):
181
- 1. В личном кабинете установите значение языка по умолчанию, чтобы аттрибут lang не передавался с нашего сервера;
182
- 2. В теге виджета на странице установите аттрибут lang со значением языка (это будет название новой локализации - locales);
183
- 3. Передайте значения для всех переменных в массиве после кода виджета. Для незаданных переменных будет использоваться язык по умолчанию - английский.
184
-
185
- **Важно!** И для виджета подписок, и для WhatsApp Hunter перевод берется из TextBack.NotificationWidget.locales. Если на странице используются оба виджета и обоим нужно задать полную кастомную локализацию в рамках одного locales, значения переменных нужно объявлять в одном массиве. Если объявить переменные по отдельности, то использоваться будет последняя переменная - неполная.
186
-
187
- Если для виджетов заданы разные lang, то объявите переменные для каждого виджета в отдельном массиве.
188
-
189
- **Пример перевода виджета подписок на французский**
190
- ```
191
- <script>
192
- TextBack.NotificationWidget.locales.fr = {
193
- facebook: "Facebook",
194
- facebookExtended: "Abonnez-vous à Facebook",
195
- telegram: "Telegram",
196
- telegramExtended: "Abonnez-vous à Telegram",
197
- viber: "Viber",
198
- viberExtended: "Subscribe to Viber",
199
- vkontakte: "VK",
200
- vkontakteExtended: "Abonnez-vous à Viber",
201
- whatsapp: "WhatsApp",
202
- whatsappExtended: "Abonnez-vous à WhatsApp",
203
- whatsappb: "WhatsApp",
204
- whatsappbExtended: "Abonnez-vous à WhatsApp"
205
- }
206
- </script>
207
- ```
208
-
209
- ### Список всех переменных
210
-
211
- Виджет подписок (пример для английского языка)
212
-
213
- ```
214
- facebook: "Facebook", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
215
- facebookExtended: "Subscribe to Facebook", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
216
- telegram: "Telegram", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
217
- telegramExtended: "Subscribe to Telegram", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
218
- viber: "Viber", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
219
- viberExtended: "Subscribe to Viber", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
220
- vkontakte: "VK", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" и "попап".
221
- vkontakteExtended: "Subscribe to VK", //если выбран лендинг ВК и вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
222
- whatsapp: "WhatsApp", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
223
- whatsappExtended: "Subscribe to WhatsApp", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
224
- whatsappb: "WhatsApp", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
225
- whatsappbExtended: "Subscribe to WhatsApp", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
226
-
227
- //NB: если не использовать лендинг ВК, то при выборе прямоугольных кнопок или попапа используется нативная кнопка, перевод которой пока не реализован
228
- ```
229
- WhatsApp Hunter (пример для английского языка)
230
-
231
- ```
232
- getAnswer: "Get an answer in ", //согласие на получение сообщений
233
- enterNumber: "Enter your phone number", //placeholder в инпуте
234
- sendMessage: "We'll send a message in 3-2-1 sec", //В процессе отправки сообщения
235
- answerSuccessful: "We've answered you in WhatsApp. <br> Check your phone", //После успешной отправки
236
- numberNotFound: "There is no such user in WhatsApp. <br> Are you from Mars?🤔", //Ошибка, формат номера некорректный
237
- tryAgain: "Try another number", //Повтор ввода, если номер не найден
238
- somethingWentWrong: "Oops! Something went wrong", //на 500 при отправке сообщения (например, канал не подключен)
239
- errorTryAgain: "Try again", //Повтор ввода при ошибки 500
240
- ```
241
-
242
- # TextBack Widget SDK
243
- TextBack Widget SDK предоставляет набор функций для управления подпиской.
244
-
245
- SDK входит в состав виджета, но может быть подключен отдельно(см. ниже).
246
-
247
- **Преимущества SDK, в сравнении с виджетом подписок:**
248
- - SDK позволяет полностью настраивать внешний вид вашего UI, предоставляя только функции подписки пользователей.
249
- - Файл с SDK имеет меньший размер, чем файл с виджетом подписок.
250
-
251
- ## Как использовать SDK
252
-
253
- ### Подключение
254
- Добавить в код страницы
255
- ```
256
- <script src="//unpkg.com/@textback/notification-widget@latest/build/sdk.js"></script>
257
- ```
258
-
259
- После этого на странице будет доступен объект ```TextBack.SDK```
260
-
261
- ### Использование
262
- Приведенный ниже код будет подписывать пользователя в Telegram при клике на ссылку с `id="MY_TG_BUTTON"`:
263
-
264
- ```javascript
265
- var config = {
266
- widgetId: 'YOUR_WIDGET_ID'
267
- };
268
-
269
- TextBack.SDK.initWidget(config).then(
270
- function(widget) {
271
- document.getElementById('MY_TG_BUTTON').addEventListener('click', function(event) {
272
- event.preventDefault();
273
- widget.subscribe('tg');
274
- })
275
- }
276
- );
277
- ```
278
- **ВАЖНО!** Элемент с `id="MY_TG_BUTTON"` должен присутствовать на странице во время исполнения скрипта.
279
-
280
- Более подробное описание функции `initWidget()`, состава полей объекта конфигурации и других функций SDK смотрите ниже.
281
-
282
- ## SDK API
283
- **Примечание.** В документации по SDK под "виджетом" подразумевается не "виджет подписок", упоминавшийся ранее, а объект, который содержит настройки и методы виджета. Таким образом "**инициализация виджета**" - это не отрисовка виджета на странице, а **загрузка настроек с сервера и подготовка к работе**.
284
-
285
- Иными словами: "виджет" = "объект в приложении", "виджет подписок" = "объект в JavaScript" + "UI".
286
-
287
- ### Глобальное пространство имен
288
- SDK и виджет подписок доступны как свойства `SDK` и `NotificationWidget` глобального объекта `TextBack` соответственно.
289
-
290
- Для своей работы SDK использует полифиллы для метода `window.fetch()` и объекта ES6 `Promise`.
291
-
292
- Также, для работы с каналами VKontakte, используется VK JS API, представленное глобальным объектом VK.
293
-
294
- ### TextBack.SDK API
295
- Объект `TextBack.SDK` предоставляет API для инициализации виджетов и работы с ними.
296
-
297
- #### Метод `initWidget(config)`
298
- Инициализирует новый виджет по заданному объекту конфигурации.
299
-
300
- **Принимает**
301
- Объект `config` со следующими полями:
302
- - widgetId - (обязательный) идентификатор виджета. Если виджет с таким идентификатором уже есть, то виджет будет перезагружен;
303
- - secureContextToken - строка;
304
- - insecureContext - объект;
305
- - apiPath - адрес сервера;
306
- - overrideConfig - объект с настройками виджета. Если задан, то настройки виджета не будут загружаться с сервера, и для инициализации виджета будет использован данный объект;
307
- - customData - произвольные пользовательские данные.
308
-
309
- **Возвращает** Promise, который будет fulfilled объектом виджета.
310
-
311
- ##### Пример использования
312
- ```javascript
313
- var config = {
314
- widgetId: 'YOUR_WIDGET_ID',
315
- insecureContext: {
316
- data: 'data'
317
- }
318
- };
319
-
320
- TextBack.SDK.initWidget(config).then(
321
- function(widget) {
322
- console.log('Widget has been initialized.');
323
- }
324
- );
325
- ```
326
-
327
-
328
- #### Метод `getWidget(widgetId)`
329
- **Принимает** `widgetId` - идентификатор виджета.
330
- **Возвращает** Promise, возвращаемый функцией `initWidget()`, соответствующий переданному идентификатору.
331
-
332
- ##### Пример использования
333
- ```javascript
334
- TextBack.SDK.getWidget('YOUR_WIDGET_ID').then(
335
- function(widget) {
336
- console.log('Widget has id = ' + widget.id);
337
- }
338
- )
339
-
340
- ```
341
-
342
- #### Метод `on(eventName, callback)`
343
- Вешает обработчик `callback` на событие `eventName`. При наступлении события в `callback` первым аргументом будет передан объект события. Описание полей объекта события для различных событий см. ниже.
344
-
345
- **Поддерживаемые события**
346
- - 'widget.init' - успеная инициализация виджета. поля события:
347
- - widgetId - идентификатор виджета
348
- - 'subscribe.start' - вызвана функция подписки на канал. поля события:
349
- - widgetId - идентификатор виджета
350
- - channel - объект канала, на который осуществляется подписка
351
-
352
-
353
- **Возвращает**
354
- Функцию отписки обработчика `callback` от события.
355
-
356
- ##### Пример использования
357
- При инициализации первого виджета вывести в консоль сообщение.
358
- ```javascript
359
- const config = {
360
- widgetId: 'YOUR_WIDGET_ID'
361
- };
362
-
363
- TextBack.SDK.initWidget(config);
364
- const off = TextBack.SDK.on('widget.init', function(event) {
365
- console.log('First widget with id = ' + event.widgetId + ' has been initilized');
366
- off();
367
- })
368
-
369
- ```
370
-
371
- #### Метод `deeplinkUpdater(String)`
372
- #### deeplinkUpdater :: String -> Promise -> Function
373
-
374
- Ф-ция getDeeplinkUpdater() принимает идентефикатор виджета и возвращает Promise, содержащий ф-цию, позволяющую обновлять данные в insecureContext с помощью PATCH запроса.
375
-
376
- ##### Пример использования
377
-
378
- Данный пример отправит в insecureContext данные на событие подписки.
379
- ```javascript
380
- TextBack.SDK.getDeeplinkUpdater('myWidgetId').then(f => {
381
- let data = {
382
- foo: 'foo',
383
- bar: 'bar'
384
- };
385
-
386
- TextBack.SDK.on('subscribe.start', () => f(data));
387
- });
388
- ```
389
-
390
- ### Widget API
391
- Объект Widget предоставляет функции для работы с конкретным виджетом.
392
-
393
- #### Метод `subscribe(channelType)`
394
- Инициализирует подписку пользователя на канал.
395
-
396
- **Принимает** channelType - тип канала, на который следует осуществить подписку. Поддерживаются следующие коды каналов:
397
- - `'facebook'` - Facebook
398
- - `'tg'` - Telegram
399
- - `'viber'` - Viber
400
- - `'vk'` - Vkontakte
401
- - `'whatsapp'` - WhatsApp
402
- - `'whatsappb'` - WhatsApp Business API
403
- - `'skype'` - Skype
404
-
405
-
406
-
407
- **Внимание!**
408
- - Мы **настоятельно рекомендуем** вызывать эту функцию непосредственно из обработчика клика на кнопку/ссылку, во избежание блокирования функции браузером.
409
-
410
- ##### Пример использования
411
- ```javascript
412
- var config = {
413
- widgetId: 'YOUR_WIDGET_ID'
414
- };
415
-
416
- TextBack.SDK.initWidget(config).then(
417
- function(widget) {
418
- document.getElementById('MY_TG_BUTTON').addEventListener('click', function(event) {
419
- event.preventDefault();
420
- widget.subscribe('tg');
421
- });
422
-
423
- document.getElementById('MY_VK_BUTTON').addEventListener('click', function(event) {
424
- event.preventDefault();
425
- widget.subscribe('vk');
426
- })
427
- }
428
- );
429
- ```
430
-
431
-
432
- #### Метод `getConfig()`
433
- **Возвращает** загруженный с сервера объект конфигурации виджета
434
-
435
-
436
- #### Метод `getChannels()`
437
- **Возвращает** объекты каналов виджета(см. `Channel` ниже)
438
-
439
-
440
- #### Метод `getEnabledChannels()`
441
- **Возвращает** объекты каналов виджета, которые сейчас активны и инициализированны без ошибок.
442
-
443
- ##### Пример использования
444
- ```javascript
445
- var config = {
446
- widgetId: 'YOUR_WIDGET_ID'
447
- };
448
-
449
- TextBack.SDK.initWidget(config).then(
450
- function(widget) {
451
- console.log('Total channels: ' + widget.getChannels().length);
452
- console.log('Enabled channels: ' + widget.getEnabledChannels().length);
453
- }
454
- );
455
- ```
456
-
457
- ### Channel API
458
- Объекты `Channel` предоставляют API конкретных каналов в виджете. Каждый канал реализует свою собственную функцию подписки пользователя.
459
-
460
- #### Свойство `hasError`
461
- Устанавливается в значение `true`, если при инициализации канала произошла ошибка (например, если не удалось загрузить внешнюю библиотеку для канала VKontakte). Информация об ошибке будет выведена в консоль.
462
-
463
- Каналы, для которых `hasError == true` не вовзращаются при вызове метода `getEnabledChannels()` у объекта виджета.
464
-
465
- #### Метод `subscribe()`
466
- Инициализирует процесс подписки пользователя на канал.
467
-
468
- ##### Пример использования
469
- ```javascript
470
- var config = {
471
- widgetId: 'YOUR_WIDGET_ID'
472
- };
473
-
474
- TextBack.SDK.initWidget(config).then(
475
- function(widget) {
476
- document.getElementById('MY_BUTTON').addEventListener('click', function(event) {
477
- event.preventDefault();
478
- const channels = widget.getEnabledChannels();
479
- if (channels.length > 0) {
480
- channels[0].subscribe();
481
- console.log('User has been subscribed on ' + channels[0].channel + ' channel');
482
- } else {
483
- console.log('No channels available for subscription');
484
- }
485
- });
486
- }
487
- );
488
- ```
489
-
490
-
491
- ## Пример
492
- Страница с двумя ссылками, подписывающими в Telegram и Vkontakte.
493
- ```html
494
- <!DOCTYPE html>
495
- <html>
496
- <head>
497
- <meta charset="UTF-8">
498
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
499
- <title>TextBack SDK Example</title>
500
- </head>
501
- <body>
502
- <h1>TextBack SDK</h1>
503
- <a href="" id="sign_tg">Telegram</a>
504
- <a href="" id="sign_vk">Vkontakte</a>
505
-
506
- <script src="//unpkg.com/@textback/notification-widget@latest/build/sdk.js"></script>
507
-
508
- <script type="text/javascript">
509
- var config = {
510
- widgetId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
511
- };
512
-
513
- var off = TextBack.SDK.on('widget.init', function(event) {
514
- console.log('First widget has been initialized. ' + event.widgetId);
515
- off();
516
- });
517
-
518
- TextBack.SDK.initWidget(config).then(function(widget) {
519
- document.getElementById('sign_tg').addEventListener('click', function(event) {
520
- event.preventDefault();
521
- widget.subscribe('tg');
522
- });
523
-
524
- document.getElementById('sign_vk').addEventListener('click', function(event) {
525
- event.preventDefault();
526
- widget.subscribe('vk');
527
- });
528
- });
529
- </script>
530
- </body>
531
- </html>
532
- ```
533
-
534
-
535
- # Разработка
536
-
537
- В терминале перейдите в директорию исходного кода виджета и выполните команды:
538
-
539
- ```
540
- npm run dev
541
- PORT=8080 npm start
542
- ```
543
-
544
- После этого тестовый стенд будет доступен локально по адресу http://localhost:8080/examples
545
-
546
- Если переменная PORT не указана, по умолчанию будет использован порт 3000
547
-
548
- После любых изменений кода обновите страницу браузера
549
-
550
- Для проверки codestyle выполните
551
-
552
- ```
553
- npm run test:lint
554
- ```
555
-
556
- # Тестирование
557
-
558
- Для запуска тестов выполните
559
-
560
- ```
561
- npm run build
562
- npm run test:all
563
- ```
564
-
565
- Тесты будут запущенны во всех браузерах, установленных на локальной машине.
566
-
567
- Тестирование осуществляется с помощью https://github.com/DevExpress/testcafe
568
-
569
- Все тесты запускаются из директории `./tests`
1
+ # Установка виджета на сайт
2
+
3
+ Для установки виджета подписки на сайт, сначала добавьте к вашей странице:
4
+
5
+ ```
6
+ <script src="//cdn.jsdelivr.net/npm/@textback/notification-widget@latest/build/index.js"></script>
7
+ ```
8
+ **Внимание** Виджет больше не требует подключения дополнительного скрипта с полифиллом.
9
+
10
+ Для корректного отображение виджета на адаптивных сайтах на мобильных требуется добавить следующий мета-тег в секцию `<head>`:
11
+ ```html
12
+ <meta name="viewport" content="width=device-width, initial-scale=1.0>
13
+ ```
14
+
15
+ Затем вы можете вставить один или несколько виджетов:
16
+
17
+ ```
18
+ <tb-notification-widget widget-id="YOUR_WIDGET_ID"></tb-notification-widget>
19
+ ```
20
+
21
+ с необходимыми widget-id. YOUR_WIDGET_ID указан в консоли администратора Textback.
22
+
23
+ Если вы планируете использовать виджет в режиме "попап", то встраивайте виджет непосредственно внутри тега body, лучше сразу перед `</body>` шаблона страницы, на которую добавляется виджет.
24
+
25
+ Если виджет будет использоваться в режиме "инлайн", то добавте виджет в том месте шаблона, в котором он должен отобразиться.
26
+
27
+ Дополнительные параметры можно передать через data-атрибуты:
28
+
29
+ ```
30
+ <tb-notification-widget
31
+ widget-id="YOUR_WIDGET_ID"
32
+ data-user-id="USER_ID"
33
+ data-order-id="ORDER_ID">
34
+ </tb-notification-widget>
35
+ ```
36
+
37
+ Чтобы передать secureContext, нужно использовать атрибут `secure-context-token`:
38
+ ```html
39
+ <tb-notification-widget
40
+ widget-id="YOUR_WIDGET_ID"
41
+ secure-context-token="YOUR_TOKEN"
42
+ </tb-notification-widget>
43
+ ```
44
+
45
+ ## Динамическая инициализация виджета
46
+
47
+ Если вам необходимо динамически проинициализировать виджет, например во всплывающем окне или при разработке Single Page Application
48
+ вы можете использовать класс, который доступен стразу после загрузки скрипта виджета
49
+
50
+ ```
51
+ var widgetContainer = document.querySelector('tb-notification-widget');
52
+
53
+ var options = {
54
+ widgetId: "YOUR_WIDGET_ID",
55
+ element: widgetContainer,
56
+ data: {userId: "USER_ID", orderId: "ORDER_ID"}
57
+ };
58
+
59
+ new TextBack.NotificationWidget(options)
60
+ ```
61
+
62
+ где widgetContainer - корневой HTML элемент, в котором необходимо отобразить виджет, data - дополнительные параметры.
63
+
64
+ Чтобы изменить параметры после инициализации виджета повторно проинициализируйте виджет на элементе с новыми параметрами:
65
+
66
+ ```
67
+ options.data.orderId = "NEW_ORDER_ID";
68
+
69
+ new TextBack.NotificationWidget(options)
70
+ ```
71
+
72
+ ### Мгновенно отобразить popup-виджет
73
+ По умолчанию при инициализации виджета используются параметры тайминга из настроек - через сколько секунд отобразить виджет, сколько раз за сессию и т.д.
74
+
75
+ Если требуется отобразить виджет сразу, то можно воспользоваться разработанным для этого API.
76
+
77
+ Сначала нужно добавить виджет на страницу, указав атрибут ```only-manual```
78
+ ```html
79
+ <tb-notification-widget widget-id="YOUR_WIDGET_ID" only-manual></tb-notification-widget>
80
+ ```
81
+ Добавленный таким образом виджет будет скрыт и не будет показан автоматически.
82
+
83
+ Чтобы теперь отобразить виджет, нужно выполнить следующий код:
84
+ ```javascript
85
+ TextBack.NotificationWidget.getWidget('YOUR_WIDGET_ID').then(function(widget) {
86
+ widget.show();
87
+ });
88
+ ```
89
+
90
+ Пример отображения виджета при нажатии на кнопку:
91
+ ```javascript
92
+ document.querySelector('#YOUR_BUTTON_ID').addEventListener('click', function() {
93
+ TextBack.NotificationWidget.getWidget('YOUR_WIDGET_ID').then(function(widget) {
94
+ widget.show();
95
+ });
96
+ });
97
+ ```
98
+
99
+ ### Предпросмотр виджета
100
+ Релизован механизм, позволяющий задать JSON виджета динамически, не
101
+ подгружая его по ID с нашего **API**. Для того, чтобы подписки работали
102
+ в предпросомтре, необходимо, чтобы виджет был сохранен в БАЗУ
103
+ и имел присвоенный ID.
104
+
105
+ ---
106
+ Этот механизм внедрян для добавления функционала пред-просмотра виджета
107
+ в нашем редакторе, но ижет быть использован сторонними разработчикми,
108
+ для динамической генерации сообщения приветствия, однака надо
109
+ иметь в виду, что **ЭТО апи не финальное, и может изменится в любой момент**,
110
+ используйте на свой страх и риск.
111
+
112
+ ---
113
+
114
+ Использование:
115
+
116
+ ```javascript
117
+ //получаем копию настроек виджета
118
+ var data = angular.copy(notificationWidgetJSON);
119
+
120
+
121
+ //override settings for preview purpose
122
+ //переопределяем некторыесвойства, сохраненные на сервере
123
+ //отображатся в виджете будет нвое значение.
124
+ data.displayOptions.onLeave = null;
125
+ data.displayOptions.timeoutDelay = 0;
126
+ data.displayOptions.onTimeout = "yes";
127
+
128
+ //к примеру vkApiId привязан к домену, на котром отображается виджет
129
+ data.vkApiId=TextBack.configuration.get('vkAppId');
130
+
131
+
132
+
133
+ //динамически создаем контейнер для виджета
134
+ var widgetContainerJq = $('<div></div>');
135
+ $('body').append(widgetContainerJq);
136
+
137
+ var widgetContainer = widgetContainerJq[0];
138
+
139
+
140
+ var options = {
141
+ apiPath: 'https://api.textback.io/api', //необязатльный параметр
142
+ element: widgetContainer,
143
+ widgetConfig: data
144
+ };
145
+
146
+ new TextBack.NotificationWidget(options)
147
+ ```
148
+
149
+ # Локализация
150
+
151
+ Все поддерживаемые языки находятся в переменной `TextBack.NotificationWidget.locales`. Перевод затрагивает только статичные элементы виджета, значения которых не задаются в настройках виджета.
152
+
153
+ Чтобы применить нужный язык к виджету, передайте соответсвующий параметр `lang` в тег виджета:
154
+
155
+ ```
156
+ <tb-notification-widget widget-id="YOUR_WIDGET_ID" lang="ru">
157
+ </tb-notification-widget>
158
+ ```
159
+
160
+ или
161
+
162
+ ```
163
+ var widgetContainer = document.querySelector('tb-notification-widget');
164
+
165
+ var options = {
166
+ widgetId: "YOUR_WIDGET_ID",
167
+ element: widgetContainer,
168
+ lang: 'ru'
169
+ };
170
+
171
+ new TextBack.NotificationWidget(options)
172
+ ```
173
+
174
+ Чтобы изменить существующий перевод, передайте новое значение для нужной переменной в **TextBack.NotificationWidget.locales**:
175
+
176
+ ```
177
+ <script>TextBack.NotificationWidget.locales.ru.whatsappb = 'Узнать больше'</script>
178
+ ```
179
+
180
+ Вы можете создать новый перевод для всех элементов виджета (это касается как виджета подписок, так и WhatsApp Hunter):
181
+ 1. В личном кабинете установите значение языка по умолчанию, чтобы аттрибут lang не передавался с нашего сервера;
182
+ 2. В теге виджета на странице установите аттрибут lang со значением языка (это будет название новой локализации - locales);
183
+ 3. Передайте значения для всех переменных в массиве после кода виджета. Для незаданных переменных будет использоваться язык по умолчанию - английский.
184
+
185
+ **Важно!** И для виджета подписок, и для WhatsApp Hunter перевод берется из TextBack.NotificationWidget.locales. Если на странице используются оба виджета и обоим нужно задать полную кастомную локализацию в рамках одного locales, значения переменных нужно объявлять в одном массиве. Если объявить переменные по отдельности, то использоваться будет последняя переменная - неполная.
186
+
187
+ Если для виджетов заданы разные lang, то объявите переменные для каждого виджета в отдельном массиве.
188
+
189
+ **Пример перевода виджета подписок на французский**
190
+ ```
191
+ <script>
192
+ TextBack.NotificationWidget.locales.fr = {
193
+ facebook: "Facebook",
194
+ facebookExtended: "Abonnez-vous à Facebook",
195
+ telegram: "Telegram",
196
+ telegramExtended: "Abonnez-vous à Telegram",
197
+ viber: "Viber",
198
+ viberExtended: "Subscribe to Viber",
199
+ vkontakte: "VK",
200
+ vkontakteExtended: "Abonnez-vous à Viber",
201
+ whatsapp: "WhatsApp",
202
+ whatsappExtended: "Abonnez-vous à WhatsApp",
203
+ whatsappb: "WhatsApp",
204
+ whatsappbExtended: "Abonnez-vous à WhatsApp"
205
+ }
206
+ </script>
207
+ ```
208
+
209
+ ### Список всех переменных
210
+
211
+ Виджет подписок (пример для английского языка)
212
+
213
+ ```
214
+ facebook: "Facebook", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
215
+ facebookExtended: "Subscribe to Facebook", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
216
+ telegram: "Telegram", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
217
+ telegramExtended: "Subscribe to Telegram", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
218
+ viber: "Viber", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
219
+ viberExtended: "Subscribe to Viber", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
220
+ vkontakte: "VK", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" и "попап".
221
+ vkontakteExtended: "Subscribe to VK", //если выбран лендинг ВК и вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
222
+ whatsapp: "WhatsApp", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
223
+ whatsappExtended: "Subscribe to WhatsApp", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
224
+ whatsappb: "WhatsApp", //для всех кнопок, кроме варианта показа "Прямоугольные кнопки" или "Всплывающее окно"
225
+ whatsappbExtended: "Subscribe to WhatsApp", //если выбран вариант показа "Прямоугольные кнопки" или "Всплывающее окно"
226
+
227
+ //NB: если не использовать лендинг ВК, то при выборе прямоугольных кнопок или попапа используется нативная кнопка, перевод которой пока не реализован
228
+ ```
229
+ WhatsApp Hunter (пример для английского языка)
230
+
231
+ ```
232
+ getAnswer: "Get an answer in ", //согласие на получение сообщений
233
+ enterNumber: "Enter your phone number", //placeholder в инпуте
234
+ sendMessage: "We'll send a message in 3-2-1 sec", //В процессе отправки сообщения
235
+ answerSuccessful: "We've answered you in WhatsApp. <br> Check your phone", //После успешной отправки
236
+ numberNotFound: "There is no such user in WhatsApp. <br> Are you from Mars?🤔", //Ошибка, формат номера некорректный
237
+ tryAgain: "Try another number", //Повтор ввода, если номер не найден
238
+ somethingWentWrong: "Oops! Something went wrong", //на 500 при отправке сообщения (например, канал не подключен)
239
+ errorTryAgain: "Try again", //Повтор ввода при ошибки 500
240
+ ```
241
+
242
+ # TextBack Widget SDK
243
+ TextBack Widget SDK предоставляет набор функций для управления подпиской.
244
+
245
+ SDK входит в состав виджета, но может быть подключен отдельно(см. ниже).
246
+
247
+ **Преимущества SDK, в сравнении с виджетом подписок:**
248
+ - SDK позволяет полностью настраивать внешний вид вашего UI, предоставляя только функции подписки пользователей.
249
+ - Файл с SDK имеет меньший размер, чем файл с виджетом подписок.
250
+
251
+ ## Как использовать SDK
252
+
253
+ ### Подключение
254
+ Добавить в код страницы
255
+ ```
256
+ <script src="//cdn.jsdelivr.net/npm/@textback/notification-widget@latest/build/sdk.js"></script>
257
+ ```
258
+
259
+ После этого на странице будет доступен объект ```TextBack.SDK```
260
+
261
+ ### Использование
262
+ Приведенный ниже код будет подписывать пользователя в Telegram при клике на ссылку с `id="MY_TG_BUTTON"`:
263
+
264
+ ```javascript
265
+ var config = {
266
+ widgetId: 'YOUR_WIDGET_ID'
267
+ };
268
+
269
+ TextBack.SDK.initWidget(config).then(
270
+ function(widget) {
271
+ document.getElementById('MY_TG_BUTTON').addEventListener('click', function(event) {
272
+ event.preventDefault();
273
+ widget.subscribe('tg');
274
+ })
275
+ }
276
+ );
277
+ ```
278
+ **ВАЖНО!** Элемент с `id="MY_TG_BUTTON"` должен присутствовать на странице во время исполнения скрипта.
279
+
280
+ Более подробное описание функции `initWidget()`, состава полей объекта конфигурации и других функций SDK смотрите ниже.
281
+
282
+ ## SDK API
283
+ **Примечание.** В документации по SDK под "виджетом" подразумевается не "виджет подписок", упоминавшийся ранее, а объект, который содержит настройки и методы виджета. Таким образом "**инициализация виджета**" - это не отрисовка виджета на странице, а **загрузка настроек с сервера и подготовка к работе**.
284
+
285
+ Иными словами: "виджет" = "объект в приложении", "виджет подписок" = "объект в JavaScript" + "UI".
286
+
287
+ ### Глобальное пространство имен
288
+ SDK и виджет подписок доступны как свойства `SDK` и `NotificationWidget` глобального объекта `TextBack` соответственно.
289
+
290
+ Для своей работы SDK использует полифиллы для метода `window.fetch()` и объекта ES6 `Promise`.
291
+
292
+ Также, для работы с каналами VKontakte, используется VK JS API, представленное глобальным объектом VK.
293
+
294
+ ### TextBack.SDK API
295
+ Объект `TextBack.SDK` предоставляет API для инициализации виджетов и работы с ними.
296
+
297
+ #### Метод `initWidget(config)`
298
+ Инициализирует новый виджет по заданному объекту конфигурации.
299
+
300
+ **Принимает**
301
+ Объект `config` со следующими полями:
302
+ - widgetId - (обязательный) идентификатор виджета. Если виджет с таким идентификатором уже есть, то виджет будет перезагружен;
303
+ - secureContextToken - строка;
304
+ - insecureContext - объект;
305
+ - apiPath - адрес сервера;
306
+ - overrideConfig - объект с настройками виджета. Если задан, то настройки виджета не будут загружаться с сервера, и для инициализации виджета будет использован данный объект;
307
+ - customData - произвольные пользовательские данные.
308
+
309
+ **Возвращает** Promise, который будет fulfilled объектом виджета.
310
+
311
+ ##### Пример использования
312
+ ```javascript
313
+ var config = {
314
+ widgetId: 'YOUR_WIDGET_ID',
315
+ insecureContext: {
316
+ data: 'data'
317
+ }
318
+ };
319
+
320
+ TextBack.SDK.initWidget(config).then(
321
+ function(widget) {
322
+ console.log('Widget has been initialized.');
323
+ }
324
+ );
325
+ ```
326
+
327
+
328
+ #### Метод `getWidget(widgetId)`
329
+ **Принимает** `widgetId` - идентификатор виджета.
330
+ **Возвращает** Promise, возвращаемый функцией `initWidget()`, соответствующий переданному идентификатору.
331
+
332
+ ##### Пример использования
333
+ ```javascript
334
+ TextBack.SDK.getWidget('YOUR_WIDGET_ID').then(
335
+ function(widget) {
336
+ console.log('Widget has id = ' + widget.id);
337
+ }
338
+ )
339
+
340
+ ```
341
+
342
+ #### Метод `on(eventName, callback)`
343
+ Вешает обработчик `callback` на событие `eventName`. При наступлении события в `callback` первым аргументом будет передан объект события. Описание полей объекта события для различных событий см. ниже.
344
+
345
+ **Поддерживаемые события**
346
+ - 'widget.init' - успеная инициализация виджета. поля события:
347
+ - widgetId - идентификатор виджета
348
+ - 'subscribe.start' - вызвана функция подписки на канал. поля события:
349
+ - widgetId - идентификатор виджета
350
+ - channel - объект канала, на который осуществляется подписка
351
+
352
+
353
+ **Возвращает**
354
+ Функцию отписки обработчика `callback` от события.
355
+
356
+ ##### Пример использования
357
+ При инициализации первого виджета вывести в консоль сообщение.
358
+ ```javascript
359
+ const config = {
360
+ widgetId: 'YOUR_WIDGET_ID'
361
+ };
362
+
363
+ TextBack.SDK.initWidget(config);
364
+ const off = TextBack.SDK.on('widget.init', function(event) {
365
+ console.log('First widget with id = ' + event.widgetId + ' has been initilized');
366
+ off();
367
+ })
368
+
369
+ ```
370
+
371
+ #### Метод `deeplinkUpdater(String)`
372
+ #### deeplinkUpdater :: String -> Promise -> Function
373
+
374
+ Ф-ция getDeeplinkUpdater() принимает идентефикатор виджета и возвращает Promise, содержащий ф-цию, позволяющую обновлять данные в insecureContext с помощью PATCH запроса.
375
+
376
+ ##### Пример использования
377
+
378
+ Данный пример отправит в insecureContext данные на событие подписки.
379
+ ```javascript
380
+ TextBack.SDK.getDeeplinkUpdater('myWidgetId').then(f => {
381
+ let data = {
382
+ foo: 'foo',
383
+ bar: 'bar'
384
+ };
385
+
386
+ TextBack.SDK.on('subscribe.start', () => f(data));
387
+ });
388
+ ```
389
+
390
+ ### Widget API
391
+ Объект Widget предоставляет функции для работы с конкретным виджетом.
392
+
393
+ #### Метод `subscribe(channelType)`
394
+ Инициализирует подписку пользователя на канал.
395
+
396
+ **Принимает** channelType - тип канала, на который следует осуществить подписку. Поддерживаются следующие коды каналов:
397
+ - `'facebook'` - Facebook
398
+ - `'tg'` - Telegram
399
+ - `'viber'` - Viber
400
+ - `'vk'` - Vkontakte
401
+ - `'whatsapp'` - WhatsApp
402
+ - `'whatsappb'` - WhatsApp Business API
403
+ - `'skype'` - Skype
404
+
405
+
406
+
407
+ **Внимание!**
408
+ - Мы **настоятельно рекомендуем** вызывать эту функцию непосредственно из обработчика клика на кнопку/ссылку, во избежание блокирования функции браузером.
409
+
410
+ ##### Пример использования
411
+ ```javascript
412
+ var config = {
413
+ widgetId: 'YOUR_WIDGET_ID'
414
+ };
415
+
416
+ TextBack.SDK.initWidget(config).then(
417
+ function(widget) {
418
+ document.getElementById('MY_TG_BUTTON').addEventListener('click', function(event) {
419
+ event.preventDefault();
420
+ widget.subscribe('tg');
421
+ });
422
+
423
+ document.getElementById('MY_VK_BUTTON').addEventListener('click', function(event) {
424
+ event.preventDefault();
425
+ widget.subscribe('vk');
426
+ })
427
+ }
428
+ );
429
+ ```
430
+
431
+
432
+ #### Метод `getConfig()`
433
+ **Возвращает** загруженный с сервера объект конфигурации виджета
434
+
435
+
436
+ #### Метод `getChannels()`
437
+ **Возвращает** объекты каналов виджета(см. `Channel` ниже)
438
+
439
+
440
+ #### Метод `getEnabledChannels()`
441
+ **Возвращает** объекты каналов виджета, которые сейчас активны и инициализированны без ошибок.
442
+
443
+ ##### Пример использования
444
+ ```javascript
445
+ var config = {
446
+ widgetId: 'YOUR_WIDGET_ID'
447
+ };
448
+
449
+ TextBack.SDK.initWidget(config).then(
450
+ function(widget) {
451
+ console.log('Total channels: ' + widget.getChannels().length);
452
+ console.log('Enabled channels: ' + widget.getEnabledChannels().length);
453
+ }
454
+ );
455
+ ```
456
+
457
+ ### Channel API
458
+ Объекты `Channel` предоставляют API конкретных каналов в виджете. Каждый канал реализует свою собственную функцию подписки пользователя.
459
+
460
+ #### Свойство `hasError`
461
+ Устанавливается в значение `true`, если при инициализации канала произошла ошибка (например, если не удалось загрузить внешнюю библиотеку для канала VKontakte). Информация об ошибке будет выведена в консоль.
462
+
463
+ Каналы, для которых `hasError == true` не вовзращаются при вызове метода `getEnabledChannels()` у объекта виджета.
464
+
465
+ #### Метод `subscribe()`
466
+ Инициализирует процесс подписки пользователя на канал.
467
+
468
+ ##### Пример использования
469
+ ```javascript
470
+ var config = {
471
+ widgetId: 'YOUR_WIDGET_ID'
472
+ };
473
+
474
+ TextBack.SDK.initWidget(config).then(
475
+ function(widget) {
476
+ document.getElementById('MY_BUTTON').addEventListener('click', function(event) {
477
+ event.preventDefault();
478
+ const channels = widget.getEnabledChannels();
479
+ if (channels.length > 0) {
480
+ channels[0].subscribe();
481
+ console.log('User has been subscribed on ' + channels[0].channel + ' channel');
482
+ } else {
483
+ console.log('No channels available for subscription');
484
+ }
485
+ });
486
+ }
487
+ );
488
+ ```
489
+
490
+
491
+ ## Пример
492
+ Страница с двумя ссылками, подписывающими в Telegram и Vkontakte.
493
+ ```html
494
+ <!DOCTYPE html>
495
+ <html>
496
+ <head>
497
+ <meta charset="UTF-8">
498
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
499
+ <title>TextBack SDK Example</title>
500
+ </head>
501
+ <body>
502
+ <h1>TextBack SDK</h1>
503
+ <a href="" id="sign_tg">Telegram</a>
504
+ <a href="" id="sign_vk">Vkontakte</a>
505
+
506
+ <script src="//cdn.jsdelivr.net/npm/@textback/notification-widget@latest/build/sdk.js"></script>
507
+
508
+ <script type="text/javascript">
509
+ var config = {
510
+ widgetId: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
511
+ };
512
+
513
+ var off = TextBack.SDK.on('widget.init', function(event) {
514
+ console.log('First widget has been initialized. ' + event.widgetId);
515
+ off();
516
+ });
517
+
518
+ TextBack.SDK.initWidget(config).then(function(widget) {
519
+ document.getElementById('sign_tg').addEventListener('click', function(event) {
520
+ event.preventDefault();
521
+ widget.subscribe('tg');
522
+ });
523
+
524
+ document.getElementById('sign_vk').addEventListener('click', function(event) {
525
+ event.preventDefault();
526
+ widget.subscribe('vk');
527
+ });
528
+ });
529
+ </script>
530
+ </body>
531
+ </html>
532
+ ```
533
+
534
+
535
+ # Разработка
536
+
537
+ В терминале перейдите в директорию исходного кода виджета и выполните команды:
538
+
539
+ ```
540
+ npm run dev
541
+ PORT=8080 npm start
542
+ ```
543
+
544
+ После этого тестовый стенд будет доступен локально по адресу http://localhost:8080/examples
545
+
546
+ Если переменная PORT не указана, по умолчанию будет использован порт 3000
547
+
548
+ После любых изменений кода обновите страницу браузера
549
+
550
+ Для проверки codestyle выполните
551
+
552
+ ```
553
+ npm run test:lint
554
+ ```
555
+
556
+ # Тестирование
557
+
558
+ Для запуска тестов выполните
559
+
560
+ ```
561
+ npm run build
562
+ npm run test:all
563
+ ```
564
+
565
+ Тесты будут запущенны во всех браузерах, установленных на локальной машине.
566
+
567
+ Тестирование осуществляется с помощью https://github.com/DevExpress/testcafe
568
+
569
+ Все тесты запускаются из директории `./tests`