zoukankan      html  css  js  c++  java
  • 基于JQ使用原生js构造一个自动回复随机消息的机器人

    某些业务会使用到页面里存在一个机器人,类似于假客服一样,可以回复游客的问题.

    那么如何自己写一个自动回复消息的机器人呢?

    源码献上

    /**
    * 基于jq的自动对话机器人
    * @param {Object} parmas 初始化配置  
    * parmas.talkModal 对话框弹出主体 classname  
    * parmas.talkBox 对话框内容区域 classname  
    * parmas.awakeBtn 唤醒按钮 用于显示对话框主体 classname  
    * parmas.exitBtn 隐藏按钮  用户隐藏对话框按钮 classname  
    * parmas.sendBtn 发送消息按钮 classname  
    * parmas.autoConent 自动对话框内容 Array  
    * parmas.input 内容输入框 classname  
    * parmas.openReply 在打开的时候自动回复一句 true or false  默认true
    * parmas.replyName 自动回复的dom类名 classname  
    * parmas.userName 用户回复的dom类名 classname  
    * parmas.isChangeBtnStatus 是否在点击 唤醒和隐藏的时候隐藏相反的按钮 true or false  默认true
    * parmas.fixedMsg 固定回复语句 string or dom  
    * 
    */
    function Talk(parmas) {
        if (typeof $ === "undefined") {
            throw new Error("Please load JQ API before use the Talk function!")
        }
        this.talkModal = $('.' + parmas.talkModal);
        this.talkContent = $("." + parmas.talkBox)
        this.awakeBtn = $("." + parmas.awakeBtn)
        this.autoConent = parmas.autoConent || ['你好', "欢迎你", "谢谢", "再见"]
        this.exitBtn = $("." + parmas.exitBtn)
        this.input = $("." + parmas.input)
        this.sendBtn = $("." + parmas.sendBtn)
        this.contentDefaultHeight = 0 // 对话框内容区域高度
        this.autoTimer = null; // 自动回复定时器
        this.autoIndexArr = Array.from({ length: this.autoConent.length }, (v, k) => k) //随机索引,先默认数组索引下标排列
        this.contentIndex = 0;
        this.openReply = parmas.openReply !== undefined ? parmas.openReply : true;
        this.fixedMsg = parmas.fixedMsg || "收到";
        this.isFixedReply = false;
        this.changeBtnStatus = parmas.isChangeBtnStatus !== undefined ? parmas.isChangeBtnStatus : true
        this.replyClassName = parmas.replyName || 'reply'
        this.userClassName = parmas.userName || 'customer-txt'
        // 检查绑定的dom是否符合规范
        this.isInvalid()
        // 绑定监听事件
        this.addEvent()
        // 生成自动回复索引
        this.randomIndex()
    }
    // 检查绑定的dom是否符合规范
    Talk.prototype.isInvalid = function () {
        if (this.talkModal.length === 0) {
            throw new Error('The TalkModal is not found.Please check out the binding TalkModel.')
        }
        if (this.talkContent.length === 0) {
            throw new Error("The TalkModal's contentBox is not found.Please check out the binding TalkModal's contentBox.")
        }
        if (this.awakeBtn.length === 0) {
            throw new Error("The TalkModal's awake Button is not found.Please check out the binding TalkModal's awake Button.")
        }
        if (this.input.length === 0) {
            throw new Error("The TalkModal's input is not found.Please check out the binding TalkModal's input.")
        }
    
        if (this.talkModal.length !== 1) {
            throw new Error("The TalkModal is not unique classname,Please check out the dom's classname.")
        }
        if (this.talkContent.length !== 1) {
            throw new Error("The TalkModal's contentBox  is not unique classname,Please check out the dom's classname.")
        }
        if (this.awakeBtn.length !== 1) {
            throw new Error("The TalkModal's awake Button  is not unique classname,Please check out the dom's classname.")
        }
        if (this.input.length !== 1) {
            throw new Error("The TalkModal's input  is not unique classname,Please check out the dom's classname.")
        }
    }
    
    // 绑定事件
    Talk.prototype.addEvent = function () {
        // 唤醒对话框按钮绑定事件
        this.awakeBtn.click(function (e) {
            e.stopPropagation || e.stopPropagation()
            this.showModal()
        }.bind(this))
        // 关闭对话框按钮 绑定事件
        this.exitBtn.click(function (e) {
            e.stopPropagation || e.stopPropagation()
            this.hiddenModal()
        }.bind(this))
        // 发送消息按钮 绑定事件
        this.sendBtn.click(function (e) {
            e.stopPropagation || e.stopPropagation()
            this.sendMsg()
        }.bind(this))
        // 输入框按钮监听回车
        this.input.on("keypress", function (event) {
            if (event.keyCode == "13") {
                this.sendMsg()
            }
        }.bind(this))
    }
    
    // 显示对话框
    Talk.prototype.showModal = function () {
        this.talkModal.fadeIn(300)
        if (this.changeBtnStatus) {
            this.awakeBtn.hide()
            this.exitBtn.show()
        }
        if (this.openReply) {
            this.autoReply()
        }
        if (this.contentDefaultHeight === 0) {
            this.contentDefaultHeight = this.talkContent.height()
        }
    }
    
    // 隐藏对话框
    Talk.prototype.hiddenModal = function () {
        clearTimeout(this.autoTimer)
        this.talkModal.fadeOut(0)
        if (this.changeBtnStatus) {
            this.exitBtn.hide()
            this.awakeBtn.show()
        }
    }
    
    // 用户主动发送消息
    Talk.prototype.sendMsg = function () {
        var val = this.input.val()
        if (!val || !val.trim()) {
            return
        }
        this.appendContent(this.userClassName, val)
        this.input.val('')
        this.isFixedReply = false
        // ...这里可以判断用户输入信息进行其他处理
        this.dealMsg(val)
    
    }
    /**
    * 处理用户输入信息 根据信息来回复
    * @param {String} msg 用户输入信息
    */
    Talk.prototype.dealMsg = function (msg) {
        // ...do Ajax or on the msg,according to directed reply
        if (msg === "你好") {
            var str = '我不好'
            this.autoReply(str)
            return
        }
        if (msg === "18888888888") {
            this.isFixedReply = true
        }
        // auto reply
        this.autoReply()
    }
    
    /**
    * 追加文本,每次聊天后滚动聊天区域
    * @param {String} classname 回复的类名 用于显示不同的对话 
    * @param {String} content 内容,即聊天内容
    */
    Talk.prototype.appendContent = function (classname, content) {
        this.talkContent.append('<div><p class="' + classname + '">' + content + '</p></div>')
        this.srcollContent()
    }
    
    // 滚动聊天内容区域
    Talk.prototype.srcollContent = function () {
        var height = this.talkContent.prop("scrollHeight")
        if (this.contentDefaultHeight > height) {
            return
        }
        this.talkContent.animate({ scrollTop: height }, 400);
    }
    
    /**
    * 机器人自动回复
    * @param {String} str 需要回复的内容 若没有则自动回复
    */
    Talk.prototype.autoReply = function (str) {
        clearTimeout(this.autoTimer)
        this.autoTimer = setTimeout(function () {
            if (this.isFixedReply) {
                return this.appendContent(this.replyClassName, this.fixedMsg)
            }
            if (str) {
                return this.appendContent(this.replyClassName, str)
            }
            var content = this.autoConent[this.autoIndexArr[this.contentIndex]]
            this.contentIndex += 1
            this.appendContent(this.replyClassName, content)
            if (this.contentIndex === this.autoConent.length) {
                this.randomIndex()
                this.contentIndex = 0
            }
        }.bind(this), 1500)
    }
    
    // 生成随机的消息索引数组
    Talk.prototype.randomIndex = function () {
        var len = this.autoConent.length;
        var temp = this.autoIndexArr
        for (var i = 0; i < len + 10; i++) {
            var rdm = Math.floor(Math.random() * temp.length)
            temp.push(temp[rdm])
            temp.splice(rdm, 1)
        }
        if (temp[0] === this.autoIndexArr[len - 1]) {
            this.randomIndex()
        } else {
            this.autoIndexArr = temp
        }
    }

    如何自己定制机器人回复内容

    只需要重写Talk函数的dealMsg函数即可,默认第一个参数是用户输入的内容,根据第一个参数进行判断去调用this.autoReply(str)即可,若不传str则默认是以预设的自动回复语句去回复.

    若你是否重写dealMsg,在Talk构造函数之后去实例化

    • 实例化
    var talk = new Talk({
        talkModal: "modal",  // 对话框主体
        talkBox: "talk-content", // 对话框内容区域
        awakeBtn: "awake", // 唤醒对话框按钮
        exitBtn: "exit", // 关闭对话框按钮
        input: "ipt", // 对话框input
        sendBtn: "send", // 发送信息按钮 // 自动回复的语句可以包含html字符
        replyName: "reply", //回复的类名 用于样式
        userName: "msg", // 用户使用的类名 用于样式
        openReply: false, // 打开自动回复一句
    })
    

      案例

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Talk</title>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <!-- 请在jq加载后,加载Talk,引入文件方式 ,或者 直接把函数复制到script里即可-->
    <script src="./Talk.js"></script>
    <style>
       * {
           margin: 0;
           padding: 0;
           border: 0;
       }
    
       .header {
           padding: 20px;
           text-align: center;
           font-size: 24px;
           background-color: antiquewhite;
       }
    
       .content {
           text-align: center;
           font-size: 24px;
           height: 1000px;
           line-height: 500px;
           background-color: aquamarine;
       }
    
       .fixed-wrap {
           position: fixed;
           right: 0;
           top: 50%;
           transform: translateY(-50%);
            30px;
           height: 100px;
           background-color: blanchedalmond;
       }
    
       .btn {
           text-align: center;
           padding: 3px 5px;
           font-size: 14px;
           cursor: pointer;
       }
    
       .exit {
           display: none;
       }
    
       .modal {
           position: absolute;
           display: none;
           left: -300px;
           top: -70px;
           padding: 10px;
            300px;
           height: 240px;
           box-sizing: border-box;
           background-color: burlywood;
       }
    
       .talk-content {
           height: 200px;
           overflow-y: auto;
       }
    
       .talk-content div {
           overflow: hidden;
       }
    
       .talk-content p {
           margin-bottom: 10px;
           padding: 8px;
           max- 80%;
           word-break: break-all;
           font-size: 12px;
           color: #000;
           border-radius: 10px;
       }
    
       .talk-content span {
           color: red;
       }
    
       .msg {
           float: right;
           background-color: #b7e6e7;
       }
    
       .reply {
           float: left;
           background-color: #fff;
       }
    
       .control {
           position: absolute;
           left: 10px;
           bottom: 5px;
           height: 25px;
       }
    
       .control input,
       .control button {
           outline: none;
           height: 100%;
           padding: 0 10px;
       }
    </style>
    </head>
    
    <body>
    <div class="header">header</div>
    <div class="content">content</div>
    <div class="fixed-wrap">
       <div class="awake btn">展开机器人</div>
       <div class="exit btn">关闭机器人</div>
       <div class="modal">
           <div class="talk-content">
           </div>
           <div class="control">
               <input type="text" class="ipt">
               <button class="send">发送</button>
           </div>
       </div>
    </div>
    </body>
    <script>
    var talk = new Talk({
       talkModal: "modal",  // 对话框主体
       talkBox: "talk-content", // 对话框内容区域
       awakeBtn: "awake", // 唤醒对话框按钮
       exitBtn: "exit", // 关闭对话框按钮
       input: "ipt", // 对话框input
       sendBtn: "send", // 发送信息按钮 // 自动回复的语句可以包含html字符
       replyName: "reply", //回复的类名 用于样式
       userName: "msg", // 用户使用的类名 用于样式
       openReply: false, // 打开自动回复一句
    })
    </script>
    
    </html>
    

      

  • 相关阅读:
    IOS中常见的Operation —— NSOperation
    动态语言,别再说不
    CoreImage的使用及常见滤镜工具(一)
    【iOS】用Layer创建一个三维模型以及拖动
    前端基础-html、css
    mysql数据库—索引
    mysql数据库—用户管理、pymysql模块
    mysql数据库—函数、数据备份、流程控制
    mysql数据库基本操作2
    mysql数据库—事务、存储过程
  • 原文地址:https://www.cnblogs.com/kongyijilafumi/p/13963018.html
Copyright © 2011-2022 走看看