|
|
let kara = new Vue({ |
|
|
el: '#kara', |
|
|
data: { |
|
|
features: { |
|
|
changeName: false, |
|
|
themes: false, |
|
|
setNameAtStart: true |
|
|
}, |
|
|
documentation: '', |
|
|
messages: [], |
|
|
talk: false, |
|
|
lastMessage: null, |
|
|
lastMessageData: {}, |
|
|
name: 'Kara', |
|
|
location: null, |
|
|
chatbox: null, |
|
|
isTyping: false, |
|
|
askedForName: false, |
|
|
awaitTodo: false, |
|
|
username: '', |
|
|
themes: null, |
|
|
activeTheme: 'slate', |
|
|
addModal: { |
|
|
includeAll: false, |
|
|
keywords: '', |
|
|
responses: [ |
|
|
'Answer #1' |
|
|
] |
|
|
}, |
|
|
settingsModal: { |
|
|
name: null, |
|
|
username: null, |
|
|
location: '' |
|
|
}, |
|
|
todos: [], |
|
|
reactions: [] |
|
|
}, |
|
|
mounted() { |
|
|
this.getSavedData(); |
|
|
this.getReactions(); |
|
|
this.getDocumentation(); |
|
|
|
|
|
if (this.features.themes) { |
|
|
this.getBootswatchThemes(); |
|
|
} |
|
|
|
|
|
this.settingsModal = { |
|
|
name: this.name, |
|
|
username: this.username, |
|
|
location: this.location |
|
|
}; |
|
|
|
|
|
if (!this.username || this.username === "null") { |
|
|
this.initialGreeting(); |
|
|
|
|
|
if (this.features.setNameAtStart) { |
|
|
this.askForName(); |
|
|
} |
|
|
|
|
|
this.stopTyping(); |
|
|
} else { |
|
|
this.welcomeBack(); |
|
|
} |
|
|
|
|
|
document.getElementById('chatinput').focus(); |
|
|
document.title = this.name; |
|
|
|
|
|
this.scrollDown(); |
|
|
}, |
|
|
methods: { |
|
|
// Initial |
|
|
initialGreeting() { |
|
|
this.botMessage( |
|
|
this.oneOf( |
|
|
[ |
|
|
"Hi! I'm " + this.name + ". :)", |
|
|
"Hi, nice to meet you! My name is " + this.name + ". :)" |
|
|
] |
|
|
), |
|
|
false |
|
|
); |
|
|
}, |
|
|
welcomeBack() { |
|
|
this.botMessage( |
|
|
this.oneOf( |
|
|
[ |
|
|
"Hi! Haven't heard of you in a while. :)", |
|
|
"Welcome back! :)", |
|
|
"Hey :) Good to see you :)", |
|
|
] |
|
|
), |
|
|
false |
|
|
); |
|
|
}, |
|
|
|
|
|
// Name |
|
|
askForName() { |
|
|
this.botMessage( |
|
|
this.oneOf([ |
|
|
'May i ask for your name?', |
|
|
'Whats your name? :)', |
|
|
'How can i call you?', |
|
|
'How did your developers call you? :)' |
|
|
]), |
|
|
false |
|
|
); |
|
|
|
|
|
this.askedForName = true; |
|
|
}, |
|
|
setName(message) { |
|
|
this.username = message.trim(); |
|
|
this.settingsModal.username = this.username; |
|
|
this.askedForName = false; |
|
|
|
|
|
this.botMessage( |
|
|
this.oneOf([ |
|
|
"That's a beautiful name!", |
|
|
"Okay, i'll call you " + this.username + " from now on :)", |
|
|
"Nice to meet you, " + this.username + ". :D" |
|
|
]) |
|
|
) |
|
|
}, |
|
|
|
|
|
// Messages / Chat |
|
|
addMessage(body, bot, me = false) { |
|
|
this.messages.push({ |
|
|
body: body, |
|
|
bot: bot, |
|
|
command: body.search('/') === 0, |
|
|
me: me, |
|
|
time: Date.now() |
|
|
}) |
|
|
}, |
|
|
addImageMessage(imageObject, bot) { |
|
|
this.lastMessageData = imageObject; |
|
|
|
|
|
this.messages.push({ |
|
|
body: imageObject.body, |
|
|
bot: bot, |
|
|
src: imageObject.src |
|
|
|
|
|
}); |
|
|
|
|
|
setTimeout(() => { |
|
|
this.scrollDown(); |
|
|
}, 1000); |
|
|
|
|
|
this.stopTyping(); |
|
|
this.updateStorage(); |
|
|
}, |
|
|
botMessage(message, save = true) { |
|
|
this.addMessage(message, true); |
|
|
|
|
|
if (this.talk) { |
|
|
this.say(message); |
|
|
} |
|
|
|
|
|
this.stopTyping(); |
|
|
|
|
|
if (save) { |
|
|
this.updateStorage(); |
|
|
} |
|
|
}, |
|
|
userMessage(body) { |
|
|
this.addMessage(body, false); |
|
|
this.lastMessage = body; |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
sendMessage() { |
|
|
if (this.chatbox.trim() === '') { |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.chatbox.search('/me') !== 0) { |
|
|
this.userMessage(this.chatbox); |
|
|
} |
|
|
this.scrollDown(); |
|
|
this.react(this.chatbox); |
|
|
this.chatbox = ''; |
|
|
}, |
|
|
meMessage(message) { |
|
|
this.addMessage(this.username + ' ' + message, false, true); |
|
|
this.react(message, true); |
|
|
}, |
|
|
react(message, recursive = false) { |
|
|
this.startTyping(); |
|
|
|
|
|
if (message.search('/') === 0 && !recursive) { |
|
|
setTimeout(() => { |
|
|
this.processCommands(message); |
|
|
this.scrollDown(); |
|
|
}, 1000); |
|
|
} else { |
|
|
setTimeout(() => { |
|
|
// Check commands |
|
|
if (this.askedForName === true) { |
|
|
this.setName(message); |
|
|
} else if (this.awaitTodo === true) { |
|
|
this.saveTodo(message); |
|
|
} else { |
|
|
let answer = this.getReaction(message); |
|
|
if (answer) { |
|
|
this.botMessage(answer); |
|
|
} |
|
|
|
|
|
this.updateStorage(); |
|
|
} |
|
|
|
|
|
this.scrollDown(); |
|
|
}, 1800); |
|
|
} |
|
|
}, |
|
|
getReaction(message) { |
|
|
let preserveLastMessageData = false; |
|
|
message = this.cleanupMessage(message); |
|
|
|
|
|
let keywords = message.split(' '); |
|
|
let answer = undefined; |
|
|
|
|
|
if (this.lastMessageData.joke && this.includesOneOf(keywords, ['another', 'more'])) { |
|
|
this.tellJoke(this.lastMessageData.category); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.lastMessageData.meme && this.includesOneOf(keywords, ['another', 'more'])) { |
|
|
this.getRandomMeme(this.lastMessageData.category); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.lastMessageData.isJeopardy) { |
|
|
if (this.includesAllOf(keywords, ['give', 'up'])) { |
|
|
this.lastMessageData = {}; |
|
|
return 'The right question would have been: "' + this.lastMessageData.question + '"'; |
|
|
} |
|
|
|
|
|
if (this.isSimilar(message, this.lastMessageData.question)) { |
|
|
this.lastMessageData = {}; |
|
|
return this.oneOf([ |
|
|
'Wow! This is the right question.', |
|
|
'Correct!' |
|
|
]); |
|
|
} else { |
|
|
return this.oneOf([ |
|
|
"Sorry, that's not correct.", |
|
|
"That's not what we're searching for.", |
|
|
"Nope, sorry. You can always give up by typing \"I give up\" if you wan't to.", |
|
|
]); |
|
|
} |
|
|
} |
|
|
|
|
|
if (this.lastMessageData.isTrivia) { |
|
|
if (this.includesAllOf(keywords, ['give', 'up'])) { |
|
|
this.lastMessageData = {}; |
|
|
return this.oneOf([ |
|
|
'The right answer would have been: "' + this.lastMessageData.question + '"' |
|
|
]); |
|
|
} |
|
|
|
|
|
if (this.isSimilar(message, this.lastMessageData.answer)) { |
|
|
this.lastMessageData = {}; |
|
|
return this.oneOf([ |
|
|
'Congratulations! This is the correct answer.', |
|
|
'Correct!' |
|
|
]); |
|
|
} else { |
|
|
return this.oneOf([ |
|
|
"Sorry, that's not correct.", |
|
|
"That's not what we're searching for.", |
|
|
"Nope, sorry. You can always give up by typing \"I give up\" if you wan't to.", |
|
|
]); |
|
|
} |
|
|
} |
|
|
|
|
|
if (!preserveLastMessageData) { |
|
|
this.lastMessageData = {}; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['change', 'my', 'name'])) { |
|
|
this.askedForName = true; |
|
|
return "Please tell me how i should call you."; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['new', 'todo']) || |
|
|
this.includesAllOf(keywords, ['new', 'task']) || |
|
|
this.includesAllOf(keywords, ['take', 'todo']) || |
|
|
this.includesAllOf(keywords, ['save', 'to', 'clipboard']) |
|
|
) { |
|
|
this.awaitTodo = true; |
|
|
return this.oneOf([ |
|
|
"What do you wan't me to save for you?", |
|
|
"Tell me what you wan't to save.", |
|
|
"What is it you wan't to save?", |
|
|
]); |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['clear', 'chat'])) { |
|
|
this.clearChat(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['play']) && |
|
|
this.includesOneOf(keywords, ['quiz', 'trivia']) |
|
|
) { |
|
|
this.startQuiz(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['play', 'jeopardy'])) { |
|
|
this.startJeopardy(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['roll', 'dice'])) { |
|
|
this.rollDice(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['clear', 'chat'])) { |
|
|
this.clearChat(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['weather']) && |
|
|
this.includesOneOf(keywords, ['how','hows', 'what', 'whats']) |
|
|
) { |
|
|
this.checkWeather(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['knock', 'joke'])) { |
|
|
this.tellJoke('knock-knock'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['joke']) && this.includesOneOf(keywords, ['coding', 'programming', 'code', 'it'])) { |
|
|
this.tellJoke('programming'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['birb', 'meme'])) { |
|
|
this.getRandomMeme('birbmemes'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['anime', 'meme'])) { |
|
|
this.getRandomMeme('animememes'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['coding', 'meme'])) { |
|
|
this.getRandomMeme('codingmemes'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['dank', 'meme'])) { |
|
|
this.getRandomMeme('dankmemes'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['meme']) && |
|
|
this.includesOneOf(keywords, ['get', 'send']) |
|
|
) { |
|
|
this.getRandomMeme(); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['joke']) && this.includesOneOf(keywords, ['coding', 'programming', 'code', 'it'])) { |
|
|
this.tellJoke('programming'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['tell', 'joke']) || |
|
|
this.includesAllOf(keywords, ['something', 'funny']) || |
|
|
this.includesAllOf(keywords, ['cheer', 'me', 'up']) |
|
|
) { |
|
|
this.tellJoke('general'); |
|
|
return false; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['whats', 'the', 'time']) || this.includesAllOf(keywords, ['how', 'late'])) { |
|
|
return "It's " + moment().format('LT'); |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['what', 'day', 'it'])) { |
|
|
return "It's " + moment().format('dddd') + "."; |
|
|
} |
|
|
|
|
|
if (this.includesAllOf(keywords, ['what', 'date', 'it']) || this.includesAllOf(keywords, ['whats', 'the', 'date'])) { |
|
|
return "It's " + moment().format('dddd') + ", " + moment().format('MMMM Do YYYY') + "."; |
|
|
} |
|
|
|
|
|
this.reactions.forEach((reactionOption) => { |
|
|
if (reactionOption.includeAll === true) { |
|
|
if (this.includesAllOf(keywords, reactionOption.keywords)) { |
|
|
answer = this.oneOf(reactionOption.responses); |
|
|
} |
|
|
} else { |
|
|
if (this.includesOneOf(keywords, reactionOption.keywords)) { |
|
|
answer = this.oneOf(reactionOption.responses); |
|
|
} |
|
|
} |
|
|
}); |
|
|
|
|
|
if (answer) { |
|
|
return answer; |
|
|
} |
|
|
|
|
|
this.rsaBackupAnswer(message); |
|
|
}, |
|
|
|
|
|
// Forms |
|
|
saveSettings() { |
|
|
this.name = this.settingsModal.name; |
|
|
this.username = this.settingsModal.username; |
|
|
this.location = this.settingsModal.location; |
|
|
this.updateStorage(); |
|
|
|
|
|
this.scrollDown(); |
|
|
}, |
|
|
|
|
|
// Commands |
|
|
processCommands: function (message) { |
|
|
if (this.checkForCommands(message, 'todo')) { |
|
|
let todoToSave = this.checkForCommands(message, 'todo'); |
|
|
this.saveTodo(todoToSave); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'clear')) { |
|
|
this.clearChat(); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'weather')) { |
|
|
this.checkWeather(); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'joke')) { |
|
|
this.tellJoke(this.checkForCommands(message, 'joke')); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'meme')) { |
|
|
this.getRandomMeme(this.checkForCommands(message, 'meme')); |
|
|
} else if (this.checkForCommands(message, 'me ')) { |
|
|
this.meMessage(this.checkForCommands(message, 'me ')); |
|
|
} |
|
|
|
|
|
let animals = [ |
|
|
{animal: 'birb', emoji: '🐦'}, |
|
|
{animal: 'dog', emoji: '🐶'}, |
|
|
{animal: 'cat', emoji: '🐱'}, |
|
|
{animal: 'fox', emoji: '🦊'}, |
|
|
{animal: 'panda', emoji: '🐼'}, |
|
|
{animal: 'red_panda', emoji: '🤩'}, |
|
|
{animal: 'koala', emoji: '🐨'} |
|
|
]; |
|
|
|
|
|
animals.forEach((animal) => { |
|
|
if (this.checkForCommands(message, animal.animal + 'Img')) { |
|
|
this.rsaRandomAnimalImage(animal.animal, animal.emoji); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, animal.animal + 'Fact')) { |
|
|
this.rsaRandomAnimalFact(animal.animal, animal.emoji); |
|
|
} |
|
|
}); |
|
|
|
|
|
animals.forEach((animal) => { |
|
|
if (this.checkForCommands(message, animal.animal)) { |
|
|
this.rsaRandomAnimalImage(animal.animal, animal.emoji); |
|
|
} |
|
|
}); |
|
|
|
|
|
if (this.checkForCommands(message, 'lyrics')) { |
|
|
this.rsaLyrics(this.checkForCommands(message, 'lyrics')); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'quiz')) { |
|
|
this.startQuiz(); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'jeopardy')) { |
|
|
this.startJeopardy(); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'dice')) { |
|
|
this.rollDice(); |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'talk')) { |
|
|
this.talk = !this.talk; |
|
|
} |
|
|
|
|
|
if (this.checkForCommands(message, 'say')) { |
|
|
this.botMessage(this.checkForCommands(message, 'say')) |
|
|
} |
|
|
|
|
|
this.lastMessage = message; |
|
|
}, |
|
|
checkForCommands(message, commands) { |
|
|
if (!Array.isArray(commands)) { |
|
|
commands = [commands]; |
|
|
} |
|
|
|
|
|
let commandFound = false; |
|
|
let parameter = false; |
|
|
|
|
|
commands.forEach((command) => { |
|
|
if (commandFound) { |
|
|
return; |
|
|
} |
|
|
let commandString = '/' + command.toLowerCase(); |
|
|
|
|
|
if (message.search(commandString) === 0) { |
|
|
parameter = message.replace(commandString, '').trim(); |
|
|
commandFound = true; |
|
|
} |
|
|
}); |
|
|
|
|
|
return parameter ? parameter : commandFound; |
|
|
}, |
|
|
checkWeather() { |
|
|
let Kara = this; |
|
|
|
|
|
if (!Kara.location) { |
|
|
Kara.botMessage('Please set your location in the settings. ⚙'); |
|
|
return; |
|
|
} |
|
|
|
|
|
let city = this.location.toLowerCase(); |
|
|
let url = 'http://api.openweathermap.org/data/2.5/weather?q=' + city + '&appid=8a1aa336da8899c1038bf6bd808d8961&units=metric'; |
|
|
|
|
|
axios.get(url) |
|
|
.then(function (response) { |
|
|
Kara.botMessage('In ' + response.data.name + ' it\'s ' + response.data.main.temp.toFixed() + '°C with ' + response.data.weather[0].description + '.'); |
|
|
}) |
|
|
.catch(function (error) { |
|
|
alertify.notify(error, 'danger'); |
|
|
Kara.botMessage('I couldn\'t check the weather for your location. 🤔'); |
|
|
}) |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
getRandomMeme(category = 'memes') { |
|
|
let Kara = this; |
|
|
let url = 'https://meme-api.herokuapp.com/gimme/'; |
|
|
|
|
|
let categorySet = false; |
|
|
|
|
|
if (category !== true && category !== false) { |
|
|
category = category.trim(); |
|
|
categorySet = true; |
|
|
} else { |
|
|
category = 'memes' |
|
|
} |
|
|
|
|
|
axios.get(url + category) |
|
|
.then(function (response) { |
|
|
Kara.addImageMessage({ |
|
|
body: response.data.title, |
|
|
src: response.data.url |
|
|
}, true); |
|
|
|
|
|
Kara.lastMessageData = { |
|
|
meme: true, |
|
|
category: category |
|
|
}; |
|
|
}) |
|
|
.catch(function (error) { |
|
|
Kara.botMessage("Hmm.. i can't think of any good memes right now, sorry.. 😞"); |
|
|
}) |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
tellJoke(category) { |
|
|
let Kara = this; |
|
|
let categorySet = false; |
|
|
|
|
|
if (category !== true && category !== false) { |
|
|
category = category.trim(); |
|
|
categorySet = true; |
|
|
} else { |
|
|
category = 'general' |
|
|
} |
|
|
|
|
|
let url = 'https://official-joke-api.appspot.com/jokes/' + category + '/random'; |
|
|
|
|
|
axios.get(url) |
|
|
.then(function (response) { |
|
|
let joke = response.data[0]; |
|
|
|
|
|
Kara.botMessage(joke.setup); |
|
|
|
|
|
setTimeout(() => { |
|
|
Kara.botMessage(joke.punchline); |
|
|
Kara.scrollDown(); |
|
|
}, 3500); |
|
|
|
|
|
Kara.lastMessageData = { |
|
|
joke: true, |
|
|
category: category |
|
|
}; |
|
|
}) |
|
|
.catch(function (error) { |
|
|
console.log(error); |
|
|
|
|
|
if (categorySet) { |
|
|
Kara.botMessage("Sorry, i don't know any jokes about this topic.. 🙄"); |
|
|
} else { |
|
|
Kara.botMessage("I can't remember any jokes right now, sorry. 😢"); |
|
|
} |
|
|
}); |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
startQuiz() { |
|
|
let Kara = this; |
|
|
let url = 'https://jservice.io/api/random'; |
|
|
|
|
|
axios.get(url) |
|
|
.then(function (response) { |
|
|
let clue = response.data[0]; |
|
|
|
|
|
Kara.botMessage('Okay! Here is your question from the category "' + clue.category.title + '":'); |
|
|
Kara.botMessage(clue.question); |
|
|
|
|
|
Kara.lastMessageData = { |
|
|
isTrivia: true, |
|
|
answer: clue.answer |
|
|
}; |
|
|
}) |
|
|
.catch(function (error) { |
|
|
Kara.botMessage("It's not a good time for a quiz."); |
|
|
}); |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
startJeopardy() { |
|
|
let Kara = this; |
|
|
let url = 'https://jservice.io/api/random'; |
|
|
|
|
|
axios.get(url) |
|
|
.then(function (response) { |
|
|
let clue = response.data[0]; |
|
|
|
|
|
Kara.botMessage('Okay! Here we go. The category is "' + clue.category.title + '":'); |
|
|
Kara.botMessage(clue.answer); |
|
|
|
|
|
Kara.lastMessageData = { |
|
|
isJeopardy: true, |
|
|
question: clue.question |
|
|
}; |
|
|
}) |
|
|
.catch(function (error) { |
|
|
Kara.botMessage("It's not a good time for a quiz."); |
|
|
}); |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
rollDice() { |
|
|
let dice = Math.random()*6; |
|
|
|
|
|
if (dice < 1) { |
|
|
dice = 1; |
|
|
} else { |
|
|
dice = Math.floor(dice); |
|
|
} |
|
|
|
|
|
this.addImageMessage({ |
|
|
body: dice + '!', |
|
|
src: 'img/' + dice + '.png' |
|
|
}, true); |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
|
|
|
// Todos |
|
|
saveTodo(message) { |
|
|
this.awaitTodo = false; |
|
|
|
|
|
this.todos.push({ |
|
|
time: moment(), |
|
|
body: message, |
|
|
checked: false |
|
|
}); |
|
|
|
|
|
this.updateStorage(); |
|
|
|
|
|
this.botMessage( |
|
|
this.oneOf([ |
|
|
"Saved! :)", |
|
|
"You can read and check your todos in the clipboard-section. :)" |
|
|
]) |
|
|
) |
|
|
}, |
|
|
clearTodos() { |
|
|
this.todos = []; |
|
|
|
|
|
this.botMessage( |
|
|
this.oneOf([ |
|
|
"Todos cleared. 🚮" |
|
|
]) |
|
|
); |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
|
|
|
// Some Random API Commands |
|
|
rsaRandomAnimalImage(animal, emoji = '😄') { |
|
|
let Kara = this; |
|
|
|
|
|
Kara.startTyping(); |
|
|
|
|
|
axios.post('/api/curlJson', { |
|
|
url: 'https://some-random-api.ml/img/' + animal |
|
|
}) |
|
|
.catch((error) => { |
|
|
Kara.botMessage("Sorry, i can't find any good pictures right now 🙁" + emoji); |
|
|
}) |
|
|
.then((response) => { |
|
|
Kara.addImageMessage({ |
|
|
body: emoji, |
|
|
src: response.data.link |
|
|
}, true); |
|
|
}) |
|
|
}, |
|
|
rsaRandomAnimalFact(animal, emoji = '😄') { |
|
|
let Kara = this; |
|
|
|
|
|
Kara.startTyping(); |
|
|
|
|
|
axios.post('/api/curlJson', { |
|
|
url: 'https://some-random-api.ml/facts/' + animal |
|
|
}) |
|
|
.catch((error) => { |
|
|
Kara.botMessage("Sorry, i can't think of any good facts right now 🙁" + emoji); |
|
|
}) |
|
|
.then((response) => { |
|
|
Kara.botMessage(response.data.fact); |
|
|
}) |
|
|
}, |
|
|
rsaLyrics(searchFor) { |
|
|
let Kara = this; |
|
|
|
|
|
Kara.startTyping(); |
|
|
|
|
|
axios.post('/api/curlJson', { |
|
|
url: 'https://some-random-api.ml/lyrics/?title=' + searchFor.replace(' ', '%20') |
|
|
}) |
|
|
.catch((error) => { |
|
|
Kara.botMessage("Hmm.. i just can't remember the lyrics, but i love that song! 🎵🎧"); |
|
|
}) |
|
|
.then((response) => { |
|
|
Kara.addImageMessage({ |
|
|
body: "Here you go!<br>" + |
|
|
"<br>" + |
|
|
response.data.title + ' from ' + response.data.author + '<br>' + |
|
|
'<br>' + |
|
|
response.data.lyrics, |
|
|
src: response.data.thumbnail.genius |
|
|
}, true); |
|
|
}) |
|
|
}, |
|
|
rsaBackupAnswer(message) { |
|
|
let Kara = this; |
|
|
|
|
|
Kara.startTyping(); |
|
|
|
|
|
axios.post('/api/curlJson', { |
|
|
url: 'https://some-random-api.ml/chatbot?message=' + message |
|
|
}) |
|
|
.catch((error) => { |
|
|
Kara.botMessage("I don't know what to say.."); |
|
|
}) |
|
|
.then((response) => { |
|
|
Kara.botMessage(response.data.response); |
|
|
}); |
|
|
}, |
|
|
|
|
|
// LocalStorage |
|
|
getSavedData() { |
|
|
let savedName = localStorage.getItem('name'); |
|
|
|
|
|
this.name = savedName ? savedName : this.name; |
|
|
|
|
|
let savedUsername = localStorage.getItem('username'); |
|
|
this.username = savedUsername ? savedUsername : null; |
|
|
|
|
|
let savedActiveTheme = localStorage.getItem('activeTheme'); |
|
|
this.activeTheme = savedActiveTheme ? savedActiveTheme : 'slate'; |
|
|
|
|
|
let savedMessages = JSON.parse(localStorage.getItem('messages')); |
|
|
this.messages = savedMessages ? savedMessages : []; |
|
|
|
|
|
let savedTodos = JSON.parse(localStorage.getItem('todos')); |
|
|
this.todos = savedTodos ? savedTodos : []; |
|
|
|
|
|
let savedLastMessage = JSON.parse(localStorage.getItem('lastMessage')); |
|
|
this.lastMessage = savedLastMessage ? savedLastMessage : null; |
|
|
|
|
|
let savedLocation = JSON.parse(localStorage.getItem('location')); |
|
|
this.location = savedLocation ? savedLocation : null; |
|
|
|
|
|
this.scrollDown(); |
|
|
}, |
|
|
updateStorage() { |
|
|
localStorage.setItem('name', this.name); |
|
|
localStorage.setItem('username', this.username); |
|
|
localStorage.setItem('activeTheme', this.activeTheme); |
|
|
localStorage.setItem('messages', JSON.stringify(this.messages)); |
|
|
localStorage.setItem('answers', JSON.stringify(this.reactions)); |
|
|
localStorage.setItem('todos', JSON.stringify(this.todos)); |
|
|
localStorage.setItem('lastMessage', JSON.stringify(this.lastMessage)); |
|
|
localStorage.setItem('location', JSON.stringify(this.location)); |
|
|
}, |
|
|
clearStorage() { |
|
|
localStorage.clear(); |
|
|
location.reload(); |
|
|
}, |
|
|
|
|
|
// Utility |
|
|
scrollDown() { |
|
|
$('#chat-box').stop().animate({ |
|
|
scrollTop: ($('#chat-box')[0].scrollHeight * 10) |
|
|
}, 800); |
|
|
}, |
|
|
startTyping() { |
|
|
this.isTyping = true; |
|
|
}, |
|
|
stopTyping() { |
|
|
this.scrollDown(); |
|
|
this.isTyping = false; |
|
|
}, |
|
|
oneOf(answers) { |
|
|
let amountOfAnswers = answers.length; |
|
|
let randomIndex = Math.floor(Math.random() * (amountOfAnswers)); |
|
|
|
|
|
return this.convertWildcards(answers[randomIndex]); |
|
|
}, |
|
|
convertWildcards(message) { |
|
|
message = message.replace('$name$', this.username); |
|
|
message = message.replace('$botname$', this.name); |
|
|
|
|
|
return message; |
|
|
}, |
|
|
cleanupMessage(message) { |
|
|
message = message.toLowerCase(); |
|
|
return message.replace('?', '') |
|
|
.replace('!', '') |
|
|
.replace('.', '') |
|
|
.replace(',', '') |
|
|
.replace('-', '') |
|
|
.replace('_', '') |
|
|
.replace('#', '') |
|
|
.replace('\'', '') |
|
|
.replace('"', '') |
|
|
.replace('+', '') |
|
|
.replace('*', '') |
|
|
.replace('§', '') |
|
|
.replace('$', '') |
|
|
.replace('%', '') |
|
|
.replace('&', '') |
|
|
.replace('/', '') |
|
|
.replace('(', '') |
|
|
.replace(')', '') |
|
|
.replace('=', '') |
|
|
.replace('\\', '') |
|
|
.replace('@', '') |
|
|
.replace('~', '') |
|
|
.replace('…', ''); |
|
|
}, |
|
|
clearChat() { |
|
|
this.messages = []; |
|
|
this.botMessage(this.oneOf([ |
|
|
'Chat cleared.', |
|
|
'Evidence destroyed.', |
|
|
'Mind cleared.', |
|
|
'Uhm.. i think forgot everything we ever talked about.. oops.', |
|
|
'A fresh start!', |
|
|
"You've got something to hide? Nevermind, gotcha fam. Chat is cleared now. 🐱👤" |
|
|
])); |
|
|
|
|
|
this.updateStorage(); |
|
|
}, |
|
|
includesOneOf(keywords, wordsToSearch) { |
|
|
let includes = false; |
|
|
|
|
|
wordsToSearch.forEach((searchWord) => { |
|
|
if (keywords.includes(searchWord)) { |
|
|
includes = true; |
|
|
} |
|
|
}) |
|
|
|
|
|
return includes; |
|
|
}, |
|
|
includesAllOf(keywords, wordsToSearch) { |
|
|
let includesAllkeywords = true; |
|
|
|
|
|
wordsToSearch.forEach((searchWord) => { |
|
|
if (!keywords.includes(searchWord)) { |
|
|
includesAllkeywords = false; |
|
|
} |
|
|
}) |
|
|
|
|
|
return includesAllkeywords; |
|
|
}, |
|
|
|
|
|
// Ajax calls for saving/receiving reactions, documentation & themes |
|
|
getBootswatchThemes() { |
|
|
let Kara = this; |
|
|
|
|
|
axios.get('https://bootswatch.com/api/4.json') |
|
|
.then(function (response) { |
|
|
Kara.themes = response.data.themes; |
|
|
}) |
|
|
.catch(function (error) { |
|
|
console.log(error); |
|
|
}) |
|
|
}, |
|
|
getReactions() { |
|
|
let Kara = this; |
|
|
|
|
|
axios.get('/reactions/get').then((response) => { |
|
|
response.data.forEach((reaction) => { |
|
|
Kara.reactions.push(JSON.parse(reaction.reaction)); |
|
|
}); |
|
|
}).catch((error) => { |
|
|
console.log(error); |
|
|
}); |
|
|
}, |
|
|
getDocumentation() { |
|
|
let Kara = this; |
|
|
|
|
|
axios.get('/api/kara/documentation').then((response) => { |
|
|
Kara.documentation = response.data; |
|
|
}).catch((error) => { |
|
|
console.log(error); |
|
|
}); |
|
|
}, |
|
|
|
|
|
// Levenshtein distance |
|
|
isSimilar(message1, message2) { |
|
|
let longer = message1; |
|
|
let shorter = message2; |
|
|
|
|
|
if (message1.length < message2.length) { |
|
|
longer = message2; |
|
|
shorter = message1; |
|
|
} |
|
|
|
|
|
const longerLength = longer.length; |
|
|
if (longerLength === 0) { |
|
|
return 1.0; |
|
|
} |
|
|
|
|
|
let similarity = (longerLength - this.editDistance(longer, shorter)) / parseFloat(longerLength); |
|
|
|
|
|
return similarity > 0.65; |
|
|
}, |
|
|
|
|
|
editDistance: function (message1, message2) { |
|
|
message1 = message1.toLowerCase(); |
|
|
message2 = message2.toLowerCase(); |
|
|
|
|
|
let costs = []; |
|
|
for (let i = 0; i <= message1.length; i++) { |
|
|
let lastValue = i; |
|
|
for (let j = 0; j <= message2.length; j++) { |
|
|
if (i === 0) |
|
|
costs[j] = j; |
|
|
else { |
|
|
if (j > 0) { |
|
|
let newValue = costs[j - 1]; |
|
|
if (message1.charAt(i - 1) !== message2.charAt(j - 1)) |
|
|
newValue = Math.min(Math.min(newValue, lastValue), |
|
|
costs[j]) + 1; |
|
|
costs[j - 1] = lastValue; |
|
|
lastValue = newValue; |
|
|
} |
|
|
} |
|
|
} |
|
|
if (i > 0) { |
|
|
costs[message2.length] = lastValue; |
|
|
} |
|
|
} |
|
|
|
|
|
return costs[message2.length]; |
|
|
}, |
|
|
|
|
|
// Speech |
|
|
say(message) { |
|
|
var speech = new SpeechSynthesisUtterance(); |
|
|
|
|
|
// Set the text and voice attributes. |
|
|
speech.text = message; |
|
|
speech.volume = 1; |
|
|
speech.rate = 1; |
|
|
speech.pitch = 1; |
|
|
|
|
|
window.speechSynthesis.speak(speech); |
|
|
}, |
|
|
} |
|
|
}) |