Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

342
LINES

< > BotCompany Repo | #1030498 // Pays5 Sahil-Style Bot Template As JavaScript [dev.]

Document

1  
// Minimal template - we assume JQuery is loaded
2  
// and script is included only once
3  
4  
/*jshint esversion: 6 */
5  
6  
console.log("starting sahil-style chat bot template");
7  
8  
// polyfill for URLSearchParams
9  
10  
(function (w) {
11  
  w.URLSearchParams = w.URLSearchParams || function (searchString) {
12  
      var self = this;
13  
      self.searchString = searchString;
14  
      self.get = function (name) {
15  
          var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString);
16  
          if (results == null) {
17  
              return null;
18  
          }
19  
          else {
20  
              return decodeURI(results[1]) || 0;
21  
          }
22  
      };
23  
  };
24  
})(window);
25  
26  
// helper for inserting emojis
27  
28  
$.fn.insertIntoTextArea = function(textToInsert) {
29  
  return this.each(function () {
30  
    var txt = $(this);
31  
    var cursorPosStart = txt.prop('selectionStart');
32  
    var cursorPosEnd = txt.prop('selectionEnd');
33  
    var v = txt.val();
34  
    var textBefore = v.substring(0,  cursorPosStart);
35  
    var textAfter  = v.substring(cursorPosEnd, v.length);
36  
    txt.val(textBefore + textToInsert + textAfter);
37  
    txt.prop('selectionStart', cursorPosStart + textToInsert.length);
38  
    txt.prop('selectionEnd', cursorPosStart + textToInsert.length);
39  
    txt.focus();
40  
  });
41  
};
42  
43  
// more helpers
44  
45  
function dynamicallyLoadScript(url, onload, asModule) {
46  
  var script = document.createElement("script");
47  
  script.src = url;
48  
  script.onload = onload;
49  
  if (asModule) script.type = "module";
50  
  document.head.appendChild(script);
51  
}
52  
53  
function dynamicallyLoadModule(code) {
54  
  var script = document.createElement("script");
55  
  script.type = "module";
56  
  script.appendChild(document.createTextNode(code));
57  
  document.head.appendChild(script);
58  
}
59  
60  
function loadStyleSheet(url, onLoad) {
61  
  var link = document.createElement('link');
62  
  link.setAttribute("rel", "stylesheet");
63  
  link.setAttribute("type", "text/css");
64  
  link.onload = onLoad;
65  
  link.setAttribute("href", url);
66  
  document.head.appendChild(link);
67  
}
68  
69  
class ChatBot {
70  
  constructor() {
71  
    this.n = $n;
72  
    this.interval = 1000;
73  
    this.nInitial = this.n;
74  
    this.started = false;
75  
    this.cookie = localStorage.getItem('chatbot-cookie');
76  
    this.notificationsOn = true;
77  
    this.pollURL = "$incrementalURL";
78  
79  
    this.sendTyping_sent = 0;
80  
    this.sendTyping_interval = 5000;
81  
    this.typingCounter = 0;
82  
    this.showTyping_interval = 3000;
83  
84  
    this.allowEmptyMsg = false;
85  
  
86  
    this.urlParams = new URLSearchParams(window.location.search);
87  
    this.botConfig = this.urlParams.get('_botConfig');
88  
    this.started = false;
89  
    this.justStarted = true;
90  
91  
    // allow cookie override in URL
92  
    var cookie2 = this.urlParams.get('cookie');
93  
    if (this.urlParams.get("_newBotCookie") == "1") {
94  
      this.cookie = "conv-" + Math.random().toString(36).substr(2, 9);
95  
      console.log("New cookie made >> " + this.cookie);
96  
    }
97  
98  
    if (cookie2) {
99  
      this.cookie = cookie2;
100  
      console.log("Cookie override >> " + cookie2);
101  
    }
102  
103  
    console.log("cookie 1: " + this.cookie);
104  
    if (!this.cookie) {
105  
      this.cookie = Math.random().toString(36).substr(2, 9);
106  
      localStorage.setItem('chatbot-cookie', this.cookie);
107  
      console.log("cookie 2: " + this.cookie);
108  
    }
109  
110  
    /*
111  
    // intTelInput.min.css
112  
    loadStyleSheet("https://botcompany.de/serve/1029819?ct=text/css");
113  
  
114  
    // intlTelInput.min.js
115  
    dynamicallyLoadScript("https://botcompany.de/serve/1029820?ct=text/javascript", function() {
116  
      window.telInput = document.querySelector("#chat_telephone");
117  
      console.log("telInput: " + telInput);
118  
      window.telHandler = window.intlTelInput(window.telInput, {
119  
        utilsScript: "https://botcompany.de/serve/1029822?ct=text/javascript", 
120  
        preferredCountries: ["in", "gb"],
121  
        separateDialCode: true,
122  
        initialCountry: "$country"
123  
      });
124  
    });
125  
  
126  
    dynamicallyLoadScript("https://gazelle.rocks/emoji-picker/index.js", function() {
127  
      console.log("emoji picker loaded");
128  
      
129  
      dynamicallyLoadModule(`
130  
        import { EmojiButton } from "https://gazelle.rocks/emoji-picker/index.js";
131  
    
132  
        const picker = new EmojiButton();
133  
        const trigger = document.querySelector('#bot-emoji-trigger');
134  
    
135  
        picker.on('emoji', selection => {
136  
          console.log(selection.emoji);
137  
          $("#chat_message").insertIntoTextArea(selection.emoji);
138  
          setTimeout(function() {
139  
            $("#chat_message").focus();
140  
          }, 250);
141  
        });
142  
    
143  
        trigger.addEventListener('click', () => picker.togglePicker(trigger));
144  
      `);
145  
    }, true);
146  
    */
147  
  }
148  
    
149  
  standardParams() {
150  
    return "&cookie=" + this.cookie + "&rand=" + Math.random() + (!this.botConfig ? "" : "&_botConfig=" + encodeURIComponent(this.botConfig));
151  
  }
152  
  
153  
  start() {
154  
    if (this.started) return;
155  
    this.started = true;
156  
    this.poll();
157  
  }
158  
159  
  poll() {  
160  
    if (!this.pollURL) return;
161  
    
162  
    var url = this.pollURL + this.n + this.standardParams();
163  
    
164  
    // mandatory memory wipe on opening chat bot
165  
    if (this.language) url += "&language_default=" + this.language;
166  
    if (this.justStarted) {
167  
      url += "&message=!new+dialog";
168  
      this.justStarted = false;
169  
    }
170  
    
171  
    var self = this;
172  
    var again = function() { self.poll(); };
173  
    
174  
    console.log("Loading " + url);
175  
    $.get(url, function(src) {
176  
      console.log("Loaded " + src.length + " chars");
177  
      var match = src.match(/\d+/);
178  
      if (match != null) {
179  
        var newN = parseInt(match[0]);
180  
        if (src.match(/NEW DIALOG -->/)) {
181  
          $(".chat-box .chat-live-content").html(src);
182  
        } else {
183  
          // hide old buttons and special input fields
184  
          $(".chat_buttons, .chat-button-span, .chatbot-choice-button").hide();
185  
          $("#chat_telephone, .iti").hide();
186  
          $("#chat_message").show();
187  
          // now append new stuff
188  
          $(".chat-box .chat-live-content").append(src);
189  
        }
190  
        //var oldN = self.n;
191  
        self.n = newN;
192  
        console.log("newN=" + newN);
193  
        $(".chat-box").scrollTop(1000000);
194  
        console.log("Appended " + src.length);
195  
        console.log(src);
196  
      } else
197  
        console.log("self.n=" + self.n + " (initial=" + self.nInitial + ")");
198  
      var interval = self.interval;
199  
      console.log("Rescheduling (" + interval + ")");
200  
      //var interval = src == '' ? self.interval*10 : self.interval; // slowdown when bug
201  
      setTimeout(again, interval);
202  
      console.log("Rescheduled");
203  
    }, 'text')
204  
      .fail(function() {
205  
        console.log("Rescheduling after fail");
206  
        setTimeout(again, self.interval);
207  
      });
208  
  }
209  
210  
  // also focuses input field  
211  
  setInput(text, placeholder) {
212  
    if (placeholder == '') placeholder = "Type a message...";
213  
    $('#chat_message')
214  
      .attr('placeholder', placeholder);
215  
    if (text)
216  
      $('#chat_message').val(text).select().focus();
217  
  }
218  
  
219  
  submitAMsg(msg) {
220  
    if (!this.allowEmptyMsg && msg == "") return;
221  
    $("#chat_message").val(msg);
222  
    this.submitMsg();
223  
  }
224  
  
225  
  submitMsg() {
226  
    var msg = $("#chat_message").val();
227  
    
228  
    if ($("#chat_telephone").is(":visible") && !/^!/.test(msg))
229  
      msg = window.telHandler.getNumber();
230  
231  
    var url = '$msgURL' + encodeURIComponent(msg) + this.standardParams();
232  
    if (this.language) url += "&language_default=" + this.language;
233  
    console.log('Submitting ' + url);
234  
    $.get(url);
235  
    $("#chat_message").val('');
236  
  }  
237  
  
238  
  playChatNotification() {
239  
    if (window.chatNotificationWav == null) {
240  
      console.log("Loading notification wav");
241  
      window.chatNotificationWav = new Audio("$notificationSound");
242  
      if ("$workerMode" != "true")
243  
        window.chatNotificationWav.volume = 0.5;
244  
    }
245  
    console.log("Playing notification mp3");
246  
    window.chatNotificationWav.play();
247  
  }
248  
  
249  
  /*var originalTitle;
250  
  
251  
  window.setTitleStatus = function(status) {
252  
    if (originalTitle == null)
253  
      originalTitle = document.title;
254  
    if (!document.hasFocus() || document.activeElement !== document.getElementById('chat_message')) {
255  
      if (status) status = status + " ";
256  
    } else status = "";
257  
    document.title = status + originalTitle;
258  
  };
259  
  
260  
  resetTitle() {
261  
    window.setTitleStatus("");
262  
  }
263  
  
264  
  window.onfocus = resetTitle;
265  
  $('#chat_message').on("focus", resetTitle);*/
266  
  
267  
  sendTyping() {
268  
    var time = Date.now();
269  
    if (time > this.sendTyping_sent+this.sendTyping_interval) {
270  
      this.sendTyping_sent = time;
271  
      var url = "$typingURL" + this.standardParams();
272  
      console.log("Loading " + url);
273  
      $.get(url);
274  
    }
275  
  }
276  
  
277  
  notiToggle() {
278  
    this.submitAMsg('!toggle notifications');
279  
    var text = $("#chatBot_notiToggleText");
280  
    text.text("Turn " + (/Turn on/.test(text.text()) ? "off" : "on") + " notifications");
281  
  }
282  
  
283  
  showTyping(botImg) {
284  
    var self = this;
285  
    console.log("showTyping " + self.typingCounter);
286  
    self.typingCounter++;
287  
    
288  
    // set avatar image for typing wave
289  
    if (botImg) {
290  
      // old version: $('#otherSideTyping img').attr('src', botImg);
291  
      $('#otherSideTyping div.bg-img').css("background-image", "url('" + botImg + "')");
292  
    }
293  
294  
    if (self.typingCounter == 1)
295  
      $('#otherSideTyping').css('display', 'block');
296  
    setTimeout(function() {
297  
      console.log("showTyping end " + self.typingCounter);
298  
      if (--self.typingCounter <= 0)
299  
        $('#otherSideTyping').css('display', 'none');
300  
    }, self.showTyping_interval);
301  
  }
302  
  
303  
  chat_keyDown(event) {
304  
    if (event.keyCode == 13) { this.submitMsg(); return false; }   
305  
    else if (event.keyCode >= 32 && event.keyCode < 128) this.sendTyping();
306  
  }
307  
} // end of class ChatBot
308  
309  
var chatBot = new ChatBot();
310  
311  
function chatBot_setInput(text, placeholder) {
312  
  chatBot.setInput(text, placeholder);
313  
}
314  
315  
function submitAMsg(msg) {
316  
  chatBot.submitAMsg(msg);
317  
}
318  
319  
function submitMsg() {
320  
  chatBot.submitMsg();
321  
}
322  
323  
function showTyping(botImg) { chatBot.showTyping(botImg); }
324  
325  
function playChatNotification() { chatBot.playChatNotification(); }
326  
327  
// change window title when bot says something
328  
329  
var originalTitle;
330  
331  
function setTitleStatus(status) {
332  
  if (originalTitle == null)
333  
    originalTitle = document.title;
334  
  if (!document.hasFocus() || document.activeElement !== document.getElementById('chat_message')) {
335  
    if (status) status = status + " ";
336  
  } else status = "";
337  
  document.title = status + originalTitle;
338  
}
339  
340  
function resetTitle() {
341  
  setTitleStatus("");
342  
}

Author comment

Began life as a copy of #1030430

download  show line numbers   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030498
Snippet name: Pays5 Sahil-Style Bot Template As JavaScript [dev.]
Eternal ID of this version: #1030498/29
Text MD5: 0dbd9778bc710bf6e6368eda2520534c
Author: stefan
Category: javax / web chat bots
Type: Document
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-01-13 23:01:13
Source code size: 10682 bytes / 342 lines
Pitched / IR pitched: No / No
Views / Downloads: 185 / 310
Version history: 28 change(s)
Referenced in: [show references]