@textback/notification-widget 2.0.1-84986 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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`