diff --git a/.gitignore b/.gitignore index 6704566..c056d9b 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,6 @@ dist # TernJS port file .tern-port + +package-lock.json +.env \ No newline at end of file diff --git a/README.md b/README.md index 9a499a5..222a8d5 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,15 @@ When submitting your code, please answer the following questions by email: 4. How would you track down a performance issue of your bot in production? Have you ever had to do this? 5. How would you improve the Web1on1 APIs that you just used? + +## Answers + +1. I missed the part on using ngrok for the webhooks. Besides that I didn't realise I had to use the JSON objects directly in the ```ask()``` (or similar) function calls +2. Time estimate: +- 4 hours. For now it was 50/50 on learning the bot structures and implementing it. I would have added a calendar object and also tests for the bot it self. In my opinion the structure for asking time & date first before location isn't smart. When a calendar from a location will be added in later, you will have to change the structure (as given in the assignment). Besides that messages appear in different orders than given, probably because the calls are async. Not sure if there's a solution in the Bot API already (coulnd't really find it that fast). Same for when a chat is created with the bot, it does the action 2/3 times in a row (e.g., will 2/3 greet you). +3. I'm suprised of the fact that creating a bot isn't that hard. Most of the features are already existing, "the foundation". +4. Normally I would try to reproduce the problem first. Preferably with the same environment, for example running the app locally as well. After that it's pretty much debugging and checking which parts are struggling. +5. It's pretty clear already, but maybe add small examples (or results) of what certains action/types/etc will do for you. Instead of having to test it first. + ---------- #### Thanks for your time, we look forward to hearing from you! diff --git a/bot.js b/bot.js index b2c86c2..34cda41 100644 --- a/bot.js +++ b/bot.js @@ -1,15 +1,165 @@ const ChipChat = require('chipchat'); -const bot = new ChipChat({ token: process.env.TOKEN }); +const dotenv = require('dotenv'); +dotenv.config(); -// conversation assigned to the bot -bot.on('assign', async (m, c) => { - console.log('', m.text); - c.say('Hello agent'); -}); +const APPOINTMENT_TYPE = { + SOMETHING_ELSE: "0", + USED_CAR: "1", + NEW_CAR: "2", +} -// contact chat message (in a contact conversation) -bot.on('message.create.contact.chat.contact', (message, conversation) => { - conversation.say('Hey, consumer', { role: 'agent' }); -}); +const LOCATIONS = { + AMSTERDAM: "0", + ROTTERDAM: "1", + DEN_HAAG: "2", +} -bot.start(); +class VideoAppointmentBot { + /** + * Starting the video appointment bot + */ + static start() { + const bot = new ChipChat({ token: process.env.API_TOKEN }); + + bot.on('message.create.agent.chat', (message, chat) => { + chat.say({ + text: "Hi, I'm your Virtual Assistant. I will help you schedule a video call appointment in 4 quick steps.", + meta: { + botstep: 1 + } + }); + + VideoAppointmentBot.stepOne(chat) + }); + + bot.start(); + } + + /** + * First step of planning a video appointment + * + * @param {*} chat, current state of the chat + */ + static stepOne(chat) { + chat.ask({ + text: "1/4: What would you like to discuss in our Video Call?", + actions: [ + { + text: "Used car", + payload: APPOINTMENT_TYPE.USED_CAR, + type: "postback" + }, + { + text: "New car", + payload: APPOINTMENT_TYPE.NEW_CAR, + type: "postback" + }, + { + text: "Something else?", + payload: APPOINTMENT_TYPE.SOMETHING_ELSE, + type: "postback" + } + ], + meta: { + botstep: 1 + } + }, VideoAppointmentBot.stepOneResponse); + } + + /** + * Second step of planning a video appointment + * + * @param {*} chat, current state of the chat + */ + static stepTwo(chat) { + chat.ask({ + text: "2/4: Thank you, please choose your preferred location.", + actions: [ + { + text: "Amsterdam", + payload: LOCATIONS.AMSTERDAM, + type: "postback" + }, + { + text: "Rotterdam", + payload: LOCATIONS.ROTTERDAM, + type: "postback" + }, + { + text: "Den Haag", + payload: LOCATIONS.DEN_HAAG, + type: "postback" + } + ], + meta:{ + botstep: 2 + } + }, VideoAppointmentBot.stepTwoResponse); + } + + /** + * Third step of planning a video appointment + * + * @param {*} chat, current state of the chat + */ + static stepThree(chat) { + + } + + /** + * Handling response of the first step + * + * @param {*} message, message input from the contact + * @param {*} chat, the current chat state + */ + static stepOneResponse(message, chat) { + switch (message.text) { + case APPOINTMENT_TYPE.USED_CAR: + chat.say("Chosen: Used car"); + VideoAppointmentBot.stepTwo(chat); + break; + case APPOINTMENT_TYPE.NEW_CAR: + chat.say("Chosen: New car"); + VideoAppointmentBot.stepTwo(chat); + break; + case APPOINTMENT_TYPE.SOMETHING_ELSE: + chat.say("Chosen: Something else"); + chat.ask({ + text: "What would you like to talk about?", + meta: { + botstep: 1.1 + } + }, () => { + VideoAppointmentBot.stepTwo(chat); + }); + break; + default: + chat.say("Something went wrong!"); + } + } + + /** + * Handling response of the second step + * + * @param {*} message, message input from the contact + * @param {*} chat, the current chat state + */ + static stepTwoResponse(message, chat) { + switch (message.text) { + case LOCATIONS.AMSTERDAM: + chat.say("Chosen: Amsterdam"); + break; + case LOCATIONS.ROTTERDAM: + chat.say("Chosen: Rotterdam"); + break; + case LOCATIONS.DEN_HAAG: + chat.say("Chosen: Den Haag"); + break; + default: + chat.say("Something went wrong!"); + } + } +} + +// Starting the bot +VideoAppointmentBot.start(); diff --git a/package.json b/package.json index 68401a1..8fb621b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "dependencies": { - "chipchat": "^0.1" + "chipchat": "^0.1", + "dotenv": "^10.0.0" }, "scripts": { "start": "node bot.js"