cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Guides

Learn more about specific Flow features
Filter
Filter by Labels
Select any of the labels below to filter results.
Filters applied...
Sorted by:
Let’s say you have a database of products that are distinguishable on multiple properties, like the type of product, the brand and the color:   When the user says “I’m looking for a black Samsung TV”, the chatbot should respond with something like “TVSamsungBlack is just the right product for you!” and send the URL for the product page. In order to set this up, we need to do 4 things: Capture the user input Retrieve the database Extract the right product and product URL from the database Return the values to the user 1. Capture the user input For capturing the user input we used entities for the properties, and combined them all in a single intent.     We set all the entities to required, so we can easily ask the user for potential missing properties:     Learn more about   How to capture user input. 2. Retrieve the database In order to be able to easily retrieve our database, we’ll import it to   restdb.io. To do that, we first need to convert the Google Spreadsheet to a CSV file.     You don’t need to format it anymore. This CSV file can directly be uploaded to restdb.io and you are good to go. As you can see, we now have the database on restdb.io:     Next, click on the gear icon on the top right corner to enter Developer mode, and head over to the settings, and then the JavaScript API Docs. There you can find your URL and API Key.   3. Extract the right product and product URL from the database Copy and paste your URL and API Key from restdb.io into this code, and also change the entity names to yours: async payload => { var request = require ( "request" ); var options = { method : 'GET' , url : 'https://test1-9795.restdb.io/rest/database-example-sheet-1' , headers : { 'cache-control' : 'no-cache' , 'x-apikey' : '6abea6430b6ef2e86c7197f7df47c0076721c' } }; let p = new Promise ( ( res,rej ) => request(options, function ( error, response, body ) { if (error) rej(error) res(body) })) let body = await p body = JSON .parse(body) console .log( 'b' ,body) const product_type = payload.params.product_type[ 0 ].value, brand = payload.params.brand[ 0 ].value, color = payload.params.color[ 0 ].value console .log(product_type, brand, color) const data = body.filter( ( e ) => e.product_type === product_type && e.brand === brand && e.color === color); console .log(data) return { params : { // Using a spread operator, we add all provided params in the result ...payload.params, // Now we override the product param product : [{ value : data[ 0 ].product, match : 'product' }], product_url : [{ value : data[ 0 ].product_url, match : 'product_url' }] } } } You can also add more filters if you have 4 or 5 properties instead of the 3 in this example of course. 4. Return the values to the user After the code action has been triggered, the bot will now have values for the parameters “product” and “product_url’, so we can use them in our bot responses like any other parameter in Flow:     When we test this flow, you can see it’s all working now!    
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
29
This guide will explain how to add a code action for storing the name of the last flow or event so you can route back to it after losing the context. A good way to create chatbots in a more efficient way is to make use of reusable flows. These flows are generic and can be re-used in multiple situations. Some examples are a feedback (“Did that help?”) flow and a “Do you still need help?” flow. When one of these reusable flows gets triggered, a user leaves the current context. In most situations, this doesn’t cause any problems. When a Feedback flow gets triggered, the user probably doesn't need to return to the previous flow. It’s a linear flow where the user got an answer to their question, and afterwards entered the Feedback flow. However, in situations like the “Do you still need help?” flow, things can get more complicated. When the user responds with “Yes”, you could trigger a handover, but what if you want to route the user back to their original context to make them complete their flow first? An example would be when the user has to select an option from a menu. You can add a Timer Trigger to detect if the user doesn’t respond for a specific time period. If so, you can let that timer trigger the “Do you still need help?” flow. When the user responds to that message with “Yes”, it would be better for the customer experience if the user is able to continue from where they left, instead of letting them select how they would like to continue their conversation with the bot. Routing to flows vs events You can route the user back to their original context by triggering the last visited flow or event. It depends on the use case which method would be best. If you have a flow containing multiple events, routing to the flow would always route the user back to the first step (event) of that flow, regardless of how much of that flow the user previously went through already. By routing to the last event, you can make sure the user skips the steps he or she has already gone through, which would be best in most situations. However, there are also some use cases where routing to the last flow could have some benefits as well. For example when using periodic broadcasts over longer time periods. Store the last flow name For every flow, you want to be able to go back to, add the following code to save the flow name. async payload => { //console.log(payload) console .log(payload.match.flow.title) return { params : { // Using a spread operator, we add all provided params in the result ...payload.params, // Now we override the lastflow param lastflow : [{ value : payload.match.flow.title, match : payload.match.flow.title }] } } } It’s also important to let the flow start with an event that has exactly the same name as the flow. Route back to the last flow Now you have stored the name of the last flow into a parameter, you can use another code action to dynamically route to an event with the name of the value of that parameter: async payload => { if ( Array .isArray(payload.params.lastflow)) { let lastflowname = payload.params.lastflow[ 0 ].value trigger(payload.params.lastflow[payload.params.lastflow.length - 1 ].value) } else { console .error( "Lastflow was undefined." ) } } Store the last event name You can do the same for the last event name. Simply replace payload.match.flow.title with payload.match.step.title and change lastflow to lastevent. async payload => { //console.log(payload) console .log(payload.match.step.title) return { params : { // Using a spread operator, we add all provided params in the result ...payload.params, // Now we override the lastevent param lastevent : [{ value : payload.match.step.title, match : payload.match.step.title }] } } } Don’t forget to add this code action underneath all events you want to be able to route back to. Route back to the last event Then the code action for routing back to the last event will look like this. async payload => { if ( Array .isArray(payload.params.lastevent)) { let lasteventname = payload.params.lastevent[ 0 ].value trigger(payload.params.lastevent[payload.params.lastevent.length - 1 ].value) } else { console .error( "Lastevent was undefined." ) } }
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
28
Give different responses depending on the value of the asked number Different routing for values that are not less than a specific number If you want your chatbot to be able to give a different response when a number is greater, equal or less than a specific number, you can use a simple code action. Let’s say we want our bot to check if the number the user says is either lower than 10, or that it is 10 or higher. We created a simple flow for that:       The code action in the flow above contains the following code: async payload => { if ( payload.params.number [ 0 ].value < 10 ) { trigger ( '<10' ) } else { trigger ( '>=10' ) } } The code action first checks if the number is less than 10, and if so, it will trigger the <10 event. Else, it will trigger the >=10 event. Don’t forget to change the event names for your own event names if you copy and paste this code into your own project. When we test it, you can see it all works now!     Different routing for values that are equal to a specific number In the last example it’s a bit weird to respond with “10 is 10 or more.”. Let’s add another event to the flow for when the value is equal to 10:     The code action now should look like this: async payload => { if ( payload.params.number [ 0 ].value < 10 ) { trigger ( '<10' ) } else if ( payload.params.number [ 0 ].value === 10 ) { trigger ( '=10' ) } else { trigger ( '>10' ) } } Value is NOT equal to It also works the other way around. The example above illustrates you can use “payload.params.number[0].value === 10” to check if the parameter is 10, but you also have the possibility to check if it is not equal to 10. To do that, simply replace “===” with “!==”. Values in a range You can also check if the value is in a range (between 2 specific numbers). To illustrate this, we created another flow:   This code action contains the following code: async payload => { if (payload .params .number [ 0 ] .value >= 10 && payload .params .number [ 0 ] .value <= 20 ) { trigger( 'in_range' ) } else { trigger( 'not_in_range' ) } }
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
26
Confirm a received message by email to your user In some cases, you might want to send an email to your customer of confirmation of receipt by email. A common example is when your chatbot creates a ticket in a CRM tool like Salesforce, Zendesk or Hubspot and you confirm that the ticket is received by email. In this guide we show you how to: Check if we have the customers email address If not, ask and extract the email address If the customer doesn't provide a valid email address, ask again Send confirmation of receipt by email to the customer 1. Check if we have the customers email address The first step is to check if we have the customers email address. We can do that by using the Condition trigger. Drag and drop it onto your canvas. The branch that you see will behave as an if/else statement. If param email exists continue with the first branch, else, follow up with the second branch. For more info regarding conditions, have a look   here. 2. If not, ask and extract the email address Let's say we don't have the customers' email address yet and the bot will continue with the second branch. That is the moment to   ask and extract   the email address. We do that by using the Any Text trigger. In this example, the name of the parameter is "email". In the right pane, you can select that this parameter should be an email address.     3. If the customer doesn't provide a valid email address, ask again Drag and drop a second any text next to Any text that should be an email. This parameter will be filled whenever the user input is not a valid email address. From there on we can   loop back   to the event on top. Tip: provide an option to head back to a menu or intro to prevent customers from being stuck the flow.   4. Send confirmation of receipt by email to the customer Now, we've received the customer's e-mail address and we can use an   Action   to send an e-mail from the Flow Platform (supported at Pro and Enterprise Plans).     Drag and drop an Action onto your canvas. You can copy and paste the code below as an example. async payload => { let emailadres = "-" if ( Array .isArray(payload.params.email)) { emailadres = payload.params.email[ 0 ].value } //console.log(emailadres) toolbelt.email({ to : emailadres, subject : 'Hello from Flow.ai' , message : `Hi and thank you for your message. Someone from flow.ai will get back to you as soon as possible. - Flow.ai Team` }) } You can verify the process by using the try it out. You should receive an email in your inbox.    
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
34
In this guide we will show you how you can use your chatbot to extract data and send that data to a database by using APIs. We will do that by showing you how to: Extract data or user input Set up a database Send data to a database (POST) In addition to pushing data to a database, it is also possible to   retrieve data from a database (GET). Together, these two are a strong combination for providing automated personalized customer journeys. Extracting data and user input Before we start filling our database, we need to extract some data or user input to send to our database. Within the Flow platform there are 2 common places where to find data. 1. User input The first place to extract data is by using user input. User input can contain valuable information such as an e-mail address, phone number, or name. Our article   How to capture user input   shows you how to extract that information as a parameter. 2. Payload Second, you can find a lot of data within the   payload. When integrating with messaging channels, such as WhatsApp or Facebook Messenger, some data is already provided by that channel. You can already extract that from the channels metadata without asking for a name or phone number. Setting up a database In this example, we’ll be working with a database from   Restdb. If you’re using a different database, don’t worry, the concept will be similar. After creating an account you can set-up your database. In the example below, you will see the database ‘userdata’ that contains 3 fields: name, phone, and email.       Sending data to a database (POST) To send data from your Flow chatbot to the RestDB database, we’ll be working with APIs. If you’re using RestDB you can access developers mode by clicking the gear/settings icon in the top right. Then head over to API docs -> Javascript. From there, you can copy and paste the code from RestDB to action   in Flow.   The next step is to alter the code in Flow’s Action, so that we can actually send the extracted data to our database. Therefore, we’ll create 3 variables. We check if they exist and if so, we’ll fill those variables. New to actions and coding? Have a look at   code best practices async payload => { var fullName = "-" var phoneNumber = "-" var email = "-" // Check if name exists if ( "fullName" in payload.user.profile) { fullName = payload.user.profile.fullName } // Check if phoneNumber if ( "phoneNumber" in payload.user.profile) { phoneNumber = payload.user.profile.phoneNumber } // Check if the param "email" exists if ( Array .isArray(payload.params.email)) { email = payload.params.email[ 0 ].value } // API (POST) to send data to database var request = require ( "request" ); var options = { method : 'POST' , url : 'https://integratedb-74ce.restdb.io/rest/userdata' , headers : { 'cache-control' : 'no-cache' , 'x-apikey' : 'YOUR SECRET API KEY' , 'content-type' : 'application/json' }, body : { name : ` ${fullName} ` , phone : ` ${phoneNumber} ` , email : ` ${email} ` }, json : true }; request(options, function ( error, response, body ) { if (error) throw new Error (error); console .log(body); }); } Our code is now completed and we can add it to our Flow and test it by using the try it out function or by using   WhatsApp testing.     Our database is now filled with 3 values: The name of the user (acquired by payload) The phone number of the user (acquired by payload) The email address of the user (acquired by user input)       Retrieving data from a database (GET) When data is stored in a database you can also use that data to improve the customer experience. Read more about   retrieving data from a database.
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
36
Use cloud code to send e-mail to multiple recipients Send e-mail to 1 recipient The following example shows you how to send an e-mail to a single recipient. async payload => { // Send an email toolbelt.email({ to : 'email1@yourdomain.com' , subject : 'Report needed' , message : 'If only you knew the power of the dark side.' }) } Send e-mail to multiple recipients The following example allows you to send an e-mail to multiple recipients by creating an array. async payload => { // Send an email toolbelt.email({ to : [ 'email1@yourdomain.com' , 'email2@yourdomain.com' ], subject : 'Report needed' , message : 'If only you knew the power of the dark side.' }) }
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
28
Create dynamic Google Maps images for your chatbot responses If your chatbot sends multiple addresses to your users, for example when you have multiple store locations, you might want to add a Google Maps image that dynamically changes depending on the address. To set this up, you need 2 things: The address A Google Maps Platform API Keys The address can be from your database, or it can be an address that the user just sent:     The Image Reply contains the following URL: https://maps.googleapis.com/maps/api/staticmap?center={{address}}&markers=color:red%7Clabel%{{address}}&zoom=12&size=600x400&key=INSERT_YOUR_API_KEY Make sure not to forget to insert your API key at the end of the URL. Notice that using this API will cost 0.002 USD each time. As you can see, the image URL contains the parameter between double curly brackets. This makes the URL dynamic. The value of the Address parameter will be used in Google Maps to do a location search. You can then use the URL in image replies, cards and carousels just like any other image URL.     Map Pins You can remove the map pin if you don’t want it. Simply remove “&markers=color:red%7Clabel%{{address}}” from the URL. You can also change the address parameter for something else to add the pin to a different location. It’s also possible to change the color of the pin or even add more pins to the image. Zoom and size By giving another value to “&zoom=12”, you have the option to change the zoom of the image. Changing the size of the image is possible by changing the value for the “&size=600x400” part of the URL.
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
0
30
A QR code, short for Quick Response, is a scannable barcode in the form of a matrix. It has its origin in the automotive industry but has become popular in the consumer market as it can enhance the customer journey. At an early stage of QR codes within the consumer market, these QR codes could only be read by mobile phones with an additional QR-code reader installed. With that hurdle taken away, almost any phone can now scan a QR code without any additional app installments. That opens up a lot of new ways to automate interactions by using AI chatbots on different channels like Web, Messenger, and WhatsApp.     Advantages of Chatbots and QR codes Chatbots allow you to automate customer interaction on different channels and different languages. That automation adds value for you as a business by saving time, and for consumers by answering questions immediately. As a well-designed chatbot adds value for businesses and for consumers, one of the challenges is how to get as many customers as possible onboarded to the chatbot. That’s where QR codes come in handy.     Why using chatbots and QR codes To get more customers to interact with your bot you can use QR codes. You can create a QR code and place it in offline items such as invites, posters, tables, and more. As it’s very likely that your consumer has their mobile phone with them, they can scan that QR code and directly interact with the chatbot to answer a question or to join a promotion. How to create QR codes for your chatbot on Web, Messenger, and WhatsApp That QR code sounds nice but how does that work? And where to start? Well, the QR code actually represents an URL and that URL can redirect customers to Web, Messenger, and WhatsApp. There a several tools that allow you to convert an URL into a QR code. In this example, we’ll be using qr-code-generator.com. You can paste your destination URL and it will generate your QR code. QR code for Web To create a QR code that opens a web URL, paste your destination or target URL into QR Code Generator. After that, your code will be created and you can download it in your preferred format. Are you working on a chatbot that serves a lead generator? In that case, you might want to add unique tags in the URL to measure conversion rates. QR code for Facebook Messenger     To create a QR code for your Facebook Messenger bot, the process is similar. We need to convert our target URL into a QR code by using a tool like QR Code Generator. The advantage of using Facebook Messenger is that you can create a link that triggers a specific event within Flow by using m.me links. In that case, your URL will be something like: http: //m.me/theflowai?ref=TEST_DRIVE Read more about Facebook m.me links in   How to use Facebook Messenger m.me links. QR code for WhatsApp The idea of creating a QR code for WhatsApp is quite similar to the m.me links. The only difference is that our URL can set a pre-defined text within WhatsApp to your chatbot so that the user only has so hit the enter button. In that case, we won’t be able to trigger an event directly from the link but we can already place a piece of text that would trigger the right flow when being sent. To create a link that’s useful for this case you can use   WhatsApp click to chat links. That will result in something like this: https: //wa.me/31633567993?text=preorder     Boost conversion With QR codes as described above you make it easier for your user to connect with you as a brand. With less friction in the process this will boost conversion rates and onboarding numbers.
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
31
Comments in JavaScript can be used to explain JavaScript code or to prevent execution of lines. Single line comments The following example shows you how to use single line comments by using the ' // '. async payload => { // Check the channel of the user let channel = payload.channelName } Multi line comments To place multi line comments you can use the ' /* ' to open the comment section and ' */ ' to close. async payload => { /* Check the channel of the user Now we can change the flows based on the channel */ let channel = payload.channelName } Prevent execution of lines To prevent execution of lines you can use both of prior methods and is great for testing. async payload => { // Check the channel of the user let channel = payload.channelName if (channel === 'messenger' ){ trigger( 'Channel-Messenger' ) } /* if(channel === 'socket'){ trigger('Channel-Socket') } */ }  
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
31
Cloud code actions provides functionality to send e-mails. Example use cases: Sending emails when your bot fails to understand a question Sending data to a specific inbox Send a confirmation email to a user You can send an email using the   toolbelt.email()   method. Sending HTML We support sending (limited) HTML formatted email with custom emails. async payload => { toolbelt.email({ to : 'foo@bar.com' , message : '<div><h1>Example Title</h1><p>This is an HTML example</p></div>' }) } Sending data with e-mails Cloud code supports JavaScript template tags that allows you to send information, like parameters inside the payload. Sending an email with the name of a user async payload => { toolbelt.email({ to : 'foo@bar.com' , message : `Some data extracted: ${payload.user.name} ` }) } Sending an email with a param async payload => { toolbelt.email({ to : 'foo@bar.com' , message : `Some data extracted: ${payload.params.city[ 0 ].value} ` }) } Sending all parameters Combining a custom formatted email with dynamic data: async payload => { const { params } = payload // Generate HTML for the params let paramsHtml = '' const paramNames = Object .keys(params) for ( let i = 0 ; i < paramNames.length; i++) { const paramName = paramNames[i] // Get the param const param = params[paramName] // Add the param name to the HTML paramsHtml += ` <p> <strong> ${paramName} :</strong> <div> ${param.map(values => values.value).join(', ')} </div> </p>` } toolbelt.email({ to : 'foo@bar.com' , subject : `Collected ${paramNames.length} params` , message : ` <h2>We found the following data!</h2> <p>This is just a small example</p> <p> ${paramsHtml} </p>` }) } Sending only parameters that have a value Sometimes not all parameters you want to send actually have a value. The code below first gives the parameters a "-" value. Next, it checks if the parameter should be overwritten. async payload => { var email = "-" var address = "-" var phone = "-" if ( Array .isArray(payload.params.email)) { email = payload.params.email[email.length - 1 ].value } if ( Array .isArray(payload.params.address)) { address = payload.params.address[address.length - 1 ].value } if ( Array .isArray(payload.params.phone)) { phone = payload.params.phone[phone.length - 1 ].value } const subject = `Chatbot Handover` toolbelt.email({ to : 'foo@bar.com' , subject, message : `Someone asked for a handover <br> E-mail:\t ${email} <br> Adres:\t ${address} <br> Phone:\t ${phone} <br>` }) } As you can see, if only the parameters for the email and the address exist, the phone number will have a "-".    
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
29
Store or Save parameters and use them later on in your design     Flow allows you to extract data from conversations. To extract data you can use   entities   or the Trigger "any text". Within the "Try it out" window on top you will see the extracted data and corresponding parameter.     When your parameter is recognized you can store or save it so that you can use that parameter later on in your design. That can be useful when you want to: Ask the user for confirmation of the data Use the parameters for API calls The code below shows an example of how to store the parameter "email". If you're using other variable names, make sure to adjust the name in the action code below. async payload => { // Check if the param "email" exists if ( Array .isArray(payload.params.email)) { // Param exists, let's store it so we can use it later await store.save( 'email' ,payload.params.email[ 0 ].value) } }
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
28
Learn how to extract and validate addresses using the Google Maps Geocoding API If you need to ship or pickup an item for a customer you might need their address. But how do you verify if it exists? Address information can consist out of street, house number, postal code, po box, city, state, country, etc. Using Flow and the   Google Maps Geocoding API, there is no need to ask all this information separately. Design your flow and capturing the address Training the AI to contextually extract house numbers and cities   using entities   works, but it requires a lot of training data. Even adding a hundred annotated examples might not give you a 100% result. In stead, it is far easier to use an   Any text   slot of the entity type   Text. Using the   Any text   you can capture any user input and use that within a code action to geo-code it to structured data.   Validating the address with the Google API There are different providers, but for this example we'll show how to use the   Google Maps Geocoding API   to convert user input into structured address information. To use the Geocoding API you   need to get an API key. The API key is a unique identifier that is used to authenticate requests with Google for usage and billing purposes. Writing the code action The first step is getting the address information.   Any text   works the same way as   any other params. In the code example below, we simply receive the address and output it to the logging console. async payload => { const { params, user } = payload const { address } = params const lastAddress = address[address.length - 1 ].value console .info( 'The last address captured' , lastAddress) } Now that we have the address we can validate and transform it into structured address data using the Google API. async payload => { try { const { params, user } = payload const { address } = params const lastAddress = address[address.length - 1 ].value // For this example we show the API key in code // but best practice is to use Configuration // https://flow.ai/docs/actions/code_configuration const key= 'MY SECRET API KEY' // Construct a Google API URL const url= encodeURI ( `https://maps.googleapis.com/maps/api/geocode/json?address= ${lastAddress} &key= ${key} &language= ${user.profile.locale || 'en'} ` ) // Call the API const { data } = await request(url) const { status, results } = data console .info( 'The API converted the address to' , results) } catch (err) { console .error( 'Failed to call the API' , err) } } Below is a sample geocoding result, in JSON. Please check the   Google documentation   to find out about all the details of the response. [ { "address_components" : [ { "long_name" : "1600" , "short_name" : "1600" , "types" : [ "street_number" ] }, { "long_name" : "Amphitheatre Pkwy" , "short_name" : "Amphitheatre Pkwy" , "types" : [ "route" ] }, { "long_name" : "Mountain View" , "short_name" : "Mountain View" , "types" : [ "locality" , "political" ] }, { "long_name" : "Santa Clara County" , "short_name" : "Santa Clara County" , "types" : [ "administrative_area_level_2" , "political" ] }, { "long_name" : "California" , "short_name" : "CA" , "types" : [ "administrative_area_level_1" , "political" ] }, { "long_name" : "United States" , "short_name" : "US" , "types" : [ "country" , "political" ] }, { "long_name" : "94043" , "short_name" : "94043" , "types" : [ "postal_code" ] } ], "formatted_address" : "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA" , "geometry" : { "location" : { "lat" : 37.4224764 , "lng" : -122.0842499 }, "location_type" : "ROOFTOP" , "viewport" : { "northeast" : { "lat" : 37.4238253802915 , "lng" : -122.0829009197085 }, "southwest" : { "lat" : 37.4211274197085 , "lng" : -122.0855988802915 } } }, "place_id" : "ChIJ2eUgeAK6j4ARbn5u_wAGqWA" , "types" : [ "street_address" ] } ] Covering any edge cases The Google API might return multiple results, so it's good to confirm the returned address with the user. For this we extend the flows to handle edge cases like: If the Google API returns an error If the API did not give any valid results If the API returns us multiple addresses Below is an example what your final flow could look like.     Within the code action we send a Carousel component to display the results, and ask the user to verify the address. async payload => { try { const { params, user } = payload const { address } = params const lastAddress = address[address.length - 1 ].value // Add the API key to the configuration const key = await toolbelt.config.get( 'api_key' ) // Build url const url= encodeURI ( `https://maps.googleapis.com/maps/api/geocode/json?address= ${lastAddress} &key= ${key} &language= ${user.profile.locale || 'en'} ` ) const { data } = await request(url) const { status, results } = data if (status !== 'OK' ) { return trigger( 'INVALID_ADDRESS' ) } /* * Simple helper function to find a piece * of address information within the API results */ const findAddressPart = ( result, part ) => { const component = result.address_components.find( c => c.types.indexOf(part) !== -1 ) if (component) { return component.short_name } return "" } // Create a carousel const carousel = new Carousel() for ( let i = 0 ; i < results.length; i++) { const result = results[i]; // Create a card const card = new Card({ title : result.formatted_address }) const params = [ new Param( 'delivery_street' , findAddressPart(result, 'route' )), new Param( 'delivery_zipcode' , findAddressPart(result, 'postal_code' )), new Param( 'delivery_housenumber' , findAddressPart(result, 'street_number' )), new Param( 'delivery_city' , findAddressPart(result, 'locality' )), new Param( 'delivery_country' , findAddressPart(result, 'country' )) ] card.addButton( new Button({ label : "Confirm" , type : 'event' , value : 'ADDRESS_CONFIRMED' , param : params })) carousel.addCard(card) } carousel.addQuickReply( new QuickReply({ type : 'event' , label : 'Try again' , value : 'DELIVERY_ADDRESS' })) return new Message( 'We do not support audio only' ).addResponse(carousel) } catch (err) { console .error( 'Failed to call the API' , err) trigger( 'INVALID_ADDRESS' ) } } As you can see you can really create advanced use cases.     Read more Working with entities Creating code actions Google Maps Geocoding API
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
30
This article shows you how to find your Organization ID within Flow App . 1. Log in Log in to the Flow App. 2. Select Organisation settings Select Organisation settings from the dropdown menu on the top right.   3. Copy Organisation ID      
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
32
Within Flow there is an advanced system in place that can detect, extract, convert and format a date and time. This makes it for example possible to ask a customer for a date and use it to plan an appointment. Slot filling The easiest way to work with dates and time is using an   Any text   slot of the entity type   Date.     Whenever a customer would say something like   today,   next Saturday   or   12th of September   the AI engine will transform this into a   UTC date, relative to the timezone of the customer.   Date and time is relative Flow works with builtin timezone support. If the current date and time of a customer in Amsterdam would be 2pm, 27th of August, it's translated to a UTC date time with the value   2019-08-27T12:00:00.000Z     With UTC it’s possible to transform a date to any local format. Since time is relative,   tomorrow   would mean something different for a customer in Japan, compared to someone living on the west coast of the US. Formatting dates If you want to format dates to a local format you need to use a code action.     To format dates and time we provide the popular   Moment.js   and   Moment Timezone   packages to be used within code actions. // Convert a date to Dutch date format moment(date).tz( 'Europe/Amsterdam' ).format( 'LLLL' ) The following example code shows you how to format a data and add it as a param to be used inside your flows. async payload => { const { params } = payload if ( Array .isArray(params.some_date)) { // Format a date in Europe/Amsterdam format return { params : { ...payload.params, formatted_date : [{ value : moment(params.some_date[ 0 ].value).tz( 'Europe/Amsterdam' ).format( 'LLLL' ) }] } } } } Whenever the above code action is executed, it would convert a date and return it as a new param.     Using a user's timezone offset Within the payload of a code action you'll receive any user profile data, including timezone offset (if available). The offset is the number of hours a user relative to UTC. The example below shows how you can use the timezone offset to convert a date to a local format. async payload => { const { params, user } = payload const { profile } = user if (! Array .isArray(params.some_date)) { // Skip if there is no date to format return } // Dynamic timezone based on user timezone offset const region = profile.timezone < 0 ? `Etc/GMT ${profile.timezone} ` : `Etc/GMT+ ${profile.timezone || 0 } ` return { params : { ...payload.params, formatted_date : [{ value : moment(params.some_date[ 0 ].value).tz(region).format( 'LLLL' ) }] } } } Read more Moment.js documentation List of UTC time offsets Code actions documentation
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
33
Add your chatbot to your wordpress website in just a few simple steps This article will show you how to deploy your Flow chatbot on your website by using the Flow web widget. There a several ways to add your chatbot to your Wordpress site. In this example we will be using a plugin and you will need the following: A Flow bot Admin access to your Wordpress Site Plugin "Header and Footer Scripts"     Copy your Web Widget script The next step is to copy the script that represents your chatbot. To do that: Log in to the flow app Go to Integrations > Web Widget Copy script to clipboard   Add script to Plugin You can now paste your script to your Wordpress site: Access the "Header and Footer Scripts" plugin Paste your script to the head or footer section Save changes and done Tip: Add the script to the footer. This allows to load the page faster as a first step and load the Web Widget as a second step in the process.    
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
27
Adjust the interaction based on the device that your user is using. JavaScript is a powerful language that can be used to detect if the user is on a mobile or desktop device. That allows you to change the work flow based on the device. In this guide we will create code that will check if the user is on a desktop device and if that's the case we will automatically open the Web Widget after 5 seconds. To get the code working we will incorporate it by following 3 steps: Create a function to check the device Use the function to check the device Add delayed opening & trigger event Javascript can also be used to check if the user is on a   Homepage or Specific Page   or you can   Combine Functions   to check if the user is one the homepage with a desktop device. 1. Create function to check the device To check if the user is desktop or mobile, in this example, we will check for the innerWidth by creating a function that will return true or false. If the width is greater than 768 px we consider it as a desktop device the function should return true when we call the function, < script > window .desktopcheck = function () { var check = false ; if ( window .innerWidth> 768 ){ check= true ; } return check; } </ script > 2. Check if on desktop The function is created and we can now call it. The function returns a boolean (true or false). The code below can be translated to something like: If it's true that user is on desktop then ... < script > if ( window .desktopcheck()){ // add code here } </ script > 3. Add delayed opening and start event The last step is to add some code to make sure the Web Widget will open after 5 seconds and the event 'START_CHAT' will be triggered. < script > // Delayed Opening setTimeout( function () { __flowai_webclient_app.open() }, 5000 ) // 5 secs // Trigger Event window .__flowai_webclient_autoTriggerEvent = 'START_CHAT' </ script > Find the complete code below < script > window .desktopcheck = function () { var check = false ; if ( window .innerWidth> 768 ){ check= true ; } return check; } if ( window .desktopcheck()){ setTimeout( function () { __flowai_webclient_app.open() }, 5000 ) // 5 secs window .__flowai_webclient_autoTriggerEvent = 'START_CHAT' } </ script >
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
31
Change the opening event based on a specific page You can use Javascript to check if the user is on the homepage or another specific page. In this example we will check if the user is on the homepage. IF, and only then we will automatically open the Web Widget after 5 seconds ant trigger a specific event. To get the code working we will incorporate it by following 3 steps: Create a function to check if on homepage Use the function to check if on homepage Add delayed opening & trigger event Javascript can also be used to check if the user is on a   Desktop or Mobile device   or you can   Combine Functions   to check if the user is one the homepage with a desktop device. 1. Create function to check if homepage Let's start by creating a function to check if the user is on the homepage. To do that we can user the pathname. If on the homepage the pathname should be equal to "/". Any other page will consist of additional characters in it's pathname. If you want to include a specific page you can replace the "/" by the pathname of your page e.g. "/blog". < script > window .homepagecheck = function () { var check = false ; if ( document .location.pathname === "/" ){ check= true ; } return check; } </ script > 2. Check if on homepage The function is created and we can now call it. The function returns a boolean (true or false). The code below can be translated to something like: If it's true that user is on the homepage then ... < script > if ( window .homepagecheck()){ // add code here } </ script > 3. Add delayed opening and start event Now let's add the delayed opening and trigger an event. < script > // Delayed Opening setTimeout( function () { __flowai_webclient_app.open() }, 5000 ) // 5 secs // Trigger Event window .__flowai_webclient_autoTriggerEvent = 'START_CHAT' </ script > Find the complete code below < script > window .homepagecheck = function () { var check = false ; if ( document .location.pathname === "/" ){ check= true ; } return check; } if ( window .homepagecheck()){ setTimeout( function () { __flowai_webclient_app.open() }, 5000 ) // 5 secs window .__flowai_webclient_autoTriggerEvent = 'START_CHAT' } </ script >
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
30
JavaScript can be used for several tasks such as detecting if the user is on a   Desktop or Mobile device   or to check if the user is on the  Homepage or a Specific Page . In this example we want to combine these two functions. If the user is on the homepage on a desktop device, we want to trigger a specific event after 5 seconds. Create functions Combine functions Add delayed opening & trigger event   1. Create functions We start by creating two functions. For more details about these functions have a look at: Function Desktopcheck Function Homepagecheck < script > window .desktopcheck = function () { var check = false ; if ( window .innerWidth> 768 ){ check= true ; } return check; } window .homepagecheck = function () { var check = false ; if ( document .location.pathname === "/" ){ check= true ; } return check; } </ script > 2. Combine functions To combine function we want both functions to return true. < script > if ( window .desktopcheck() && window .homepagecheck()){ // Add code } </ script > 3. Add delayed opening and start event Now let's add the delayed opening and trigger an event. < script > // Delayed Opening setTimeout( function () { __flowai_webclient_app.open() }, 5000 ) // 5 secs // Trigger Event window .__flowai_webclient_autoTriggerEvent = 'START_CHAT' </ script > Find the complete code below < script > window .desktopcheck = function () { var check = false ; if ( window .innerWidth> 768 ){ check= true ; } return check; } window .homepagecheck = function () { var check = false ; if ( document .location.pathname === "/" ){ check= true ; } return check; } if ( window .desktopcheck() && window .homepagecheck()){ setTimeout( function () { __flowai_webclient_app.open() }, 5000 ) // 5 secs window .__flowai_webclient_autoTriggerEvent = 'START_CHAT' } </ script >
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
36
Set profile attributes and personalize the experience Are you customers using your chatbot but you have no idea who that customer is? Well, there are different ways to get to know your customer and make the customer experience more personal. When a customer visits your page that the user is Anonymous in most cases. An expectation might be the user is logged in into their personal account. If that’s the case you can already pass that information into your chatbot by setting a custom originator. When there’s no login option still there’s a way to personalize the experience.     In the example below, we show you how to ask the user for information and add that to his or her profile. Instead of being Anonymous, you will now have a name added to the profile that you can use within your chatbot design or whenever there’s a handoff to a human colleague. 1. Ask for user input Within your flow the first step is to ask the user for input. In this case we want to know the name of the user so we ask something like “What is your name?”. 2. Modify profile attributes To use the input of the user we can use the Any Text trigger to store that input into a parameter (or variable). When that value is available within a parameter we can use it later on in our conversation and we can use it to change the profile attributes. To change those attributes the only thing we need to do is to change the name of the parameter to any of these: user.name user.firstName user.lastName     In our example, we set the attribute user.name to the user input. 3. Follow up with a personalized experience You can now follow up with a bot reply that uses that information or you can hand the conversation off to an agent that will immediately see the name of the user.  
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
Labels (1)
0
33
Flow allows you to create multiple fallback scenarios for when the NLP engine fails to understand a message. The Unknown Trigger For creating fallback scenarios we provide a special trigger called   Unknown. Whenever the system receives a trigger it cannot match it will search for an Unknown trigger. Handing over to humans If you want to hand over a conversation to a human agent, you can do this by using the   takeover action   in   cloud code.     Auto Pause When a human agent sends a message using the Chat app the NLP engine is paused automatically. You can set the number of minutes before the bot is activated again using the project settings. The NLP engine also automatically pauses when there a messages being sent by moderators on Channels like Facebook Messenger. For example: when an employee uses the Facebook for business app to send replies. Example Scenarios Standalone AI Assistants Add a new flow Start with the trigger Unknown Add a Text reply with the message:   Sorry I don't know about that yet Customer service     Add a new flow Start with the trigger Unknown Add a Text reply with the message:   Thank you, one of our service operators will be here shortly Drag and drop an action with Takeover Drag and drop an action with Pause bot Customer service, double tap     Add a flow Start with the trigger Unknown Add a Text reply with the message:   Could you please rephrase the question Add another the Unknown trigger below the reply message Add a Text reply with the message:   Thank you, one of our service operators will be here shortly Drag and drop an action with Takeover Drag and drop an action with Pause bot Read more on Handover actions:  Chatbot Handoff How to nail the bot to human handoff How pausing and resuming works with Front How to implement Push Notification How to hand over to a human agent Send text versus trigger event Trigger the bot from within Front
View full article
by Khoros Staff Khoros Staff Jun 19, 2021
0
31