PageSourceSearch

https://www.mikopbx.ru/bitrix/js/miko.calltracking/calltacking.client.js?178530194816298

js mikopbx.ru collected 2026-10-02 14:37:04 UTC 16,298 bytes, 316 lines download raw bytes

1// Инициализация библиотеки
2BX.ready(function() {
3
4    BX.namespace("MikoCallTracking");
5
6    MikoCallTracking={
7
8        debugMode: false,
9        poolTimeout: '',
10        poolStarted: false,
11        replaceClassName: '',
12        defaultNumber: '',
13        resetToDefaultTimeout: '',
14        mainDomain: '',
15        apiUrl: '',
16        previousVisitorId: '',
17        currentVisitorId: '',
18        lastGoalLinkedid: '',
19
20        // Информация о посетителе
21        visitorData: function(){
22
23            // Получаем идентификатор клиента Google (куки _ga может не быть, если Google-тег убран)
24            var gaCookie = BX.getCookie('_ga') || '';
25            var match = gaCookie.match(/(\d+\.\d+)$/);
26            var gacid = (match) ? match[1] : '';
27
28            var yacid = BX.getCookie('_ym_uid');
29            var lastVisitor ='';
30            if (parseInt(MikoCallTracking.previousVisitorId)>0
31                && MikoCallTracking.previousVisitorId!=MikoCallTracking.currentVisitorId){
32                lastVisitor = MikoCallTracking.previousVisitorId;
33            }
34
35            var result={
36                TRAFFIC_TYPE:    sbjs.get.current.typ, // тип трафика // возможные значения: `utm`, `organic`, `referral`, `typein`
37                UTM_SOURCE:      sbjs.get.current.src, // источник (utm_source)
38                UTM_MEDIUM:      sbjs.get.current.mdm, // канал (utm_medium)
39                UTM_CAMPAIGN:    sbjs.get.current.cmp, // кампания (utm_campaign)
40                UTM_CONTENT:     sbjs.get.current.cnt, // контент (utm_content)
41                UTM_TERM:        sbjs.get.current.trm, // ключевое слово (utm_term)
42                SOURCE:          sbjs.get.current_add.ep, // точка входа
43                REFERRER:        sbjs.get.current_add.rf, // реферер
44                FIRST_SOURCE:    sbjs.get.first_add.ep, // первая точка входа
45                FIRST_REFERRER:  sbjs.get.first_add.rf, // первая точка входа
46                FIRST_VISIT:     sbjs.get.first_add.fd, // дата первого посещения
47                GOOGLE_CID:      gacid,
48                YANDEX_CID:      yacid,
49                HOST:            window.location.hostname,
50                PREVIOUS_VISITOR_ID: lastVisitor,
51
52            }
53            return result;
54        },
55
56        // Инициализация коллтрекинга
57        init: function (params){
58
59            MikoCallTracking.debugMode=params.debugMode;
60            MikoCallTracking.poolTimeout=params.poolTimeout;
61            MikoCallTracking.replaceClassName=params.replaceClassName;
62            MikoCallTracking.resetToDefaultTimeout=params.resetToDefaultTimeout;
63            MikoCallTracking.mainDomain=params.mainDomain;
64            MikoCallTracking.apiUrl=params.apiUrl;
65
66            MikoCallTracking.previousVisitorId = BX.getCookie('_miko_visitor_id');
67
68            // Запустим библиотеку отслеживания переходов посетителей
69            var sbjs_param={};
70            sbjs_param.callback = MikoCallTracking.RegisterNewVisitor;
71            sbjs_param.domain = MikoCallTracking.mainDomain;
72            sbjs_param.referrals= [
73                {
74                    host: 't.co',            // Это хост Twitter'а из `http referer`
75                    medium: 'social',        // Это настраиваемый `utm_medium`, если не указать - будет `referral`
76                    display: 'twitter.com'   // Так оно сохранится в куку
77                },
78                {
79                    host: 'plus.url.google.com',
80                    medium: 'social',
81                    display: 'plus.google.com'
82                },
83                {
84                    host: 'facebook.com',
85                    medium: 'social',
86                    display: 'facebook.com'
87                }
88            ];
89            sbjs.init(sbjs_param);
90
91            // Освободим номер при закрытии страницы
92            //
93            $(window).bind("beforeunload", function() {
94                BX.ajax.post(
95                    MikoCallTracking.apiUrl+'?action=freenumber',
96                    {'userData':
97                        {
98                            'visitorId': MikoCallTracking.currentVisitorId
99                        }
100                    }
101                );
102            });
103
104        },
105
106        // Заменяет все номера на странице на переданный в параметр
107        // newNum номер в формате подстановки
108        replaceNumbers: function (newNum)	{
109            var nodes = BX.findChildrenByClassName(BX(document.body), MikoCallTracking.replaceClassName);
110            nodes.forEach(function(element){
111                if (MikoCallTracking.defaultNumber.length==0 ) {
112                    MikoCallTracking.defaultNumber = element.text;
113                    if (MikoCallTracking.debugMode)  console.log("МИКО: Коллтрекинг","Исходный перед подменой", MikoCallTracking.defaultNumber);
114                }
115                BX.adjust(element,
116                    {
117                        "text": newNum,
118                        "props":{ "href":"tel:"+newNum}
119                    })
120            })
121        },
122
123
124        RegisterNewVisitor: function(sb){
125
126            var visitorData = MikoCallTracking.visitorData();
127
128            BX.ajax.post(
129                MikoCallTracking.apiUrl+'?action=registerVisitor',
130                {
131                    'userData': visitorData,
132                },
133                function (response) { // получаем id посетителя, и сохраняем в куку на пол года
134
135                    if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Ответ сервера на регистрацию посетителя',response);
136
137                    if (/{*}/.test(response)) {
138                        var result = JSON.parse(response);
139
140                        if (result.visitorId) {
141
142                            MikoCallTracking.currentVisitorId= result.visitorId;
143
144                            // Проверим есть ли на странице телефоны для подмены, если их нет, то не будем запускать ничего
145                            //
146                            if (BX.findChildrenByClassName(BX(document.body), MikoCallTracking.replaceClassName,false).length>0)
147                            {
148                                MikoCallTracking.StartCallTracking();
149                            } else {
150                                if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг','На странице нет элементов с телефоном или не установлен класс', MikoCallTracking.replaceClassName);
151                            }
152
153                            BX.setCookie('_miko_visitor_id',result.visitorId, { expires: 86400*180});
154
155                            // Обновим данные сессии с небольшим таймаутом, есть проблема с загрузкой асинхронных скриптов
156                            //
157                            setTimeout(function() {
158                                MikoCallTracking.updateAnalyticsInfo();
159                            }, 8000);
160
161                            // Запустим отслеживание 60 секундной конверсии через 10 секунд после входа на страницу
162                            //
163                            MikoCallTracking.track60secconversion();
164                            // setTimeout(function() {
165                            //
166                            // }, 10000);
167
168                        }
169                    }
170                }
171            )
172        },
173
174
175
176        // Запросим новый номер на для подмены на текущей странице
177        //
178        StartCallTracking: function(){
179
180            BX.ajax.post(
181                MikoCallTracking.apiUrl+'?action=getNewNumber',
182                {
183                    'visitorId': MikoCallTracking.currentVisitorId
184                },
185                function (response) { // получаем номер для подмены
186                    if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Ответ сервера на запрос номера',response);
187                    if (/{*}/.test(response)) {
188                        var result = JSON.parse(response);
189                        if (result.number!=null) {
190                            MikoCallTracking.replaceNumbers(result.number);
191                            if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Подменяем номер на ',result.number);
192
193                            // Освободим номер из пула при таймауте пользователя
194                            //
195                            setTimeout(function() {
196                                MikoCallTracking.poolStarted=false;
197                                MikoCallTracking.replaceNumbers(MikoCallTracking.defaultNumber);
198                                if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг','Возврат номера по таймауту', MikoCallTracking.defaultNumber);
199                            }, MikoCallTracking.resetToDefaultTimeout);
200
201                            if (result.startpoll) {
202                                MikoCallTracking.poolStarted=true;
203                                MikoCallTracking.poll();
204                            } else {
205                                MikoCallTracking.poolStarted=false;
206                            }
207                        }
208                    }
209                })
210        },
211
212        // Дополним данные о посетителе из счетчиков Google и Yandex
213        //
214        updateAnalyticsInfo: function (){
215
216            BX.ajax.post(
217                MikoCallTracking.apiUrl+'?action=updateAnalyticsInfo',
218                {
219                    'userData': MikoCallTracking.visitorData(),
220                    'visitorId': MikoCallTracking.currentVisitorId
221                }
222            )
223            if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Отправили данные для обновления',MikoCallTracking.visitorData());
224        },
225
226        // Отправка цели во все инициализированные на странице счётчики Яндекс.Метрики.
227        // Счётчики определяются автоматически, поэтому конфигурация не нужна и код
228        // работает на любом сайте с подключённой Метрикой (общее ядро на несколько сайтов).
229        reachYandexGoal: function (goal, params) {
230            try {
231                if (!window.ym) return;
232                var ids = [];
233                // Основной источник — реально инициализированные счётчики Метрики (ключи вида "30535012:0")
234                if (window.Ya && window.Ya._metrika && window.Ya._metrika.counters) {
235                    for (var key in window.Ya._metrika.counters) {
236                        var cid = parseInt(key, 10);
237                        if (cid && ids.indexOf(cid) === -1) ids.push(cid);
238                    }
239                }
240                // Резервный источник — очередь вызовов ym(<id>,'init',...), если Метрика ещё не догрузилась
241                if (ids.length === 0 && window.ym.a) {
242                    window.ym.a.forEach(function (args) {
243                        if (args[1] === 'init' && ids.indexOf(args[0]) === -1) ids.push(args[0]);
244                    });
245                }
246                ids.forEach(function (id) { window.ym(id, 'reachGoal', goal, params || {}); });
247                if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Отправлена цель Метрики',goal,'в счётчики',ids);
248            } catch (e) {
249                if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Ошибка отправки цели Метрики',e);
250            }
251        },
252
253        track60secconversion: function(){
254
255            $('body') . activity({
256                'achieveTime':60
257                ,'testPeriod':10
258                ,useMultiMode: 1
259                ,callBack: function (e) {
260
261                    BX.ajax.post(
262                        MikoCallTracking.apiUrl+'?action=Register60SecConversion',
263                        {
264                            'visitorId': MikoCallTracking.currentVisitorId
265                        }
266                    );
267                    if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг:','Сработала конверсия 60 секунд');
268                }
269            })
270        },
271        // Запустим постоянное соединение с сайтом на случай звонка клиента
272        //
273        poll: function () {
274            if (!MikoCallTracking.poolStarted) return; // Прервем пул
275
276            setTimeout(function() {
277                BX.ajax.post(
278                    MikoCallTracking.apiUrl+'?action=getnewcall',
279                    {
280                        'visitorId': MikoCallTracking.currentVisitorId,
281                        'secondsago': MikoCallTracking.poolTimeout
282                    },
283                    function (result) { // Если есть ответ от сервера, значит был звонк, отправим в метрику данные
284                        if (/{*}/.test(result))
285                        {
286                            var call = JSON.parse(result);
287                            // Один и тот же звонок сервер возвращает в течение всего окна secondsago,
288                            // поэтому цель шлём только один раз на linkedid, иначе будет флуд в Метрику.
289                            if (call.linkedid && call.linkedid !== MikoCallTracking.lastGoalLinkedid) {
290                                MikoCallTracking.lastGoalLinkedid = call.linkedid;
291                                // Передаём цель звонка в счётчики: dataLayer (если на сайте остался GTM) + нативная Яндекс.Метрика
292                                if (window.dataLayer) {
293                                    dataLayer.push({
294                                        'event': 'calltracking',
295                                        'category': 'phone',
296                                        'action': 'call',
297                                        'linkedid': call.linkedid
298                                    });
299                                }
300                                MikoCallTracking.reachYandexGoal('calltracking', { linkedid: call.linkedid });
301                                if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг','Новый звонок', call);
302                            }
303                        } else {
304                            if (MikoCallTracking.debugMode)  console.log('МИКО: Коллтрекинг','Новый цикл Long Polling',result);
305                        }
306                        // Запускаем цикл из ajax запросов
307                        MikoCallTracking.poll();
308                    }
309                )
310            }, MikoCallTracking.poolTimeout*1000);
311        }
312
313    };
314
315
316});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.