|
|
|
|
|
let kara = new Vue({
|
|
|
|
|
|
el: '#kara',
|
|
|
|
|
|
data: {
|
|
|
|
|
|
features: {
|
|
|
|
|
|
changeName: false,
|
|
|
|
|
|
themes: false,
|
|
|
|
|
|
setNameAtStart: true
|
|
|
|
|
|
},
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
|
|
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.isTyping = false;
|
|
|
|
|
|
} 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 + ". :)"
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
);
|
|
|
|
|
|
},
|
|
|
|
|
|
welcomeBack() {
|
|
|
|
|
|
this.botMessage(
|
|
|
|
|
|
this.oneOf(
|
|
|
|
|
|
[
|
|
|
|
|
|
"Hi! Haven't heard of you in a while. :)",
|
|
|
|
|
|
"Welcome back! :)",
|
|
|
|
|
|
"Hey :) Good to see you :)",
|
|
|
|
|
|
]
|
|
|
|
|
|
)
|
|
|
|
|
|
);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 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? :)'
|
|
|
|
|
|
])
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
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"
|
|
|
|
|
|
])
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
this.updateStorage();
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 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.updateStorage();
|
|
|
|
|
|
},
|
|
|
|
|
|
botMessage(message) {
|
|
|
|
|
|
this.addMessage(message, true);
|
|
|
|
|
|
|
|
|
|
|
|
if (this.talk) {
|
|
|
|
|
|
this.say(message);
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
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.isTyping = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (message.search('/') === 0 && !recursive) {
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
this.processCommands(message);
|
|
|
|
|
|
|
|
|
|
|
|
this.isTyping = false;
|
|
|
|
|
|
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.isTyping = false;
|
|
|
|
|
|
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', '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, ['cat']) &&
|
|
|
|
|
|
this.includesOneOf(keywords, ['images', 'photos', 'send'])
|
|
|
|
|
|
) {
|
|
|
|
|
|
this.getRandomCat();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this.includesOneOf(keywords, ['doggo', 'dog', 'shiba']) &&
|
|
|
|
|
|
this.includesOneOf(keywords, ['images', 'photos', 'send'])
|
|
|
|
|
|
) {
|
|
|
|
|
|
this.getRandomShiba();
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this.includesAllOf(keywords, ['dank', 'meme'])) {
|
|
|
|
|
|
this.getRandomMeme('dankmemes')
|
|
|
|
|
|
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.botMessage("I don't know what to say..");
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// Forms
|
|
|
|
|
|
saveSettings() {
|
|
|
|
|
|
this.name = this.settingsModal.name;
|
|
|
|
|
|
this.username = this.settingsModal.username;
|
|
|
|
|
|
this.location = this.settingsModal.location;
|
|
|
|
|
|
this.updateStorage();
|
|
|
|
|
|
|
|
|
|
|
|
// this.botMessage('Settings saved! :)');
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
if (message.search(commandString) === 0) {
|
|
|
|
|
|
parameter = message.replace(commandString, '').trim();
|
|
|
|
|
|
commandFound = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
return parameter ? parameter : commandFound;
|
|
|
|
|
|
},
|
|
|
|
|
|
checkWeather() {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
|
|
|
|
|
|
if (!vue.location) {
|
|
|
|
|
|
vue.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) {
|
|
|
|
|
|
vue.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');
|
|
|
|
|
|
vue.botMessage('I couldn\'t check the weather for your location. 🤔');
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.updateStorage();
|
|
|
|
|
|
},
|
|
|
|
|
|
getRandomMeme(category = 'memes') {
|
|
|
|
|
|
let vue = 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) {
|
|
|
|
|
|
vue.addImageMessage({
|
|
|
|
|
|
body: response.data.title,
|
|
|
|
|
|
src: response.data.url
|
|
|
|
|
|
}, true);
|
|
|
|
|
|
|
|
|
|
|
|
vue.lastMessageData = {
|
|
|
|
|
|
meme: true,
|
|
|
|
|
|
category: category
|
|
|
|
|
|
};
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(function (error) {
|
|
|
|
|
|
vue.botMessage("Hmm.. i can't think of any good memes right now, sorry.. 😞");
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
this.updateStorage();
|
|
|
|
|
|
},
|
|
|
|
|
|
tellJoke(category) {
|
|
|
|
|
|
let vue = 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];
|
|
|
|
|
|
|
|
|
|
|
|
vue.botMessage(joke.setup);
|
|
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
vue.botMessage(joke.punchline);
|
|
|
|
|
|
vue.scrollDown();
|
|
|
|
|
|
}, 3500);
|
|
|
|
|
|
|
|
|
|
|
|
vue.lastMessageData = {
|
|
|
|
|
|
joke: true,
|
|
|
|
|
|
category: category
|
|
|
|
|
|
};
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(function (error) {
|
|
|
|
|
|
console.log(error);
|
|
|
|
|
|
|
|
|
|
|
|
if (categorySet) {
|
|
|
|
|
|
vue.botMessage("Sorry, i don't know any jokes about this topic.. 🙄");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
vue.botMessage("I can't remember any jokes right now, sorry. 😢");
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
this.updateStorage();
|
|
|
|
|
|
},
|
|
|
|
|
|
startQuiz() {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
let url = 'https://jservice.io/api/random';
|
|
|
|
|
|
|
|
|
|
|
|
axios.get(url)
|
|
|
|
|
|
.then(function (response) {
|
|
|
|
|
|
let clue = response.data[0];
|
|
|
|
|
|
|
|
|
|
|
|
vue.botMessage('Okay! Here is your question from the category "' + clue.category.title + '":');
|
|
|
|
|
|
vue.botMessage(clue.question);
|
|
|
|
|
|
|
|
|
|
|
|
vue.lastMessageData = {
|
|
|
|
|
|
isTrivia: true,
|
|
|
|
|
|
answer: clue.answer
|
|
|
|
|
|
};
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(function (error) {
|
|
|
|
|
|
vue.botMessage("It's not a good time for a quiz.");
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
this.updateStorage();
|
|
|
|
|
|
},
|
|
|
|
|
|
startJeopardy() {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
let url = 'https://jservice.io/api/random';
|
|
|
|
|
|
|
|
|
|
|
|
axios.get(url)
|
|
|
|
|
|
.then(function (response) {
|
|
|
|
|
|
let clue = response.data[0];
|
|
|
|
|
|
|
|
|
|
|
|
vue.botMessage('Okay! Here we go. The category is "' + clue.category.title + '":');
|
|
|
|
|
|
vue.botMessage(clue.answer);
|
|
|
|
|
|
|
|
|
|
|
|
vue.lastMessageData = {
|
|
|
|
|
|
isJeopardy: true,
|
|
|
|
|
|
question: clue.question
|
|
|
|
|
|
};
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(function (error) {
|
|
|
|
|
|
vue.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 vue = this;
|
|
|
|
|
|
|
|
|
|
|
|
axios.post('/api/curlJson', {
|
|
|
|
|
|
url: 'https://some-random-api.ml/img/' + animal
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
|
vue.botMessage("Sorry, i can't find any good pictures right now 🙁" + emoji);
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
vue.addImageMessage({
|
|
|
|
|
|
body: emoji,
|
|
|
|
|
|
src: response.data.link
|
|
|
|
|
|
}, true);
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
rsaRandomAnimalFact(animal, emoji = '😄') {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
|
|
|
|
|
|
axios.post('/api/curlJson', {
|
|
|
|
|
|
url: 'https://some-random-api.ml/facts/' + animal
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
|
vue.botMessage("Sorry, i can't think of any good facts right now 🙁" + emoji);
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
vue.botMessage(response.data.fact);
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
rsaLyrics(searchFor) {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
|
|
|
|
|
|
axios.post('/api/curlJson', {
|
|
|
|
|
|
url: 'https://some-random-api.ml/lyrics/?title=' + searchFor.replace(' ', '%20')
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
|
vue.botMessage("Hmm.. i just can't remember the lyrics, but i love that song! 🎵🎧");
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((response) => {
|
|
|
|
|
|
vue.addImageMessage({
|
|
|
|
|
|
body: "Here you go!<br>" +
|
|
|
|
|
|
"<br>" +
|
|
|
|
|
|
response.data.title + ' from ' + response.data.author + '<br>' +
|
|
|
|
|
|
'<br>' +
|
|
|
|
|
|
response.data.lyrics,
|
|
|
|
|
|
src: response.data.thumbnail.genius
|
|
|
|
|
|
});
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
},
|
|
|
|
|
|
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 & themes
|
|
|
|
|
|
getBootswatchThemes() {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
|
|
|
|
|
|
axios.get('https://bootswatch.com/api/4.json')
|
|
|
|
|
|
.then(function (response) {
|
|
|
|
|
|
vue.themes = response.data.themes;
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(function (error) {
|
|
|
|
|
|
console.log(error);
|
|
|
|
|
|
})
|
|
|
|
|
|
},
|
|
|
|
|
|
getReactions() {
|
|
|
|
|
|
let vue = this;
|
|
|
|
|
|
|
|
|
|
|
|
axios.get('/reactions/get').then((response) => {
|
|
|
|
|
|
response.data.forEach((reaction) => {
|
|
|
|
|
|
vue.reactions.push(JSON.parse(reaction.reaction));
|
|
|
|
|
|
});
|
|
|
|
|
|
}).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);
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|