Как создать чат бота бесплатно

В этой статье мы с вами поговорим о создании автоматической обратной связи для сайта. Она является очень важной составляющих любого сайта. Общение с клиентами — главная цель любого сайта, особенно продающих landing-page.

Некоторые сайты, которые содержат огромную аудиторию и большую клиентскую базу. У некоторых из них нет возможности нанять большое количество администраторов и модераторов для ответа на вопросы покупателей. Это может снизить количество клиентов, а также не дать появиться новым.

В таких ситуациях на помощь приходят чат-боты. Программы, которые содержат в себе определенное количество возможных вопросов и ответов посетителей. Они гораздо упрощают работу с клиентами, а также могут заменить людей, которые будут требовать определенную плату за работу. В каком-то смысле это даже экономит средства.

Их можно купить у специальных компаний по разработке веб-приложений, а можно и сделать самостоятельно. Сегодня мы покажем один из способов создания чат-бота для сайта, преимущественно через JavaScript.

Разметка страницы и подключение скриптов. HTML

В нашей работе мы будем использовать JavaScript и его библиотеку JQuery. Чтобы все записанные нами функции загружались и работали нам нужно подключить все плагины и скрипты, с помощью парного тега <script>. Создадим 2 тега <script>, в первом будет указана ссылка на основной JavaScipt документ, в котором мы и будем работать, а во втором подключим библиотеку JQuery.

Также для корректной работы плагина нужно подключить его стили. Для этого создадим тег <link>. В нем указываем ссылку, идентичную той, что находится в теге <script>.

Чат бот как создать
<!DOCTYPE html>
<html lang="ru">
<head>
	<title>Test Page</title>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
	<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
	<link rel="stylesheet" type="text/css" href="dist/jquery.convform.css">
	<script type="text/javascript" src="dist/jquery.convform.js"></script>

Для проверки работы чат-бота создаем форму. Записываем тег input с типом text и именем question. Можете поменять имя на любое другое, это не имеет особого значения.

Ниже можем создать блоки с вопросами. Создаем несколько списков select, в его атрибуте con-question вводим сам вопрос. Далее в элементах списка (option) записываем наши ответы. Вот пример:

Готовый чат бот
	<section id="demo">
	    <div class="vertical-align">
	        <div class="container">
	            <div class="row">
	                <div class="col-sm-6 col-sm-offset-3 col-xs-offset-0">
	                    <div class="card no-border">
	                        <div id="chat" class="conv-form-wrapper">
	                            <form action="" method="GET" class="hidden">
	                                <select data-conv-question="Здравствуйте! Я бот поддержки сайта Fokit.ru. Могу вам составить компанию, хотите поговорить? (Нужно выбрать ответ)" name="first-question">
	                                    <option value="yes">Давай</option>
	                                    <option value="sure">Конечно поболтаем!</option>
	                                </select>

Итак, мы создали небольшую структуру, содержащую вопросы с ответами. На неё мы будем ссылаться при работе с JavaScript.

Пару слов об атрибутах. Как вы наверное заметили в тегах <select> содержится атрибут "conv-question". Он содержит в себе необходимый вопрос, ответы на которые находятся в атрибуте "select". При желании можете поменять его на любой другой.

Если хотите поменять количество ответов и их содержимое, просто добавляйте теги <option> и задавайте значение атрибута <value>, то, которое вам нужно.

Работа с JavaScript

В нашем примере будем использовать один плагин, который используется для создания чат-бота. Он имеет свои определенные настройки, которые можно изменить. Не рекомендуем вам самостоятельно менять значения или записанные команды, если вы не разбираетесь в JavaScript, можно вписать некорректные значения, которые не позволят чат-боту работать.

Параметры JavaScript:

Чат бот как создать

Если хотите, то можете поменять названия некоторых функций. Также можно поменять значение "typeInputUi" на обычный "text". Вы заметите небольшую разницу в отображении. Как вы могли понять эта команда задает тип поля ответа. По умолчанию стоит значение "textarea", что равно тегу <textarea>.

Заключение

Чат бот в действии

Вы только что создали чат-бота для своего сайта, можем вас поздравить. Можете заменить список вопросов на более подходящий, а также поменять стилизацию. Данный бот универсален и подойдет для многих сайтов.

Если же что-то пошло не так, то скачайте предлагаемые исходники и попробуйте поработать с ними. Можете разобраться в их значениях, но это, скорее всего, займет определенное время.

Теги:
0

6 комментариев для “Как создать чат бота бесплатно

  1. все здорово и все понравилось, но не могли бы вы меня поправить,
    я так понял два скрипта это движок, другие файлы стиль а вот это то что надо:
    function SingleConvState(input){
    this.input = input;
    this.answer = »;
    this.next = false;
    return this;
    };
    SingleConvState.prototype.hasNext = function(){
    return this.next;
    };
    function ConvState(wrapper, SingleConvState, form, params) {
    this.form = form;
    this.wrapper = wrapper;
    this.current = SingleConvState;
    this.answers = {};
    this.parameters = params;
    this.scrollDown = function() {
    $(this.wrapper).find(‘#messages’).stop().animate({scrollTop: $(this.wrapper).find(‘#messages’)[0].scrollHeight}, 600);
    }.bind(this);
    };

    ConvState.prototype.next = function(){
    if(this.current.input.hasOwnProperty(‘callback’)) {
    window[this.current.input.callback](this);
    }
    if(this.current.hasNext()){
    this.current = this.current.next;
    if(this.current.input.hasOwnProperty(‘fork’) && this.current.input.hasOwnProperty(‘case’)){
    if(this.answers.hasOwnProperty(this.current.input.fork) && this.answers[this.current.input.fork].value != this.current.input.case) {
    return this.next();
    }
    if(!this.answers.hasOwnProperty(this.current.input.fork)) {
    return this.next();
    }
    }
    return true;
    } else {
    return false;
    }
    };
    ConvState.prototype.printQuestion = function(){
    var questions = this.current.input.questions;
    var question = questions[Math.floor(Math.random() * questions.length)]; //get a random question from questions array
    var ansWithin = question.match(/\{(.*?)\}(\:(\d)*)?/g); // searches for string replacements for answers and replaces them with previous aswers (warning: not checking if answer exists)
    for(var key in ansWithin){
    if(ansWithin.hasOwnProperty(key)){
    var ansKey = ansWithin[key].replace(/\{|\}/g, «»);
    var ansFinalKey = ansKey;
    var index = false;
    if(ansKey.indexOf(‘:’)!=-1){
    ansFinalKey = ansFinalKey.split(‘:’)[0];
    index = ansKey.split(‘:’)[1];
    }
    if(index!==false){
    var replacement = this.answers[ansFinalKey].text.split(‘ ‘);
    if(replacement.length >= index){
    question = question.replace(ansWithin[key], replacement[index]);
    } else {
    question = question.replace(ansWithin[key], this.answers[ansFinalKey].text);
    }
    } else {
    question = question.replace(ansWithin[key], this.answers[ansFinalKey].text);
    }
    }
    }
    var messageObj = $(this.wrapper).find(‘.message.typing’);
    setTimeout(function(){
    messageObj.html(question);
    messageObj.removeClass(‘typing’).addClass(‘ready’);
    if(this.current.input.type==»select»){
    this.printAnswers(this.current.input.answers, this.current.input.multiple);
    }
    this.scrollDown();
    if(this.current.input.hasOwnProperty(‘noAnswer’) && this.current.input.noAnswer===true) {
    if(this.next()){
    setTimeout(function(){
    var messageObj = $(»);
    $(this.wrapper).find(‘#messages’).append(messageObj);
    this.scrollDown();
    this.printQuestion();
    }.bind(this),200);
    } else {
    this.parameters.eventList.onSubmitForm(this);
    }
    }
    $(this.wrapper).find(this.parameters.inputIdHashTagName).focus();
    }.bind(this), 500);
    };
    ConvState.prototype.printAnswers = function(answers, multiple){
    this.wrapper.find(‘div.options div.option’).remove();
    if(multiple){
    for(var i in answers){
    if(answers.hasOwnProperty(i)){
    var option = $(»+answers[i].text+»)
    .data(«answer», answers[i])
    .click(function(event){
    var indexOf = this.current.input.selected.indexOf($(event.target).data(«answer»).value);
    if(indexOf == -1){
    this.current.input.selected.push($(event.target).data(«answer»).value);
    $(event.target).addClass(‘selected’);
    } else {
    this.current.input.selected.splice(indexOf, 1);
    $(event.target).removeClass(‘selected’);
    }
    this.wrapper.find(this.parameters.inputIdHashTagName).removeClass(‘error’);
    this.wrapper.find(this.parameters.inputIdHashTagName).val(»);
    if(this.current.input.selected.length > 0) {
    this.wrapper.find(‘button.submit’).addClass(‘glow’);
    } else {
    this.wrapper.find(‘button.submit’).removeClass(‘glow’);
    }
    }.bind(this));
    this.wrapper.find(‘div.options’).append(option);
    $(window).trigger(‘dragreset’);
    }
    }
    } else {
    for(var i in answers){
    if(answers.hasOwnProperty(i)){
    var option = $(»+answers[i].text+»)
    .data(«answer», answers[i])
    .click(function(event){
    this.current.input.selected = $(event.target).data(«answer»).value;
    this.wrapper.find(this.parameters.inputIdHashTagName).removeClass(‘error’);
    this.wrapper.find(this.parameters.inputIdHashTagName).val(»);
    this.answerWith($(event.target).data(«answer»).text, $(event.target).data(«answer»));
    this.wrapper.find(‘div.options div.option’).remove();
    }.bind(this));
    this.wrapper.find(‘div.options’).append(option);
    $(window).trigger(‘dragreset’);
    }
    }
    }
    var diff = $(this.wrapper).find(‘div.options’).height();
    $(this.wrapper).find(‘#messages’).css({paddingBottom: diff});

    };
    ConvState.prototype.answerWith = function(answerText, answerObject) {
    //console.log(‘previous answer: ‘, answerObject);
    //puts answer inside answers array to give questions access to previous answers
    if(this.current.input.hasOwnProperty(‘name’)){
    if(typeof answerObject == ‘string’) {
    if(this.current.input.type == ‘tel’)
    answerObject = answerObject.replace(/\s|\(|\)|-/g, «»);
    this.answers[this.current.input.name] = {text: answerText, value: answerObject};
    this.current.answer = {text: answerText, value: answerObject};
    //console.log(‘previous answer: ‘, answerObject);
    } else {
    this.answers[this.current.input.name] = answerObject;
    this.current.answer = answerObject;
    }
    if(this.current.input.type == ‘select’ && !this.current.input.multiple) {
    $(this.current.input.element).val(answerObject.value).change();
    } else {
    $(this.current.input.element).val(answerObject).change();
    }
    }
    //prints answer within messages wrapper
    if(this.current.input.type == ‘password’)
    answerText = answerText.replace(/./g, ‘*’);
    var message = $(»+answerText+»);

    //removes options before appending message so scroll animation runs without problems
    $(this.wrapper).find(«div.options div.option»).remove();

    var diff = $(this.wrapper).find(‘div.options’).height();
    $(this.wrapper).find(‘#messages’).css({paddingBottom: diff});
    $(this.wrapper).find(this.parameters.inputIdHashTagName).focus();
    if (answerObject.hasOwnProperty(‘callback’)) {
    window[answerObject.callback](this);
    }
    setTimeout(function(){
    $(this.wrapper).find(«#messages»).append(message);
    this.scrollDown();
    }.bind(this), 100);

    $(this.form).append(this.current.input.element);
    var messageObj = $(»);
    setTimeout(function(){
    $(this.wrapper).find(‘#messages’).append(messageObj);
    this.scrollDown();
    }.bind(this), 150);

    this.parameters.eventList.onInputSubmit(this, function(){
    //goes to next state and prints question
    if(this.next()){
    setTimeout(function(){
    this.printQuestion();
    }.bind(this), 300);
    } else {
    this.parameters.eventList.onSubmitForm(this);
    }
    }.bind(this));
    };

    (function($){
    $.fn.convform = function(options){
    var wrapper = this;
    $(this).addClass(‘conv-form-wrapper’);

    var parameters = $.extend(true, {}, {
    placeHolder : ‘Написать ответ боту’,
    typeInputUi : ‘textarea’,
    timeOutFirstQuestion : 1200,
    buttonClassStyle : ‘icon2-arrow’,
    eventList : {
    onSubmitForm : function(convState) {
    console.log(‘completed’);
    convState.form.submit();
    return true;
    },
    onInputSubmit : function(convState, readyCallback) {readyCallback()}
    },
    formIdName : ‘convForm’,
    inputIdName : ‘userInput’,
    loadSpinnerVisible : »,
    buttonText: ‘▶’
    }, options);

    /*
    * this will create an array with all inputs, selects and textareas found
    * inside the wrapper, in order of appearance
    */
    var inputs = $(this).find(‘input, select, textarea’).map(function(){
    var input = {};
    if($(this).attr(‘name’))
    input[‘name’] = $(this).attr(‘name’);
    if($(this).attr(‘data-no-answer’))
    input[‘noAnswer’] = true;
    if($(this).attr(‘required’))
    input[‘required’] = true;
    if($(this).attr(‘type’))
    input[‘type’] = $(this).attr(‘type’);
    input[‘questions’] = $(this).attr(‘data-conv-question’).split(«|»);
    if($(this).attr(‘data-pattern’))
    input[‘pattern’] = $(this).attr(‘data-pattern’);
    if($(this).attr(‘data-callback’))
    input[‘callback’] = $(this).attr(‘data-callback’);
    if($(this).is(‘select’)) {
    input[‘type’] = ‘select’;
    input[‘answers’] = $(this).find(‘option’).map(function(){
    var answer = {};
    answer[‘text’] = $(this).text();
    answer[‘value’] = $(this).val();
    if($(this).attr(‘data-callback’))
    answer[‘callback’] = $(this).attr(‘data-callback’);
    return answer;
    }).get();
    if($(this).prop(‘multiple’)){
    input[‘multiple’] = true;
    input[‘selected’] = [];
    } else {
    input[‘multiple’] = false;
    input[‘selected’] = «»;
    }
    }
    if($(this).parent(‘div[data-conv-case]’).length) {
    input[‘case’] = $(this).parent(‘div[data-conv-case]’).attr(‘data-conv-case’);
    input[‘fork’] = $(this).parent(‘div[data-conv-case]’).parent(‘div[data-conv-fork]’).attr(‘data-conv-fork’);
    }
    input[‘element’] = this;
    $(this).detach();
    return input;
    }).get();

    if(inputs.length) {
    //hides original form so users cant interact with it
    var form = $(wrapper).find(‘form’).hide();

    var inputForm;
    parameters.inputIdHashTagName = ‘#’ + parameters.inputIdName;

    switch(parameters.typeInputUi) {
    case ‘input’:
    inputForm = $(»+parameters.buttonText+’‘);
    break;
    case ‘textarea’:
    inputForm = $(»+parameters.buttonText+’‘);
    break;
    default :
    console.log(‘typeInputUi must be input or textarea’);
    return false;
    }

    //appends messages wrapper and newly created form with the spinner load
    $(wrapper).append(»);
    $(wrapper).append(inputForm);

    //creates new single state with first input
    var singleState = new SingleConvState(inputs[0]);
    //creates new wrapper state with first singlestate as current and gives access to wrapper element
    var state = new ConvState(wrapper, singleState, form, parameters);
    //creates all new single states with inputs in order
    for(var i in inputs) {
    if(i != 0 && inputs.hasOwnProperty(i)){
    singleState.next = new SingleConvState(inputs[i]);
    singleState = singleState.next;
    }
    }

    //prints first question
    setTimeout(function() {
    $.when($(‘div.spinLoader’).addClass(‘hidden’)).done(function() {
    var messageObj = $(»);
    $(state.wrapper).find(‘#messages’).append(messageObj);
    state.scrollDown();
    state.printQuestion();
    });
    }, parameters.timeOutFirstQuestion);

    //binds enter to answer submit and change event to search for select possible answers
    $(inputForm).find(parameters.inputIdHashTagName).keypress(function(e){
    if(e.which == 13) {
    var input = $(this).val();
    e.preventDefault();
    if(state.current.input.type==»select» && !state.current.input.multiple){
    if(state.current.input.required) {
    state.wrapper.find(‘#userInputBot’).addClass(‘error’);
    } else {
    var results = state.current.input.answers.filter(function (el) {
    return el.text.toLowerCase().indexOf(input.toLowerCase()) != -1;
    });
    if (results.length) {
    state.current.input.selected = results[0];
    $(this).parent(‘form’).submit();
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).addClass(‘error’);
    }
    }
    } else if(state.current.input.type==»select» && state.current.input.multiple) {
    if(input.trim() != «») {
    var results = state.current.input.answers.filter(function(el){
    return el.text.toLowerCase().indexOf(input.toLowerCase()) != -1;
    });
    if(results.length){
    if(state.current.input.selected.indexOf(results[0].value) == -1){
    state.current.input.selected.push(results[0].value);
    state.wrapper.find(parameters.inputIdHashTagName).val(«»);
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).val(«»);
    }
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).addClass(‘error’);
    }
    } else {
    if(state.current.input.selected.length) {
    $(this).parent(‘form’).submit();
    }
    }
    } else {
    if(input.trim()!=» && !state.wrapper.find(parameters.inputIdHashTagName).hasClass(«error»)) {
    $(this).parent(‘form’).submit();
    } else {
    $(state.wrapper).find(parameters.inputIdHashTagName).focus();
    }
    }
    }
    autosize.update($(state.wrapper).find(parameters.inputIdHashTagName));
    }).on(‘input’, function(e){
    if(state.current.input.type==»select»){
    var input = $(this).val();
    var results = state.current.input.answers.filter(function(el){
    return el.text.toLowerCase().indexOf(input.toLowerCase()) != -1;
    });
    if(results.length){
    state.wrapper.find(parameters.inputIdHashTagName).removeClass(‘error’);
    state.printAnswers(results, state.current.input.multiple);
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).addClass(‘error’);
    }
    } else if(state.current.input.hasOwnProperty(‘pattern’)) {
    var reg = new RegExp(state.current.input.pattern, ‘i’);
    if(reg.test($(this).val())) {
    state.wrapper.find(parameters.inputIdHashTagName).removeClass(‘error’);
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).addClass(‘error’);
    }
    }
    });

    $(inputForm).find(‘button.submit’).click(function(e){
    var input = $(state.wrapper).find(parameters.inputIdHashTagName).val();
    e.preventDefault();
    if(state.current.input.type==»select» && !state.current.input.multiple){
    if(state.current.input.required) {
    return false;
    } else {
    if (input == parameters.placeHolder) input = »;
    var results = state.current.input.answers.filter(function (el) {
    return el.text.toLowerCase().indexOf(input.toLowerCase()) != -1;
    });
    if (results.length) {
    state.current.input.selected = results[0];
    $(this).parent(‘form’).submit();
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).addClass(‘error’);
    }
    }
    } else if(state.current.input.type==»select» && state.current.input.multiple) {
    if(state.current.input.required) {
    return false;
    } else {
    if (input.trim() != «» && input != parameters.placeHolder) {
    var results = state.current.input.answers.filter(function (el) {
    return el.text.toLowerCase().indexOf(input.toLowerCase()) != -1;
    });
    if (results.length) {
    if (state.current.input.selected.indexOf(results[0].value) == -1) {
    state.current.input.selected.push(results[0].value);
    state.wrapper.find(parameters.inputIdHashTagName).val(«»);
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).val(«»);
    }
    } else {
    state.wrapper.find(parameters.inputIdHashTagName).addClass(‘error’);
    }
    } else {
    if (state.current.input.selected.length) {
    $(this).removeClass(‘glow’);
    $(this).parent(‘form’).submit();
    }
    }
    }
    } else {
    if(input.trim() != » && !state.wrapper.find(parameters.inputIdHashTagName).hasClass(«error»)){
    $(this).parent(‘form’).submit();
    } else {
    $(state.wrapper).find(parameters.inputIdHashTagName).focus();
    }
    }
    autosize.update($(state.wrapper).find(parameters.inputIdHashTagName));
    });

    //binds form submit to state functions
    $(inputForm).submit(function(e){
    e.preventDefault();
    var answer = $(this).find(parameters.inputIdHashTagName).val();
    $(this).find(parameters.inputIdHashTagName).val(«»);
    if(state.current.input.type == ‘select’){
    if(!state.current.input.multiple){
    state.answerWith(state.current.input.selected.text, state.current.input.selected);
    } else {
    state.answerWith(state.current.input.selected.join(‘, ‘), state.current.input.selected);
    }
    } else {
    state.answerWith(answer, answer);
    }
    });

    if(typeof autosize == ‘function’) {
    $textarea = $(state.wrapper).find(parameters.inputIdHashTagName);
    autosize($textarea);
    }

    return state;
    } else {
    return false;
    }
    }
    })( jQuery );
    *******************************************************************сам файл ехе:

    ******************************************************************
    как ввести в этом примере ответ на слово вопрос — и что?
    а ответ бота именно на эти слова — Что что?
    ******************************************************************
    движок ради интереса можно редактировать.

  2. *******************************************************************сам файл ехе:

    ******************************************************************

  3. да

    нет

    Надоел!
    *****************************************************************************
    тут все окей и вызазят окошки ответов и при нажатии все срабатывают и ведут далее по тексту но
    *****************************************************************************

    *****************************************************************************

    Задать вопрос

    Скрипты сложные?
    *************************************************************************************
    вторая попытка приносит неуспех, но все тоже самое, код повторяется но просто не работает.
    ***************************************************************************************

    ****************************************************************************************
    в этом месте движок не дает ответы на «text»

Добавить комментарий для Николай Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *