Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Coding chatbots in node.js

KahWee Teng
November 26, 2016

Coding chatbots in node.js

Bots are a new way to interface with services and businesses. In today’s landscape, there’s Alexa, Facebook Messenger, Slack and more. Let’s see how we can code and test chat bots efficiently using natural language tools.

KahWee Teng

November 26, 2016
Tweet

More Decks by KahWee Teng

Other Decks in Technology

Transcript

  1. • @kahwee • JavaScript for the past 5 years •

    Work for Tremor Video in San Francisco • Responsible for We Build SG chatbot • Likes sushi
  2. @kahwee What is a chatbot? A chatbot is designed to

    perform a task via a chat user interface which is typically text enabled
  3. @kahwee Why make a chatbot? • Reduce proximity between customers

    and businesses • Think personal assistants such as Cortana and Amazon Echo • Think chat messaging interfaces such as Facebook Messenger and Kik
  4. @kahwee Why make a chatbot? • Businesses are competing on

    customer’s attention span over other businesses • ComScore found that average Americans devote half their app time to a single app.
  5. @kahwee @TODO List ! Receiving messages from chat service "

    Comprehending the user’s input # Responding to the user
  6. @kahwee { "object": "page", "entry": [ { "id": "309202066131176", "time":

    1479910134831, "messaging": [ { "sender": { "id": “1328417810563062" }, "recipient": { "id": “309202066131176" }, "timestamp": 1479910134741, "message": { "mid": "mid.1479910134741:99abab3941", "seq": 4, "text": "Hello How are you doing today?" } } ] } ] }
  7. @kahwee Using localtunnel and nodemon • localtunnel • https://localtunnel.github.io/www/ •

    Lets you test and develop locally • nodemon • Automatically restarts on change
  8. @kahwee “Book an appointment tomorrow at 4 PM” • The

    easiest way to determine the intent is to use rule-based filters on the current application • Example use case — Doctor’s appointment service • Only 2 main functions 1. getAppointments() 2. bookAppointment(datetime)
  9. @kahwee “Book an appointment tomorrow at 4 PM” We determined

    we need to use bookAppointment(datetime)
  10. @kahwee “Book an appointment tomorrow at 4 PM” • How

    do we get the parameter “tomorrow at 4 PM”? • Regex isn’t as straightforward any more • There’s A Package For That ™
  11. @kahwee Using simple NLP tools • We are going to

    use nlp_compromise which has a parts of speech (POS) tagger • https://github.com/nlp-compromise/nlp_compromise • A POS Tagger is a piece of software that reads text and assigns parts of speech to each word or other token based on both its definition and its context — i.e., its relationship with adjacent and related words in a phrase, sentence, or paragraph. (Wikipedia) There’s A Package For That ™
  12. @kahwee I have a pen Parse “I have a pen”

    with
 nlp_compromise const nlp = require('nlp')
 nlp.sentence('I have a pen').terms.forEach((t) => {
 console.log(t)
 })
  13. @kahwee I have a pen Person { whitespace: { preceding:

    '', trailing: ' ' }, text: 'i', normal: 'i', expansion: null, reasoning: [ 'lexicon_pass', 'is_person' ], pos: { Noun: true, Person: true, Pronoun: true }, tag: 'Person', honourific: null, firstName: null, middleName: null, lastName: null },
  14. @kahwee I have a pen Verb { whitespace: { preceding:

    '', trailing: ' ' }, text: 'have', normal: 'have', expansion: null, reasoning: [ 'lexicon_pass' ], pos: { Verb: true, Infinitive: true }, tag: 'Infinitive' }
  15. @kahwee I have a pen Term { whitespace: { preceding:

    '', trailing: ' ' }, text: 'a', normal: 'a', expansion: null, reasoning: [ 'lexicon_pass' ], pos: { Determiner: true }, tag: 'Determiner' },
  16. @kahwee I have a pen Noun { whitespace: { preceding:

    '', trailing: '' }, text: 'pen', normal: 'pen', expansion: null, reasoning: [ 'fallback' ], pos: { Noun: true }, tag: 'Noun' }
  17. @kahwee I have an Person { whitespace: { preceding: '',

    trailing: ' ' }, text: 'i', normal: 'i', expansion: null, reasoning: [ 'lexicon_pass', 'is_person' ], pos: { Noun: true, Person: true, Pronoun: true }, tag: 'Person', honourific: null, firstName: null, middleName: null, lastName: null },
  18. @kahwee I have an Verb { whitespace: { preceding: '',

    trailing: ' ' }, text: 'have', normal: 'have', expansion: null, reasoning: [ 'lexicon_pass' ], pos: { Verb: true, Infinitive: true }, tag: 'Infinitive' }
  19. @kahwee I have an Term { whitespace: { preceding: '',

    trailing: ' ' }, text: 'a', normal: 'a', expansion: null, reasoning: [ 'lexicon_pass' ], pos: { Determiner: true }, tag: 'Determiner' },
  20. @kahwee I have an Term { whitespace: { preceding: '',

    trailing: '' }, text: '', normal: '', expansion: null, reasoning: [], pos: {}, tag: '?' }
  21. @kahwee I have an const gemoji = require('gemoji') console.log(gemoji.unicode[‘']) {

    description: 'red apple', names: [ 'apple' ], tags: [], name: 'apple', emoji: '' } There’s A Package For That ™
  22. @kahwee Initial pass with nlp_compromise • Using nlp_compromise, • Parse

    “Book an appointment tomorrow at 4 PM” through nlp_compromise
  23. @kahwee Book an appointment tomorrow at 4 PM Noun {

    whitespace: { preceding: '', trailing: ' ' }, text: 'Book', normal: 'book', expansion: null, reasoning: [ 'fallback' ], pos: { Noun: true }, tag: 'Noun' }
  24. @kahwee Book an appointment tomorrow at 4 PM Term {

    whitespace: { preceding: '', trailing: ' ' }, text: 'an', normal: 'an', expansion: null, reasoning: [ 'lexicon_pass' ], pos: { Determiner: true }, tag: 'Determiner' },
  25. @kahwee Book an appointment tomorrow at 4 PM Noun {

    whitespace: { preceding: '', trailing: ' ' }, text: 'appointment', normal: 'appointment', expansion: null, reasoning: [ 'fallback' ], pos: { Noun: true }, tag: 'Noun' },
  26. @kahwee Book an appointment tomorrow at 4 PM _Date {

    whitespace: { preceding: '', trailing: '' }, text: 'tomorrow at 4 PM', normal: 'tomorrow at 4 pm', expansion: null, reasoning: [ 'lexicon_pass', 'lexicon_pass', 'Date-Preposition-Date' ], pos: { Noun: true, Date: true }, tag: 'Date', data: { year: null, month: null, day: null } } ]
  27. @kahwee Book an appointment tomorrow at 4 PM Returns “2016-11-21T02:00:00.000Z”

    Passed through chrono-node There’s A Package For That ™
  28. @kahwee Figuring out the date and time Use `chrono-node` const

    chrono = require(‘chrono-node') const parsed = chrono.parse('feb 23 to mar 2’) console.log(parsed[0].start.date()) // 2017-02-23T20:00:00.000Z console.log(parsed[0].end.date()) // 2017-03-02T20:00:00.000Z
  29. @kahwee General rules of thumb • Be succinct • Be

    friendly • Respect the medium • Handle errors
  30. @kahwee Be succinct • Mobile messaging apps are limited by

    space. The shorter the bot responses are, the better. • Remember emojis are valid responses too! ✅
  31. @kahwee Be friendly • Use pronouns like I and You.

    • Greetings, apologizing and thank you • Remember to greet back • It’s okay to say “Sorry I don’t understand” • Use active instead of passive voice. “Your flight has been booked” is not as good as “I booked your flight.” • Be humble and polite so people won’t be frustrated
  32. @kahwee Respect the medium Know what kind of response the

    messaging API supports. For example, Facebook Messenger supports: • Text • Emoji • Location • Buttons
  33. @kahwee Respect the medium • Format using “underscore.string” • toSentence(["jQuery",

    "Mootools", “Prototype"])
 // => "jQuery, Mootools and Prototype” • prune("Hello, cruel world", 15)
 // => "Hello, cruel..." There’s A Package For That ™
  34. @kahwee Respect the medium • Poncho uses a “Send Location”

    button that users can tap on instead of typing a city name or postal code in Facebook Messenger
  35. @kahwee Respect the medium • Use “ranka” for added expressivity

    • https://github.com/kahwee/ranka There’s A Package For That ™
  36. @kahwee Problems faced when building bots 1. Choosing what to

    build is hard 2. You are encroaching into a personal space such as Facebook Messenger. 3. Every chat messaging system is a medium that can have special characteristics hence different APIs
  37. @kahwee Conversational vs Structured text • Conversational text • Less

    predictable, potentially open-ended • Requires a complex rule-based system or machine learning capabilities
  38. We Build SG • Example of structured chatbot • Built

    by me and We Build SG’s API • Try asking about “upcoming events” to We Build SG
  39. @kahwee Thanks • Source code for the afternoon: • https://github.com/kahwee/ranka-jsconfasia

    • We Build SG chatbot: • https://github.com/webuildsg/bot • Ranka: • https://github.com/kahwee/ranka