An assignment I’ve seen several Computer Science teachers give their students is to write a chat bot. I thought that could be cool to do with my students and I always run though assignments myself before assigning them to a class. So, for my take on the assignment, I decided to make a chat bot that speaks Thai. For the code, check it out on codepen. Note that the bot only knows the Thai script, phonetic transcription won’t work. To chat with it visit this page or try it out below:
There are lots of Natural Language Processing (NLP) tools out there for English but there aren’t as many in Thai. I took a pretty naive approach to my implementation since there are several challenges in NLP unique to Thai (even tokenizing words is nontrivial since there aren’t spaces between words in the Thai script).
The relevant function in the code is the one that determines what the bot’s response will be to what the user types. To start, lets just have it respond with ไม่เข้าใจ (mai kao jai – I don’t understand) to anything said. Our bot just arrived in Thailand and doesn’t know any phrases other than this.
function chatbotResponse() {
botMessage = "ไม่เข้าใจ";
}
Alright, we have something going. Next, let’s teach our bot some basic greetings. How do we know if someone is greeting us? We could check to see if the user includes “สวัสดี” or “หวัดดี” anywhere in their message. That covers formal or informal and whatever articles someone may add at the end. It would catch user messages like “หวัดดี” (wat dee – hi) and “สวัสดีค่ะ/ครับ” (sawatdee ka/khrab – Hello) or as my first student tester entered: “สวัสดีจ้าาา” (sawatdee jaaaa – more colloquial way of saying hello in chat) Let’s respond with a random greeting such as สวัสดี (sa wat dee – hello) or สวัสดีครับ (sa wat dee khrab – hello). I’ve chosen to make my bot male so I’ll use particles like ครับ instead of ค่ะ. I’ll remember that going forward to stay consistent.
if (lastUserMessage.includes('สวัสดี') || lastUserMessage.includes('หวัดดี')) {
/* randomElement is a custom function to pick one of the words in the given list */
botMessage = randomElement(['สวัสดี','วัสดีครับ','สวัสดีครับ']);
}
Cool, now maybe we should give our bot a name. “Bot” seems appropriate, but let’s write it in Thai:
botName = 'บอท';
if (lastUserMessage.includes('ชื่อ')) {
botMessage = 'ผมชื่อ' + botName;
}
Again, บอท is male, so we used ผม (pom) for I instead of ฉัน (chan). Next, we should check if the user is asking how we are. Since Bot is a pretty chill guy let’s have him always give a positive response.
if (lastUserMessage.includes('เป็นอย่างไรบ้าง') || lastUserMessage.includes('สบายดีไหม') || lastUserMessage.includes('สบายดีมั้ย')) {
botMessage = 'สบายดีมากครับ';
}
Alright, we’re beefing up Bot’s vocabulary. How about another easy one, “Thank you” and “You’re welcome”. In Thai we might say thank you with either ขอบคุณ ครับ/ค่ะ (kop khun khrap/ka) or the more casual ขอบใจ (kop jai). We could respond with ยินดีครับ (yin dee khrap – you’re welcome) or ไม่เป็นไร (mai bpen rai – no problem/no worries), and of course we could always throw a ครับ (khrap) at the end to add some politeness.
if (lastUserMessage.includes('ขอบคุณ') || lastUserMessage.includes('ขอบใจ')) {
botMessage = randomElement([
'ยินดีครับ',
'ไม่เป็นไร',
'ไม่เป็นไรครับ'
]);
Let’s give our bot a useful feature. How about telling you the time if you ask? กี่โมง (gee mong (long ‘o’ sound)) is how to ask what time it is so let’s check if the user writes that. And if so, we’ll print out the current time.
/* what time is it? */
if (lastUserMessage.includes('กี่โมง')) {
botMessage = new Date().toLocaleTimeString();
}
Now, how about a sense of humor? When chatting in Thai, it’s common to see the number 5 (pronounced ‘ha’ in Thai) used for laughter. Maybe 555 or even more 5’s if it’s really funny. So, if we see the word ตลก (talok – funny) in the user’s message let’s output a string of 5’s (anywhere from 3 to 9) to indicate Bot’s amusement.
if (lastUserMessage.includes('ตลก')) {
let extra_fives = Math.floor(Math.random()*6);
botMessage = '555';
for (var i=0; i < extra_fives; ++i) {
botMessage += '5';
}
}
Alright, let’s try something a bit more complicated. Let’s try to detect if the user is asking a question and respond either positively or negatively. ไหม (mai, also written as มั้ย) is a particle added to the end of a statement to make it a question. i.e.
เอาไหม (ow mai – do you want it?)
or
ไปไหม (pai mai – do you want to go?)
To respond positively we just chop off the question particle and use the verb i.e.
เอา (ow – I want it)
or
ไป (pai – let’s go)
To respond negatively we still chop off the particle but also add a negation (ไม่ – mai, with a falling tone) in front i.e.
ไม่เอา (mai ow – I don’t want it) or
ไม่ไป (mai pai – let’s not go).
if (lastUserMessage.includes('ไหม')) {
let i = lastUserMessage.search('ไหม')
botMessage = lastUserMessage.substr(0,i);
let coinflip = Math.floor(Math.random()*2);
if (coinflip) {
botMessage = 'ไม่' + botMessage;
}
}
if (lastUserMessage.includes('มั้ย')) {
let i = lastUserMessage.search('มั้ย')
botMessage = lastUserMessage.substr(0,i);
let coinflip = Math.floor(Math.random()*2);
if (coinflip) {
botMessage = 'ไม่' + botMessage;
}
}
I won’t list every single thing I put into the program here but I’ve added more stuff to it. Feel free to chat with บอท to find more messages I’ve added. Or peek at the code. If you’ve got more suggestions for what to teach him, let me know!