PageSourceSearch

https://interforums.ru/js/jivo-contact-intake.js?v=1

js interforums.ru collected 2026-10-02 16:32:42 UTC 3,746 bytes, 112 lines download raw bytes

1(function (window, document) {
2  'use strict';
3
4  var ENDPOINT = window.IF_JIVO_CONTACT_INTAKE_URL || 'https://hooks.globalconf.ru/jivo/contact-intake';
5  var TOKEN_KEY = 'if_jivo_contact_token_v1';
6  var lastCompletedKey = '';
7  var inFlightKey = '';
8  var memoryToken = '';
9
10  function randomId(prefix) {
11    if (!window.crypto || typeof window.crypto.getRandomValues !== 'function' || typeof window.btoa !== 'function') return '';
12    var bytes = new window.Uint8Array(16);
13    window.crypto.getRandomValues(bytes);
14    var raw = Array.prototype.map.call(bytes, function (byte) { return String.fromCharCode(byte); }).join('');
15    return prefix + window.btoa(raw).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
16  }
17
18  function getOrCreateToken() {
19    var token = memoryToken;
20    try { token = window.sessionStorage.getItem(TOKEN_KEY) || token; } catch (_) {}
21    if (!/^ifj1_[A-Za-z0-9_-]{22}$/.test(token)) token = randomId('ifj1_');
22    if (!token) return '';
23    memoryToken = token;
24    try { window.sessionStorage.setItem(TOKEN_KEY, token); } catch (_) {}
25    return token;
26  }
27
28  function contactKey(info) {
29    return JSON.stringify([
30      String(info.client_name || '').trim(),
31      String(info.phone || '').trim(),
32      String(info.email || '').trim().toLowerCase(),
33      String(window.location && window.location.href || ''),
34    ]);
35  }
36
37  function sendWithRetry(payload, key) {
38    var delays = [0, 500, 1500];
39    inFlightKey = key;
40
41    function attempt(index) {
42      window.fetch(ENDPOINT, {
43        method: 'POST',
44        mode: 'cors',
45        credentials: 'omit',
46        keepalive: true,
47        headers: { 'Content-Type': 'application/json' },
48        body: JSON.stringify(payload),
49      }).then(function (response) {
50        if (!response || !response.ok) throw new Error('contact intake unavailable');
51        lastCompletedKey = key;
52        if (inFlightKey === key) inFlightKey = '';
53      }).catch(function () {
54        if (index + 1 < delays.length) {
55          window.setTimeout(function () { attempt(index + 1); }, delays[index + 1]);
56        } else if (inFlightKey === key) {
57          inFlightKey = '';
58        }
59      });
60    }
61
62    attempt(0);
63  }
64
65  function configureAndCapture() {
66    var api = window.jivo_api;
67    if (!api || typeof api.setUserToken !== 'function' || typeof api.getContactInfo !== 'function') return false;
68    var token = getOrCreateToken();
69    if (!token) return false;
70    try { api.setUserToken(token); } catch (_) { return false; }
71
72    var info;
73    try { info = api.getContactInfo() || {}; } catch (_) { return true; }
74    var phone = String(info.phone || '').trim();
75    var email = String(info.email || '').trim();
76    if (!phone && !email) return true;
77    var key = contactKey(info);
78    if (key === lastCompletedKey || key === inFlightKey) return true;
79    var eventId = randomId('ifje_');
80    if (!eventId) return true;
81    sendWithRetry({
82      version: 1,
83      token: token,
84      event_id: eventId,
85      name: String(info.client_name || '').trim(),
86      phone: phone,
87      email: email,
88      page: String(window.location && window.location.href || ''),
89    }, key);
90    return true;
91  }
92
93  function composeCallback(name) {
94    var previous = window[name];
95    window[name] = function () {
96      var result;
97      try {
98        if (typeof previous === 'function') result = previous.apply(this, arguments);
99      } finally {
100        configureAndCapture();
101      }
102      return result;
103    };
104  }
105
106  composeCallback('jivo_onLoadCallback');
107  composeCallback('jivo_onIntroduction');
108  composeCallback('jivo_onCallStart');
109  [0, 500, 1500, 4000].forEach(function (delay) {
110    window.setTimeout(configureAndCapture, delay);
111  });
112})(window, document);

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.