Simple rule based ai assistant with vanilla (pure) javascript

ai with js

note: this is a rule based ai and have certain limitations.

When we think of ai,we generally see complex algorithms and training with huge amounts of data. Well rule based ai is also an ai type and i have tried to make an assista…


This content originally appeared on DEV Community and was authored by volcareso

ai with js

note: this is a rule based ai and have certain limitations.

When we think of ai,we generally see complex algorithms and training with huge amounts of data. Well rule based ai is also an ai type and i have tried to make an assistant out of it with Wikipedia's api and open source weather source apis for weather. For data of course.

Next i used regex in js to detect likely phrases and added dome random sentences to reply.

Again, this is a RULE BASED ai. It has limitations.
I didnt fed huge amount of data, a little was sufficient :)

You can see the assistant here
the loading might appear similar try to guess ;)
And the github repo here

the script

const recommend = {
    'one': "what can you do",
    'two': "who are you",
    'three': "what is a piano",
    'four': "who is mahatma gandhi",
    'five': "how are you",
    'six': "hi",
    'onne': "who made you",
    'tmwo': "bye",
    'thjree': "who was trump",
    'fjour': "who is biden",
    'fjive': "what was Disney",
    'skix': "will you marry me"
}

const happy = {
    'one': "happy to help",
    'two': "you're happy im happy",
    'three': "glad you liked it",
    'four': "that did helped i guess",
    'five': "i am so excited",
    'six': "happy as you",
    'onne': "im happy forever",
    'tmwo': "so happy",
    'thjree': "that was interesting",
    'fjour': "nice",
    'fjive': "oh wow",
    'skix': "helping keeps me happy"
}

const sad = {
    'one': "whatever!",
    'two': "ughh",
    'three': "shitz",
    'four': "im bored",
    'five': "you shouldn't do that ig",
    'six': "*sighh*",
    'onne': "okay.....",
    'tmwo': "k den",
    'thjree': "aarghh",
    'fjour': "your not so cool",
    'fjive': "ill be silent",
    'skix': "sighh"
}
const lol = {
    'one': "lol",
    'two': "xD",
    'three': "hahaha",
    'four': "wow",
    'five': "?",
    'six': "?",
    'onne': "XD",
    'tmwo': "*laughing hard*",
    'thjree': "*cries out while laughing*",
    'fjour': "that was funny",
    'fjive': "you got me at that point",
    'skix': "see, who said machines can't laugh. xD"
}
const intro = {
    'one': "Hi there!",
    'two': "Oh Hello!",
    'three': "Hi",
    'four': "So happy to meet you!",
    'five': "Oh hi!",
    'six': "Hi, how may i help you?"
}

const outro = {
    "1": "BYE!",
    "2": 'bye bye have a nice day!',
    '3': "sure! bye",
    '4': "dont forget to come back soon!",
    '5': "oh bye then",
    "6": "TAKE CARE"
} 

function newsapi(){
  localStorage.setItem('news-api', prompt('enter api key'));
}

//to choose a random val in obj
function random_val(obj) {
    return obj[Object.keys(obj)[Math.floor(Math.random() * Object.keys(obj).length)]];
}

//initialise
function display(string) {
    document.querySelector('#assistant_display').innerHTML = string;
    read(document.querySelector('#assistant_display').innerHTML);
}
function displayWithoutSpeech(string) {
    document.querySelector('#assistant_display').innerHTML = string;
}

//the default hello msg
display(random_val(intro))

function search_wiki(search_item) {
    document.querySelector('#main_input').value = '';

    var searchTerm = search_item;
    var url = "https://en.wikipedia.org/w/api.php?action=opensearch&search=" + searchTerm + "&format=json&callback=?";

    $.ajax({
        type: "GET",
        url: url,
        async: false,
        dataType: "json",
        success: function(data) {
            $('#output').html('');
            if(data[1][0] != undefined){
            for (var i = 0; i < data[1].length; i++) {
                $('#output').prepend("<div class='search_box'><a class='search' href= " + data[3][i] + ">" + data[1][i] + "</a><p>" + data[2][i] + "</p></div>");

            }
            displayWithoutSpeech("I know about <a href='"+ data[3][1]+"'>" + data[1][1] + "</a> !");
            }else{
               display("I didn't get that!");
            }
        },

        error: function(err) {
            log("Error ("+err+") ");

        }



    })
}

function status_set(status) {
    document.querySelector('.emote').innerHTML = status;
}

function read(msg) {
    let speech = new SpeechSynthesisUtterance();
    speech.lang = "en-US";

    speech.text = msg;
    speech.volume = 1;
    speech.rate = 1;
    speech.pitch = 0.8;

    window.speechSynthesis.speak(speech);
}


function news(quer) {
    var query = quer.replace(" ", "+");
    display('sure!')
    $.getJSON("https://newsapi.org/v2/everything?q=" + query + "&sortBy=popularity&apiKey="+LocalStorage.getItem('news-api'), function(result) {
        for (let i = 0; i < result.articles.length; i++) {
            $('#output').append(`
                            <div class="news" onclick="document.location.href= '${result.articles[i].url}';">
                                <div class="news_title text-center" style="font-size: 25px;">
                                    ${result.articles[i].title}
                                </div>
                                <div class="news_description">
                                    <i class="text-center">${result.articles[i].description}</i>
                                </div>
                                <div class="news_source_name" style="text-align: right;">
                                    --> <i>${result.articles[i].source.name}</i>
                                </div>
                            </div>
                            <br>

                            `);
        }

    });
}

//fire event function initiated
function eventFire(el, etype) {
    if (el.fireEvent) {
        el.fireEvent('on' + etype);
    } else {
        var evObj = document.createEvent('Events');
        evObj.initEvent(etype, true, false);
        el.dispatchEvent(evObj);
    }
}

function search_word(search_item) {
    document.querySelector('#main_input').value = '';

    var searchTerm = search_item;
    var url = "https://api.dictionaryapi.dev/api/v2/entries/en_US/"+searchTerm;

    $.ajax({
        type: "GET",
        url: url,
        async: false,
        dataType: "json",
        success: function(data) {
            $('#output').html('');
            $('#output').append('<div class="text-center h4">' + data[0].word+'- '+data[0].phonetics[0].text+'<br>'+data[0].meanings[0].definitions[0].definition + '</div><audio controls autoplay><source src="'+ data[0].phonetics[0].audio +'" type="audio/mp3">Your browser does not support the audio element.</audio>');
        },

        error: function(err) {
            display("that don't have a meaning.");

        }



    })
}


function log(q) {
    document.querySelector('#log').innerHTML = q + "<br /><hr />" + document.querySelector('#log').innerHTML;
}

function respect(status){
  if(status == 'up'){
       localStorage.setItem('respect', Math.floor(localStorage.getItem("respect"))+1);
  }
  if(status == 'down'){
       localStorage.setItem('respect', localStorage.getItem('respect')-2);
  }
}

function eval_respect(){
   if(localStorage.getItem('respect') == 0 || localStorage.getItem('respect') == null ){
       return "give me time, ";
   }
   if(localStorage.getItem('respect') >= 5){
       return "you're nice but, ";
   } 
   if(localStorage.getItem('respect') >= 10){
       return "so sweet of you but, ";
   }
   if(localStorage.getItem('respect') < 0){
       return "you're abusive. ";
   }
   if(localStorage.getItem('respect') <= -10){
       return "you're dirty minded. ";
   }
   if(localStorage.getItem('respect') <= -20){
       return "go somewhere else, ";
   }
}

// the main hunt function to seek the ans
function hunt(query) {
    if (document.querySelector('#main_input').value == '') {
        return;
    }
    query = query.toLowerCase();

    if(document.querySelector('#main_input').value == localStorage.getItem('recent')){
       display('tell me when you are done with sending the same things...');
       status_set('?');
    }else{
      localStorage.setItem('recent', document.querySelector('#main_input').value)   

    if (/^hello|^hi|hey|nice to meet|it's a pleasure/.test(query)) {
        display(random_val(intro));
        status_set('?');
        respect('up');
    } else if (/^bye|boi|babai|i'll see you soon|it's time|see you/.test(query)) {
        display(random_val(outro));
        status_set('?');
    } else if (/ivy/.test(query)) {
        display('thats me for sure');
        status_set('?');
    }else if (/sorry/.test(query)) {
        display('Aw so sweet, I forgave you');
        localStorage.setItem('respect', '0');
        status_set('?');
    }else if (/lol|xD|haha|?|?|?|?|?|?/.test(query)) {
        display(random_val(lol));
        status_set('?');
    }else if (/(?=.*of)(?=.*meaning)/.test(query)) {
        display("yeah yeah, sure!");
        search_word(document.querySelector('#main_input').value.split('of ')[1])
        status_set('?');
    } else if (/(?=.*date)(?=.*what)/.test(query)) {
        display(new Date().getDate() + '/' + new Date().getMonth() + '/' + new Date().getFullYear());
        status_set('?');
    } else if (/(?=.*time)(?=.*what)/.test(query)) {
        display(new Date().getHours() + ':' + new Date().getMinutes() + ':' + new Date().getSeconds());
        status_set('');
    } else if (/(?=.*news )(?=.*about)|(?=.*news)(?=.*for)/.test(query)) {
        var val = document.querySelector('#main_input').value;
        displayWithoutSpeech("news and other stuff are coming up with pro. Else <a href='#' onclick='newsapi();' >enter</a> your <a href='newsapi.com'>newsapi.com</a> api key");
        news(val.split('about ')[1]);
        status_set('?');
    } else if (/(?=.*love)(?=.*me)(?=.*you)/.test(query)) {
        display(eval_respect() + 'I FEAR IM NOT THAT MUCH INTO LOVE');
        status_set('?');
    } else if (/anal|anus|arse|ass|ballsack|balls|bastard|bitch|biatch|bloody|blowjob|blow job|bollock|bollok|boner|boob|bugger|bum|butt|buttplug|clitoris|cock|coon|crap|cunt|damn|dick|dildo|dyke|fag|feck|fellate|fellatio|felching|fuck|f u c k|fudgepacker|fudge packer|flange|Goddamn|God damn|^hell|homo|jerk|jizz|knobend|knob end|labia|lmao|nigger|nigga|omg|penis|piss|poop|prick|pube|pussy|queer|scrotum|sex|shit|s hit|sh1t|slut|smegma|spunk|tit|tosser|turd|twat|vagina|wank|whore|wtf/.test(query)) {
        display(random_val(sad));
        respect('down');
        status_set('?');
    } else if (/(?=.*marry)(?=.*me)/.test(query)) {
        display(eval_respect() + 'I THINK YOU SHOULD ASK GOOGLE FOR THAT');
        status_set('?');
    } else if (/(?=.*love)(?=.*you)|(?=.*love)(?=.*me)/.test(query)) {
        display(eval_respect() + 'I THINK IM NOT THAT MUCH INTO IT');
        status_set('?');
        respect('up');
    } else if (/(?=.*you)(?=.*do)(?=.*what)/.test(query)) {
        display('ANYTHING ,JUST ASK!');
        status_set('?');
    } else if (/(?=.*made)(?=.*you)/.test(query)) {
        display('I WAS MADE BY VOLCARESO!');
        status_set('?');
    } else if (/(?=.*you)(?=.*how)|(?=.*you)(?=.*happy)|(?=.*you)(?=.*sad)|(?=.*you)(?=.*how)/.test(query)) {
        status_set('?');
        display(eval_respect()+random_val(happy));
    } else if (/(?=.*you)(?=.*how)/.test(query)) {
        display('IM FINE, ANYTHING I CAN HELP WITH?')
        status_set('?');
    } else if (/(?=.*you)(?=.*name)|(?=.*you)(?=.*who)/.test(query)) {
        display('IM IVY, YOUR ASSISTANT!');
        status_set('?');
    } else if (/who is/.test(query)) {
        var val = document.querySelector('#main_input').value;
        search_wiki(val.split('is ')[1]);
        status_set('?');
    } else if (/who was/.test(query)) {
        var val = document.querySelector('#main_input').value;
        search_wiki(val.split('was ')[1]);
        status_set('?');
    } else if (/what is/.test(query)) {
        var val = document.querySelector('#main_input').value;
        search_wiki(val.split('is ')[1]);
        status_set('?');
    } else if (/what was/.test(query)) {
        var val = document.querySelector('#main_input').value;
        search_wiki(val.split('was ')[1]);
        status_set('?');
    } else if (/weather/.test(query)) {

        if (localStorage.getItem('loc') == null) {
            var cityName = prompt("ENTER YOUR CITY: (I'LL ASK YOU ONLY ONE TIME)");
            localStorage.setItem('loc', cityName);
            link = "https://api.openweathermap.org/data/2.5/weather?q=" + cityName + "&units=metric&apikey=dcaa145d416ffe38627b8ea7d232bf5e";
            var request = new XMLHttpRequest();
            request.open('GET', link, true);
            request.onload = function() {
                var obj = JSON.parse(this.response);
                if (request.status >= 200 && request.status < 400) {
                    var temp = obj.main.temp;
                    display(temp + ' °Celsius');
                } else {
                    display("The city doesn't exist! Kindly check");
                }
            }
            request.send();
        } else {
            link = "https://api.openweathermap.org/data/2.5/weather?q=" + localStorage.getItem('loc') + "&units=metric&apikey=dcaa145d416ffe38627b8ea7d232bf5e";
            var request = new XMLHttpRequest();
            request.open('GET', link, true);
            request.onload = function() {
                var obj = JSON.parse(this.response);
                if (request.status >= 200 && request.status < 400) {
                    var temp = obj.main.temp;
                    display(temp + ' °Celsius');
                } else {
                    display("The city doesn't exist! Kindly check");
                }
            }
            request.send();
        }

        status_set('☁️');
    } else {
        search_wiki(document.querySelector('#main_input').value);
        status_set('?');
    }
}

}

//align rec values randomly
document.querySelector("#reco").innerHTML = random_val(recommend);

$("#reco").on('click', function() {
    document.querySelector("#main_input").value = this.innerHTML;
    eventFire(document.querySelector('.hunt'), 'click')
})

document.querySelector("#recom").innerHTML = random_val(recommend);

$("#recom").on('click', function() {
    document.querySelector("#main_input").value = this.innerHTML;
    eventFire(document.querySelector('.hunt'), 'click')
})

document.querySelector("#recomm").innerHTML = random_val(recommend);

$("#recomm").on('click', function() {
    document.querySelector("#main_input").value = this.innerHTML;
    eventFire(document.querySelector('.hunt'), 'click')
})


var SpeechRecognition = SpeechRecognition || webkitSpeechRecognition
var SpeechGrammarList = SpeechGrammarList || webkitSpeechGrammarList
var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEvent

var grammar = '#JSGF V1.0; grammar colors; public <color> = ["hi","hello"];' 

var recognition = new SpeechRecognition();
var speechRecognitionList = new SpeechGrammarList();
speechRecognitionList.addFromString(grammar, 1);
recognition.grammars = speechRecognitionList;
recognition.continuous = false;
recognition.lang = 'en-US';
recognition.interimResults = false;
recognition.maxAlternatives = 1;

document.querySelector('.mic_img').onclick = function() {
    recognition.start();
    log('Ready to receive command.');
}

recognition.onresult = function(event) {
    var command = event.results[0][0].transcript;
    log('I HEARD --> ' + command);
    log('Confidence: ' + Math.round(event.results[0][0].confidence * 100) + '%');
    document.querySelector('#main_input').value = command;
    eventFire(document.querySelector('.hunt'), 'click')
}

recognition.onspeechend = function() {
    recognition.stop();
}

recognition.onnomatch = function(event) {
    log("I didn't recognise that command.");
}

recognition.onerror = function(event) {
    log('Error : ' + event.error);
}

You can see as my friend suggested i added the abuse filter i took the list online (i swear).
Also the respect stuff makes her dynamic but not that much.
Also emotions were a great approach!

the gui (index.html)

<style>
.ccenter{
   position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.wobbling-4 {
  width:20px;
  height:20px;
  background:#25b09b;
  box-shadow:0 0 60px 15px #25b09b;
  transform: translate(-80px);
  clip-path:inset(0);
  animation:
    w4-1 0.5s ease-in-out infinite alternate,
    w4-2 1s   ease-in-out infinite;
}

@keyframes w4-1 {
  100% {transform:translateX(80px)}
}

@keyframes w4-2 {
   33% {clip-path:inset(0 0 0 -100px)}
   50% {clip-path:inset(0 0 0 0)     }
   83% {clip-path:inset(0 -100px 0 0)}
} 
</style>
<div class="loading ccenter">
   <div class="wobbling-4"></div>
</div>
<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
    <meta charset="utf-8">
    <title>IVY -an assistant made with javascript and regex (inside siliconduct)</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./style.css">
    <link rel="stylesheet" type="text/css" href="./stylesheet.css">
</head>

<body onload='document.querySelector(".loading").style.display = "none";'>
    <root>
        <div class="heading text-center display-2">
            HI, I'M IVY!
        </div>
        <br>
        <br>
        <div class="input-container text-center">
            <label for="main_input">
                <query>QUERY: </query>
            </label>
            <input type="text" id="main_input" name="main_input" placeholder="what can you do?" />
        </div>
        <br>
        <div class="text-center display-5">TRY THEESE:</div>
        <div class="text-center recommended">
            <span id="reco">loading...</span>
            <span id="recom">loading...</span>
            <span id="recomm">loading...</span>
        </div>
        <br>
        <div class="button-container text-center">
            <button class="btn hunt btn-primary" onclick="hunt(document.querySelector('#main_input').value)">
                ASK
            </button>
            <img class="mic_img" src="https://cdn.pixabay.com/photo/2018/05/15/20/47/microphone-3404243_960_720.png"
                alt="SPEAK">
        </div>
        <br><br>
        <div class="text-center assistant_container">
            <span class="display-5"><span class="assistant_name"><span class="emote">?</span>IVY:</span>
            </span><span id="assistant_display" class="text-center display-5 assistant_display">
                PLEASE WAIT..
            </span>
        </div>
        <br>
    </root>
    <br>
    <div id="output">

    </div>

    <div id="log">
        <div class="text-center">
            HERE GOES YOUR ASSISTANT LOGS (ERROS AND WARNS)
        </div>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="./script.js" charset="utf-8"></script>
</body>

</html>

The loading animation is the most satisfying one. guess it!

Im just 15 so tell me as much as you can about how i can make something better.
Any issue, bad practices are welcomed in the comments!


This content originally appeared on DEV Community and was authored by volcareso


Print Share Comment Cite Upload Translate Updates
APA

volcareso | Sciencx (2021-09-07T06:18:39+00:00) Simple rule based ai assistant with vanilla (pure) javascript. Retrieved from https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/

MLA
" » Simple rule based ai assistant with vanilla (pure) javascript." volcareso | Sciencx - Tuesday September 7, 2021, https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/
HARVARD
volcareso | Sciencx Tuesday September 7, 2021 » Simple rule based ai assistant with vanilla (pure) javascript., viewed ,<https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/>
VANCOUVER
volcareso | Sciencx - » Simple rule based ai assistant with vanilla (pure) javascript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/
CHICAGO
" » Simple rule based ai assistant with vanilla (pure) javascript." volcareso | Sciencx - Accessed . https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/
IEEE
" » Simple rule based ai assistant with vanilla (pure) javascript." volcareso | Sciencx [Online]. Available: https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/. [Accessed: ]
rf:citation
» Simple rule based ai assistant with vanilla (pure) javascript | volcareso | Sciencx | https://www.scien.cx/2021/09/07/simple-rule-based-ai-assistant-with-vanilla-pure-javascript/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.