Transcript for:
Creating an AI Hotel Chatbot Using Voiceflow

what's up my people welcome back so as you've seen in the title we're building a really extremely powerful AI Hotel customer support chatboard in the process we're going to be going through several functionalities in voice flow that will enhance the power within your voice flow chart boards enabling you to build chart boards that drive real impact so here's a demo so here I've deployed the chatboard on my local computer so I'll just click on the chat bubble and we'll get into it so the chatboard is able to handle General Customer Support over 8% of customer support inquiries handle booking of hotel rooms as well as suggesting local attractions that the hotel guests can visit whilst at the hotel so let's ask it some few questions so first of all is there a fitness center or gym at the hotel let us see yes we have a fully equipped fitness center available for our guests it is open 24/7 what are the checkin and check out times checking times from 3:00 p.m. and checkout is until 12:00 p.m. let us see can I request an extra bed for my room yes extra beds are available upon request please contact the front desk to make arrangements let's say I'm a social media guy and I need some Wi-Fi okay let us see is Wi-Fi available at the hotel yes complimentary Wi-Fi is available throughout the hotel for all guests and what is the Wi-Fi password so the Wi-Fi password is Hotel 2024 now let's say I want to make a booking right now okay I want to book a room certainly I'd be happy to assist with that what's your name that's my name proud of my African names by the way and my email what about my phone number there you go next kindly select the type of room you want to book so uh you can see there are several options over here junior sweet uh executive presidential standard room Delux all this so uh I'm an executive so let me pick the Executive Suite fit for purpose so here you can read through the description of the Executive Suite uh you can read through that all that so I don't bore you with the details but let's get into it so kindly mention the day you'd love to check in so I'll be like next week Monday awesome and how long do you plan for your stay for a week is good enough for this guy to just take a chill a bit so that is 6 nights is that correct yes your total amount will be 300,000 click the button below to pay so let's make the payment so you see the payment model pops up and we can proceed to make the payment so it's through bank bank authentication okay so let's authenticate there you go successfully booked your hotel room here's your booking ID so kindly check your email for details in regard to your booking so if I go to the CRM that's storing this booking details which in this case is air table you can be able to see that so you can see it here in our bookings table you can see booking ID uh 22 the customer name email their phone number that they stated the date they want to check so you remember we said next week Monday and if we check our calendar next week Monday is actually on 30th so it was able to capture that uh the number of nights which is six nights the room type the the status of their booking the payment ID and the amount they paid and if I go to my email address that I used to make the booking I can be able to see the booking details so here you have it can see dear M this is to inform on your recent booking at the hotel your stay starts on 2024 9030 for a total of six nights your room type is that and your booking ID is that thank you for choosing the hotel looking forward to seeing you regards now let's say I have just want to know if there are some fun places to visit whilst at the hotel so I can be like are there any fun places I can visit whilst at the hotel so you can see absolutely I can assist find local attractions near that you can see it's listed there and you can see some examples so you can see Nairobi National Museum giraffe Center and Nairobi National Park and if you want to let's say learn more about Nairobi National Museum you can click that and then you can read through the description uh that the museum is a treasure Trove of Kenya's reach I don't like reading all this but you can pause and read through it but now you're asking yeah this is all powerful and nice but how do I get into building one myself let me show you so we're building the chatboard using voice flow the most popular chatboard Builder out there so uh if you don't have an account go ahead and search voice flow.com register for an account then you'll arrive at your dashboard you can be able to import the exact template we're using for this video so Link in the description if you want access to the entirety of what we're going to be building so the template is available completely for free as well as the code that we're going to use so if we use any code within the video link the description for the GitHub repository so you can go and copy the code and use it for your project for free let's get into it so the chat starts with a simple greetings hi there I'm Alexa your AI assistant how may I help you today and you can see that I generated some variations of that so so that the chatboard Isn't So static then we capture the user's response and have the AI give a response to what the user asks so you can see this is a response AI step uh that's answering from information in the knowledge base and we'll go into the knowledge base to see what's there but you can see it's a simple prompt provide a relevant response the customers inquiry based on info in the knowledge base then we are to on the not found path just in case it doesn't get an answer we able to handle it then we override the prompt settings we pick the GPT 3.5 Tabo as the model uh we lower the temperature to 0.1 uh especially when you're giving responses with the AI and you want it to be uh you can be able to predict the answers it gives bring down the temperature to as low as possible you don't have to increase the temperature cuz the AI will be creative cuz temperature means being creative so if you wanted to give precise answers based on info in the knowledge base bring down the temperature as low as possible prefer I believe and bring it down to zero I just wanted a bit of creativity a bit so set your maximum tokens then the system prompt okay so you can pause and read through it but I won't go through much of it so you give it a roll the task some specifics in regard to the task some context on in the in terms of the hotel that we are working with then you can give it some notes down here if you imported the template you have this so don't worry so once AI gets an answer uh it's going to respond then it will ask is there anything else I can help you with then we'll have some buttons If they click yes we tell them sure go ahead then we capture their response so we'll send them back to the block which is capture the user query so if we just click on that to lead us to this capture block okay so you're seeing that but if they say no we'll just say if you have any more questions feel free to reach out I'm here for you okay then we end the conversation otherwise if there's a no match so instead of clicking either of the buttons they type in a statement into the chart widget just forward whatever they've asked into the response AI step for it to handle giving a response to the user so in case they don't click on the button but they continue just to ask another question the response AI step will give a response to the user okay so and in case the response AI doesn't get an answer we'll follow the not found path and we'll say sorry I don't have a response at the the moment is there anything else I can help with some buttons again just like initially if they say yes we take them to the block of sure go ahead and that block is this one over here then if they say no we take them to the block of AI is done with the questions and this block is this block you're seeing over here so you're noticing that all my blocks are named so this is good practice I propose to you just to ensure that you you can easily build your chart boards and your canvas Isn't So cluttered why is that cuz if I my block I don't have to uh drag the flow all the way across the canvas to go to a specific block I can simply just do an action so for example I delete this so let me delete that then I can simply just go to actions go to block then I can select the block that I want to go to so you can see over here the blocks that I've already named if I didn't name them you'll see new block one new block two and you don't really know what this block was specifically doing so if you name them you're able to to go to them easily okay so that's a customer support part uh it's quite simple so you can be able to uh go through that but now let's go into booking a room so this section has a lot of uh learnings that you can be able to get especially with rendering things dynamically or working with the function calling or even custom action block so it's quite comprehensive to pay attention so let's go to that workflow which is Booker room workflow so this workflow is being triggered by an intent and that intent is the book a room intent so if you go to the intent to see what what kind of utterances are triggering this intent we can be able to see that so I'll go there click edit the intent then you can be able to see this auka room intent this is the description which doesn't really matter much unless you're using llm intent classification so in this case you're using nlu intent classification which is free less accurate compared to using llm intent but is good enough for this case Okay so that's why this is a critical part providing the kind of statements that trigger this intent so you can pause and read through them for example can I reserve a room for next week are there any vacancies for the weekend and so on and so forth so I'll close that so once this intent has been triggered we'll get a response AI step to give a response to the statement the user has just mentioned before this okay why are we doing this is so that the chart conversation is in perfect cohesion with what the user has just stated lastly okay so you can be able to see we're passing in the last atance and in the pr settings we say you're a helpful enthusiastic Hotel assistant your task is to give a relevant response that is in perfect cohesion with the chart history conversation okay so if the user said that I want to book a perfect room for the weekend what do you guys have the AI can be able to give a response saying uh definitely I can help you get a perfect room for the weekend and you're seeing that statement is in perfect cohesion with what they've said so that's why we want a a cohesive chat conversation okay okay so you can pause and read through the prompt itself but an important part is after giving that response that is in cohesion with what the user has stated we ask for their name so you can see here for example in the examples you can see the user say do you have any rooms available for the upcoming conference yes we definitely have some rooms available for the upcoming conference I can help you in Booking the perfect room for your stay first of all what's your name so in any case we need to end the statement by asking for the name and that's part of the instructions okay so then we'll have a capture block that captures their name saves it to a variable called customer name then we ask for their email then we capture their email using what we call entities so what entities are is for example if the user says my email is mutiso gmail.com it will just pick mutiso gmail.com as the email we don't have to capture the entire response okay so you can see here you can either capture the entire user reply or capture a specific part of it that we so need so that's where entities come in handy so I went ahead and created a new entity called it email so for that you can create new entity give it a name of email and choose the data type as email so you see that's already built into voice flow so if it captures the right email it will proceed and save it to a variable called customer email so you seeing in the actions the action is set customer email to that email address okay but if they input a wrong email for example mutiso art and they don't complete gmail.com that's a wrong email so we need to tell them to State the email again so for that we have a no match step okay that goes ahead to ask kindly enter the correct email address then we forward them back to that capture block for them to input it correctly okay so what that's in place we ask for their phone number capture their phone number this is also an entity of type number so that if they say my phone number is 07 blah blah blah it will just capture 07 blah blah blah so that's in place once it gets the correct phone number it saves it so this is an action of setting the customer phone to that phone number that's been captured okay then after saving that variable it forwards the flow to the block which is for them to pick their hotel room okay so this block is called pick hotel room and we'll go to it so that you can see it okay but in case they imput the wrong phone number we have a no mat step over here so I went ahead and clicked no match added a path for the no mat then we're able to handle that okay so if I exit this you can see here we ask them kindly enter the correct number then we F the flow back to the capture block so now let's go to the pick a hotel room so if I click on that and go to that block it's within the same workf flow you just uh bit tided it up so first you ask next kindly select the type of room you want to book and for this to render the type of rooms we're using a function block to handle that so to see the kind of rooms available we'll go to our air table which is over here then you go to room availability in this we able to see the different room types that are available and the number of available rooms that are available for each of those room types so you can see standard room has 10 available rooms deluxe room has five and so on and so forth if either of these rooms had zero available rooms they wouldn't be displayed back to the user and I'll show you how we handle that using the function so you can see number of available rooms the image to represent that room type the description so you can see the description of a standard room and so on and so forth and the price per night okay so let's go back to the function over here and let's see how we're able to render this dynamically so the function itself has some input variables output variables and paths okay so the only input variable that we need in this case is the air table token that gives us access to the air table API to be able to retrieve those room types okay so this air table token you can just go to your air table over here click on your profile then go to build a hub so I'll just drag this over here so once you land over here you want to create a new access token that gives you permission to access the API so give it a name whatever it is you want to name it give it some Scopes so this is the level of permissions that you want to give access to so for example if you only want to retrieve information you'll only give it read permissions if you want to create new records or update a record you'll also give it right permissions but normally I just like to give it all scope so that in in case later on I want to access a specific functionality I can always do it using that one access token so go ahead and add the Scopes that you want you can add all of them then attach a base so this is the database you want to use in this case mine is Hotel then you'll create the token it will pop up with your access token copy it and save it somewhere cuz you'll use it within your voice flow you can just come in and paste it in directly to your voice flow so if I go to the workflows over here in the function itself you'll click on it then you'll paste in your access token over here okay so that is critical so let's go back to the function so standard procedure is when you start your function always obtain all the variables you'll be using so we obtain our air table token then we want to make an API code to retrieve the room types okay so this is the function that does that so try making an API call to retrieve the room types if in any case you run into an error be able to capture that error down here so I'll scroll down here we'll capture the error eror then follow through the path of error so this is how we exit from the function we use the return keyword exit the function then we pass to the path of error which is over here so we explicitly State our paths success error or no room selected okay so once we pass through that path we want to send back a debug message so you can be able to know why isn't it working okay so we'll turn a trace off type debug and the debug message is error retrieving available room types okay so if you're not familiar address is whatever is being rendered into the chatboard if the AI responds with a statement like hi I'm zaadi here to help you that's a statement which is a trace of type text if it renders some buttons that is a trace of type Choice okay but in this case this is a test of type debug which when you run the chatboard within your voice flow canvas you normally see some small uh messages in gray that tells you what's happening in the background so that helps in debugging but once you deploy the chart Bard you can't see it remember in the demo you don't see those small messages okay so now let's assume everything's working okay so try uh doing this API call okay so first of all we'll create an air table formula that will filter and get only the available rooms that have number of available rooms not equal to zero that means that that it has more than zero available rooms let's say one two or three available rooms okay so then we make an API call Okay so so await fetch then getting this URL we're able to get let me just expand this so this URL you get from Air table documentation which is just so awesome so you go back here to build a hub go to developer docs scroll down till you see web API API docs click on that scroll down till you see the database you want to access which is in in this case Hotel then you want to click the table that you want to access in this case is room availability table so we'll click on it click list records then you want to copy this URL as is so the entirety of it you can copy the entirety of it go back to your voice flow and paste it in there okay so you come and paste it over here okay but I also suggest you don't copy the entire URL just copy till this part so let me just show you just this part over here okay till where you see the question mark okay so copy that come back to your voice flow paste it in there then you'll have question mark so this is where you're passing the parameters filter by formula and we pass in the formula we just passing over here and notice I didn't mention but this formula itself we want to encode it okay so we are using this inbuilt JavaScript function encode URI component that encodes this uh formula into the URL okay so that's critical anytime you're passing in a variable into your url when you're making an API call that variable has to be encoded otherwise it won't work okay so the request type is a get request cuz we receiving information then we passing our table token for authorization then we capture the response and transform it into Json so that we able to work with it then we check if the Json response is not empty or the Json response do records is not empty that means it was successfully retrieved so we're able to continue otherwise if this is empty means it wasn't able to retrieve the room types we're able to come down here and follow the else path and we exit the function so return exits from the function we pass to the path of error then we return a debug message saying no room type records found okay so then we pass in the response so that we're able to use it for debugging purposes okay otherwi if everything is okay we're able to render the room types back to the user in form of a carousel so we'll handle that so first we create an empty variable uh it would be an empty array where we'll insert our card object so each single card within the Carell is represented by an object and we'll able to see that object how it's structured okay so this function I'll get into it is just inserting commas within the price itself and you'll see how we handle that so first of all we want to Loop through each record of the room types returned then we want to uh push an object uh that represents a single card okay and this object will be inserted into our cards array over here and a single card has an ID has a title of that card has a description okay has an image URL and has some buttons okay okay so in regard to the detail of how we render this I've done a full comprehensive video on how we able to render things dynamically so for that just go and visit my YouTube channel you'll see a video on how to render things dynamically into your voice chatboard it's quite comprehensive and you'll understand the nitty grees on how this works okay and why we do the things that we're doing over here so that's very critical go and check out that video so first of all in the title we checking the Jon response we want to get that specific record which is in that specific index that we are in in the for Loop then we want to access the fields but specifically the room type so that will be the title of that card okay then the description we want to say price per night is Kenya Shillings then we pass in that specific price so first of all we get the price through this specific section of the code which gets the price per night then we pass that price to this function which is number with commas and this function just inserts commas every three zeros so they are thousand has one comma a million has two commas so we want to insert the commas accordingly then we have the image URL uh we just obtain it from Json response. records we want to access that specific record the fields but specifically the image okay then we have some buttons it only has one button to select that room type so the button name is Select okay then this is the request that will be sent to the voice flow run time when the user clicks on that specific button so if let's say three room types are displayed each of them has a button called select if I select uh let's say the first room type an event will be sent to the voice flow rant time so that we're able to obtain the specific room type they have selected okay so this is the request that is sent back okay so the type of request is default path and this is critical cuz uh once we exiting from the function will follow through the path of default path and I'll show you how that works just wait so in the payload we'll pass in the room type the room description and the room price which will use within the chatboard flow uh from this function okay so once we have created all the cards for the room types we want to now exit the function and we want to return some traces which is a carousel okay so we'll return a trace and the trace is of type Carousel and in the payload we pass in which is a layout of car cell and the cards we just created so this cards is the cards that we created over here okay then this is critical so pay attention so exiting from the function you can be able to exit two ways okay there's the next one command which is what we have been used to using over here where it only has one uh argument which is path but there's the next manyu command Okay so the next manyu command ensures that we only exit from this function once the user has interacted with something within the function so for example in this case we only want to exit from this function once the user has selected a specific room type okay so that we able to know uh which room type they've selected okay so that's why we have the next manyu command which has three properties okay so pay attention here it has the listen property set to True which means we want to pose uh once the function has been executed to wait for the user to make an interaction with the chatboard so that that event is sent to the voice flow run time and we're able to use it to decide on how we're able to continue with the flow okay so listen property set to two means pause after executing the function pause to wait for the user to let's say send a message or click on a button just for them to interact with the chatboard for us to continue that is critical so then we have the two uh property which takes in an array of conditional uh events okay so a condition takes in two properties an own property and a property so this on is like the if statement check if the event type is this if that's the case follow this specific path okay so this path is in the desk property and this is the paths that we explicitly stated if I minimize this you can see our paths over here so this is the path that we are passing through over here but now you're wondering we only have one condition which is if the event type is default path why is this is cu in either way whatever room type they select will just flow through the same path but why we're using the next manyu command is so that we pause and wait for them to select then whatever they select will be passed on through this payload so that is the critical part so even if the path will follow through is just one path which is default path we want to pause and get in this payload okay but in actual sense there are sometimes where you'll have several conditions over here where the event type first of all let's say this is default path the next one is default path one the next one default path two depending on the scenario that you're working with at that moment okay so then we have a default two property which states that if none of these conditions that have been stated here are met uh follow through the path of No Room selected okay so why is this is in case the user doesn't select a specific button for a specific room type so in this case they actually just typed in a statement okay we want to float through the path of default to means they didn't select a room and that path is no room selected okay so and the rest of this is just error handling which we have already touched on okay so now let's move on but you can see I've said it's best practice to render the carousel or buttons via the custom action block due to global listening issue so this is is critical I just wanted to render it using the function block to show you that this is a possibility but in real sense I'd have used the custom action block and a JavaScript block I've already done a video on this on how you can use the custom action block uh to render things dynamically which I think I've already mentioned but you can go and check out that video why is this is using the custom action block it has a feature so let me just drag it out over here so here in the custom action block there's this feature if I click over here you'll see use Global listening and what this does is once we have rer the car cell and the chart conversation continues back and forth with the user the user can always scroll scroll back up to where the carousel had been stated and they can be able to select a different Carousel or a different card or a different button so it enables the chatboard to be more forgiving in case the user selected the wrong room type they can always scroll back up and choose a different room type which is impossible when you use the function block to render it dynamically so that is critical okay and I'll show you how we able to use this custom action uh when we are rendering the local attractions so this is critical okay so once we have rendered the room types successfully we'll flow onto this JavaScript block which just obtains uh whatever that the user had picked so the room they selected the description of that room and the price of that room so you can see how we able to get that that is in the last event. payload do room description and what is the last event I think I already showed you that so let's go to the function you can see here the last event is this specific request over here so able to see it there so whatever button they click uh this is the request that will be sent so we're doing last event do payload do room type okay so that is critical then over here we render the room description just in a text message then we move on to for them to pick the start date of their stay okay so in case there was an error rendering the room types we'll just Flo through this path render a message saying error then we end the conversation in case they didn't pick uh a specific room will F them to the response AI step that was in the home workflow that we had over here okay this means they actually typed in a statement or a question the AI can respond to them okay but in case they uh pick a room so now we flow on to pick the start date which is just over here so kindly mention the day you'd love to check in we capture their response then we have a JavaScript block over here which sets the current date so we'll use this current date to determine the exact St date okay so for example if the current date is 25th of September and they say uh I want to check in tomorrow the AI can be able to know that tomorrow is 26th so that's why we are setting the current date over here so this code does that then we have a set AI step over here which extracts the date so you can read through the prompt your a date extraction system your task is to analyze the entire conversation history to determine whether it contains a specific date all that so then we provide the current date so you can pause and read through the prompt but the point is it will be able to analyze the chart conversation and get the specific date the user has mentioned then we'll give it some examples down here so it's a long prompt but if you're using the template you already have it okay so then we give it the chart history conversation which is by default available in the VF memory variable so then we save whatever the AI determines as a date to a variable called captured date okay then we move on to another set AI step that converts that date into ISO format which is this format that you're seeing over here where it's the year four digits two digits for the month and two digits for the day so we're able to handle that then we save it to a variable called ISO date okay then we move on and ask them how long they're planning to stay capture their response okay then we move on to a set AI step again to extract the duration okay so in case they said that I want to check in tomorrow then they say I want to stay for a week that is 7 days and that is 6 nights okay cuz the last day they don't sleep okay if they say I want to check in tomorrow then the AI asks how long do you plan to stay and they say I want to stay till the 3rd of October the AI can be able to calculate how many nights are in between the third of October and the 26th of September okay so that is critical so this prompt does that okay so let me just open it this prompt does that so you can pause and read through it okay so you see for example here the user says from 20th May to 26th May the assistant will say those are five nights and it's only to return the number of nights and that only okay and save that to a variable called number of nights cuz we'll use this number of nights to calculate the price they ought to pay for their stay okay so next thing we confirm the number of nights so that is six nights is that correct so that is five nights is that correct Okay then if they say yes we move on if they say no we say sorry for the confusion kindly State how long you're planning to stay then we capture the stay duration again so this block is just this one over here okay so capture their response again so then next we have a JavaScript block that's able to calculate the total amount they ought to pay so you're seeing that's the number of nights times the room price okay then we insert commas within the amount so that we can render it back to the user then we save that amount to a variable called total amount print so you're seeing we're passing in the total amount okay to this function called number with commas okay so that inserts the commas within the amount okay then next you tell them your total amount will be Kenya Shillings whatever it can be 300,000 200,000 click the button below to pay then when they click on the button it takes them to this custom action block which pops up the payment model if you remember in the demo so this custom action extension has a custom action name of xor pay and this is what will trigger that specific extension okay let's go to the HTML file where we render this so that you can see that in action so you're seeing this is the HTML file just a simple HTML file then this is a script code that we get from The Voice flow integration tab then the only thing we change is changing this to type module so that we can import our external modules okay this type module enables us to use the import keyword okay why is this is because we have our extensions in this Javascript file called extensions. JS which I suggest this is the best way to create your extensions create your extensions in a different file so that you don't clutter your index. HTML with too much code cuz you could as well just all this extension code would have it within our index HTML file within this script tag okay then we just insert it in accordingly but it will be too cluttered so we create the extension in our extensions. JS then we export it uh insert it into our HTML file okay so let's go through the extension so I already did a video on working with extensions you can go and check it out everything you need to know on creating and working with chart widget extensions it's quite comprehensive go and check that out okay so here's the name of the extension the extension type can either be effect or response response means that we want to render something within the chart widget effect means you just want to perform an action not necessarily render something into the chart widget okay in this case the action is popping up the payment model that payment model isn't rendered within the chart widget that's why we use uh extension of type effect okay then over here we check the trace type that's been sent from The Voice flow run time does it have xcore pay as the custom action name if that's the case that means this is the extension we are trying to trigger and that's how you see xcore pay is the name that we gave to the custom action so that we can trigger that specific extension okay so then we want to pass in this effect uh we don't need this parameter of element this would come in handy if we were using uh the response extension okay then uh going into the nties of this extension you can go and check out did a video on integrating payments into the voice flow chart board so go and check that out but the critical part is once the user has made a successful payment we want to return the payment ID back to the voice flow uh chatboard okay so that's why this is the code that does that okay so you see we send an interact event back to voice flow pass through the path of payment complete then we pass in the payload the payment reference number that we got from uh payack which is in this case the pent provider then back in the index HTML once we import the extension as is we pass the extension to the voice flow chart board this way so you have an assistant property and the assistant we pass in the extension and we pass in the extension we want to use so back here in the voice flow you can see in the custom action we have only one path and that path is payment complete which you remember if if I go back here is the path we passed through once the payment has been successfully done okay then we toggle stop on action ction which means only proceed with a chatboard conversation once they've made the payment okay the next here we have a JavaScript step just to obtain the payment ID from the last event do payload do reference number and the last event is this last event okay do payload do reference number okay then now here is a function to save the booking details so you can see it takes in some several variables but let's go into the function itself so it text in some input variables the amount paid customer name email phone the date they want to start number of nights the room type the payment ID and the air table token so has to call the database and add that record okay then the output variable is the booking ID of the record created within air table okay so first standard procedure let's just expand this is to obtain all the variables we'll be using okay then we want to make an API call to air table which is a post request so in the headers you want to pass in the access token for authorization then we want to say that the content of the book body is Json data and you can see that's why in the body itself we want to turn this into a Json string okay and pass in the fields that we want to add to the record and the fields are customer name email all that based on what we imported okay then once that's been done successfully uh we want to obtain the response turn it into Json so that we can work with it if the response Json is not empty or response g. ID is not empty means the record was created successfully then we can have handle that accordingly so if it turn into an error this will be empty therefore we can be able to handle that so else if that's a case we want to exit from the function pass through the path of error then we return a debug message saying error creating the new booking records then we passing the response Json error. message okay and also in any case if any error runs within the function able to handle that error through this block so we have a catch block that captures the error exit to the path of error then return the debug message accordingly passing in the error message okay so now let's assume everything is okay we want to send an email to the customer with their booking details and for this we use make.com for that so you can see we're making an API call to make.com okay and let me just show you the me.com scenario so here is the scenario itself it's just a simple scenario that has two modules okay so the first module is the trigger and it's an instant trigger which runs the scenario when data comes through okay so it's always waiting for when data comes in through this specific web Hook is when it will send the email okay so there are two trigger types instant trigger and uh polling trigger polling trigger is one that is Waits every let's say 5 minutes or 15 minutes for it to check if there are any changes so that it can run the scenario but in this case it's an instant trigger that runs immediately data comes in you can see the web hook itself okay so we copy this web hook and go and paste it within our voice flow function okay and the email so this email module is what will send the email okay it takes in and sends in the email to that specific customer email we get from the API call okay then it has a subject line of hotel booking the content type is HTML so that we can use HTML tags like this one okay so it says Dear customer name let's say dear mutiso this is to inform on your recent booking then you pass in all those details accordingly okay then going back here so we paste in that webbook URL over here then we send a post request okay then the content type is application SL Json we don't have any authorization or access token so that's why we only have one headers then we pass in the data we want to pass through to make.com okay so then we check the email response the status text is okay if it's okay means email was sent successfully so we can exit the function pass through the path of success then we want to return the output variable tables which is booking ID and that's we get in the booking ID of that specific record from Air table okay but if the email response status text is not okay means it wasn't able to send the email we're able to exit the function pass through the path of error then we send in the debug message of error sending emails then we pass in the email response for debug purposes okay then this part we have already handled for uh handling the errors okay so let's go back to the workflow so if there's an error or saving the booking details we'll just say sorry you're having trouble saving your booking details kindly try again later then we take them to the block of any further assistance okay but if everything was successful we say successfully booked your hotel room here's your booking ID kindly check your email for your booking details okay is there anything else I can help you with if yes we take them to the block where it asks sure go ahead then it captures the response for the AI to continue with the conversation otherwise if they say no we just say if you need any further assistance don't hesitate I'm here for you then we end the conversation okay so that's the booker room functionality okay now let's go to the local attractions functionality which suggests some fun places the guest can go to whilst at the hotel so this workflow does that so what triggers this specific workflow is the local attractions intent so if I go to the intent itself to see the kind of statements that trigger it I can be able to see that so you can see Trigger this intent when the user expresses interest in knowing any fun activities or local attractions surrounding the hotel then if they say statements like can you recommend any interesting local attractions what are some popular tourist Sports nearby and so on and so forth okay so if that's the case uh just like initially we want to the AI to give a response that is in cohesion with what they've said Okay so this response on AI step does that and if go to the prompt settings you can see it's a quick one you can read through that you're a hotel assistant your work is to acknowledge that you can assist the user in finding local attraction they can visit remember that the local attractions are already set and will be displayed below the message you respond with therefore don't ask them to provide any further details so that was some cautioning I'm giving the AI while I was practicing with it I saw it was messing up a bit then we have a function block to retrieve the local attractions okay so let's go to it so it takes in the air table token okay then you make an API call to the local attractions endpoint it's a get request then we pass in our access token transform the response that comes back from the API into Json then we check if that response is not empty that's a case that means successfully retrieved the local attractions so we want to exit the function flow through the path of success then we send back the local attractions through this variable so you're seeing in the output variables you have local attractions so you want to set it to the records that we get back from the API call okay else if the Json response is empty means that was an error we exit the function pass through the path of error then send back this debug message same case to if there's any error within the function we can pick it up and send it back to the developer through a debug message okay for them to debug it back to the workflows so if it's successfully retrieved the local attractions will move on otherwise we'll just say error while receiving local attractions then we end it okay so now this JavaScript block is what will help render the carousel dynamically the carousel containing the local attractions so you remember I told you there are two ways you can render things dynamically into your voice flow chart board using the custom action block or using the function block the function block is what we used to render the room types but in this case I told you that it has a limitation of it's not forgiving such that if the user selected the wrong room and they continued with the chart conversation they can't scroll back up and pick a different room okay but with this case using the custom action block they can do that okay so this JavaScript step does that kind of like what we already used using the function block we get the local attractions and turn it into Json so that we can work with it create an empty cards array then we Loop through each single local attraction then we create a card for it kind of like what we already did so I won won't go to the details then you create the payload that will render the carousel dynamically and you'll see where we'll insert this payload okay so then we turn it into a string cuz the custom action block body only accepts a string and I'll show you that so uh next after this we go to a custom action block custom action block has a custom action name of carel which means means whatever Trace you're trying to render using this custom action block is what you'll pass in as a custom action name so if you're trying to render some buttons this will have it as Choice okay if you're trying to render text you'll have this as Chace of type text otherwise in this case we want to render Carousel so you'll have that as Carousel that is critical if you misspell Carousel it won't work then in the action body passing that payload and this is why this has to be a string so that's why we were stringifying that payload then we only have one default path so in any case once we display the local attractions and they pick either of the local attractions we flow through one path okay and I think I didn't touch on that in the JavaScript over here when we R the carousel we have some buttons and that button has a button if they want to learn more about that local attraction okay so in the request that we send once they click on that button is this request and the payload you want to pass in the description of that local attraction okay and you can see the in the request type is the default path which matches the name of the path that we want to flow through in the custom action so you can see default path is the same name we have for the path within the custom action block over here okay then we toggle stop on action for us to only proceed once they select learn more on a specific local attraction okay then over here we set use Global listening so I can disable this to show you I come back here and say use Global listening which is that feature which I mentioned if they pick the wrong local attraction they can always scroll back up and pick a different local attraction to learn more about it okay then whatever they pick uh if they say learn more on the first local attraction that description will be passing through the payload of the last event okay so we able to capture that save it to a variable called attraction description then is what we render back to the user through this text message uh you see we passing the attraction description okay and yeah that's that's how this works we can be able to just continue over here and ask them is there anything else I can help you with okay but I think I'm done over here then to deploy the chart board itself just come back over here go to the Integrations tab then you'll copy this code as is and is what you'll go and paste in within your HTML file over here then if you're importing your extensions from an external file you'll transform this script type to type module so you can see here this is type text/javascript but you want to change it to type module if your extensions are in a different file okay then you can be able to change the appearance so let's say the title of the chatboard you can see that the description all that and some few settings then uh you can even change the theme color so like you can insert the brand color of the specific hotel and you can upload even the icon or the brand icon of that hotel okay so you can see that's what we're using over here the brand icon over here and the brand icon over here so that's how you're able to deploy it for it to be more brand cohesive okay and yeah that's it from me uh if you have access to everything we've built over here so that is the voice flow template as well as the code that we use to build this chatboard link in the description uh if you want to work with our team to build such comprehensive chat boat whether it's a AI chat boat whether it's an AI voice boat whether it's automating any repetitive tasks within your business Link in the description to visit our website and book in a meeting with our team anyways till next time stay servy peace for is