Dialog Flow ( Api.ai ) Conversation in chatbot - chatbot

I am having a welcome intent and it allows user to select three different actions. Ex: Welcome! you can print your firstname, you can print your lastname or you can print your zipcode. If User select or enter last name then it should call the last name intent. So we are providing multiple options at welcome intent itself and user can choose any one of them.
Based on the action selected by user, the conversation should occur.
Please help me how to achieve this.

You are giving the user the option of proceeding by providing their first name, their last name or their zip code.
To capture their response, you will need to create three intents:
Capture First Name
Capture Last Name
Capture Zip Code
For each intent, you would provide a series of example phrases showing how the user might express each thing. For example, "Capture First Name" might contain examples like:
"My first name is Dan"
"Dan"
"Dan is my first name"
I'd recommend providing around 10 examples for each intent.
Dialogflow provides a system entity for zip codes, so it will be able to automatically extract the zip code from the "Capture Zip Code" intent.
However, to make the first and last name intents work, you'll need to create entities to represent the first and last names of all your users. Assuming you know these values ahead of time, you should first create each entity and then write a script to populate it from your datastore using the Dialogflow API's /entities endpoint.
Once you've created and populated these entities, add some examples that make use of them to your intents. Ensure that you highlight and annotate any entity values that are not automatically identified.
When your intents are complete, you can use Dialogflow's fulfillment to send the information they capture to your back-end.

Normally when the welcome intent triggered it will send a request to your backend through webhook,from backend you can send responses as templates or buttons and user can choose one of them ,if you are using backend here
Else in welcome intent response,use a response like you can print firstname ,you can print second name and configure intents for those and use contexts for proper flow.
In the second intent,keep one entity containing some values for first name and use a output context like frstname_output_context
In the another intent,keep one entity containing some values for last name as entity and use a output context like lsttname_output_context
Hope it clarifies using webhook and without webhook.

Related

What is the relationship between 'intents' and 'actions' in Dialogflow?

I'm having a bit of trouble conceptualizing the relationship between 'intents' and 'actions' in a Dialogflow agent.
I get that intents map the user's spoken request to a particular feature of my fulfillment service, optionally carrying parameters as input variables. This is how intents are defined in the official documentation:
"An intent represents a mapping between what a user says and what
action should be taken by your software."
But what then are actions? Their definition reads almost exactly the same:
"An action corresponds to the step your application will take when a
specific intent has been triggered by a user’s input."
Actions are defined within the context of intents, which means there can only be one action per intent and an action can't be attached to multiple intents. An action doesn't seem to be more than its name, which is also entirely optional as the intent works the same whether I specify an action name or not.
So what is their purpose? Why would I have my service react to actions instead of intents?
You have one slight misstatement in your question, but it illustrates the difference between a Dialogflow Intent and Action. The statement
an action can't be attached to multiple intents
isn't true. You can use the same Action name for multiple Intent names. In this case, it means that you can use the Action as a map to a function in the fulfillment without having to list each Intent that maps in your code.
In Dialogflow, the Intent does more than just match a particular user phrase - it also is used to match conversations that are in a particular state (determined by Contexts that are set) or for particular non-phrase events. Since you may wish to map several of these to the same action on the back-end (for example, if you have two different Incoming Contexts that you need matched with different user phrases), you can set the same Action for them but use different Intent names to identify them.
Some libraries, such as actions-on-google v2 and multivocal let you work with either, whichever makes the most sense.
When I name Intents, I will generally start all of them that do roughly the same thing with the same name I use for the Action, but add a suffix indicating why the Intents are different. (With the name of the context, or event, or parameters that are different.)
Update to clarify a few things
I generally use the Action name as the one that triggers my functions, however there are a few cases where I might still group things by action (because it makes sense to organize them that way), but carve out an exception for one of the Intents. Think of this as subclassing in an OO model. Rule of thumb would be to use the Action name but don't hold this rigidly if there is a good reason not to. (An example of this is using multivocal, the library defines an "unknown" Action that covers both misunderstood input and no input. Sometimes I want to handle one of these differently, however, so I'll define a handler that works on just the Intent.)
The Action name should be available in the JSON that Dialogflow sends your fulfillment in queryResult.action. I'm not sure why the documentation omits this at the moment.

REST where should end point go?

Suppose there's USERS and ORDERS
for a specific user's order list
You could do
/user/3/order_list
/order/?user=3
Which one is prefered and why?
Optional parameters tend to be easier to put in the query string.
If you want to return a 404 error when the parameter value does not correspond to an existing resource then I would tend towards a path segment parameter. e.g. /customer/232 where 232 is not a valid customer id.
If however you want to return an empty list then when the parameter is not found then query string parameters. e.g. /contacts?name=dave
If a parameter affects an entire URI structure then use a path e.g. a language parameter /en/document/foo.txt versus /document/foo.txt?language=en
If unique identifiers to be in a path rather than a query parameter.
Path is friendly for search engine/browser history/ Navigation.
When I started to create an API, I was thinking about the same question.
Video from apigee. help me a lot.
In a nutshell when you decide to build an API, you should decide which entity is independent and which is only related to someone.
For example, if you have a specific endpoint for orders with create/update/delete operations, then it will be fine to use a second approach /order/?user=3.
In the other way, if orders have only one representation, depends on a user and they don't have any special interaction then you could first approach.
There is also nice article about best practice
The whole point of REST is resources. You should try and map them as closely as possible to the actual requests you're going to get. I'd definitely not call it order_list because that looks like an action (you're "listing" the orders, while GET should be enough to tell you that you're getting something)
So, first of all I think you should have /users instead of /user, Then consider it as a tree structure:
A seller (for lack of a better name) can have multiple users
A user can have multiple orders
An order can have multiple items
So, I'd go for something like:
The seller can see its users with yourdomain.com/my/users
The details of a single user can be seen with yourdomain.com/my/users/3
The orders of a single user can be seen with yourdomain.com/my/users/3/orders
The items of a single order can be seen with yourdomain.com/my/users/3/orders/5

Master Data Services - Domain based attributes

We are using Master Data Services as an MDM solution for our SQL Server BI environment. I have an entity containing a first name and last name and then I have created a business rule that concatenates these two fields to form a full name which is then stored in the "name" system field of the entity.
I use this as a domain based entity in another entity. Then the user can then see the full name before linking it as a attribute in the second entity.
I want to be able to restrict the users from capturing data in the first entity against the name attribute because the business rule deals with the logic to populate this attribute. I have read that there are two ways to do this:
Set the display width to zero of the attribute. This does not seem to work, the explorer version still shows a narrow version of the field in the rows and the user can still edit the field in the detail pane.
Use the security to make the attribute read only. I have tried different combinations of this but it seems that you cannot use this functionality for a name field (system field).
This seems like pretty basic functionality that I require and it seems that there is no clear cut way to do this in MDS.
Any assistance will be appreciated.
Thanks
We do exactly the same thing.
I tested it, and whether you create a new member, or edit an existing member, the business rule just overwrites the manual input value in the name attribute.
Is there a specific 'business' reason why you need to restrict data input in the name field? If it is for Ux reasons, you can change the display name of the name attribute to something like 'Don't populate' or alternatively make it a '.', then the users won't know what to input.

Elastic Search completion suggester configuration

I'm trying to set autocomplete/suggestions on my site's search form, using Elastic Search's completion suggester feature.
I have a list of products, which are grouped by categories (on multiple levels). The search feature should be able to suggest category names, which are of more interest to users than direct products.
Several of these categories have the same name but a different parent (e.g. 'milk' under parent category 'dairy products' and 'milk' under category 'baby'). When the user selects a category suggestion, she's redirected to another page, with more specific results than mere search method.
Additional metadata (url to redirect to, parent category id/name) are added in the payload field.
I use the output field to return normalized suggestions for different inputs. As stated in the documentation:
"The result is de-duplicated if several documents have the same output,
i.e. only one is returned as part of the suggest result."
But as explained, my outputs may have the same value, while being different results, as they will link to different pages. It is also possible in the future that different category levels will yield different actions.
I am reluctant to differentiate things by adding the full string (i.e. "milk in dairy products") as the output, because:
1. The parent category is conceptually not the output itself but a related metadata.
2. I intend to have some formatting in the results, this forces me to parse the output string to add HTML tags in it.
So, is it possible to deactivate the de-duplication?
One workaround I'm thinking of if it's not possible is to store a stringified json object in the output, with all the data 'll need, both the one displayed in the search form and the metadata currently in the payload. But Id' rather look into existing configuration before resorting to that.

How to generate one-time-use links? Any CMS or framework solutions?

I'm making a site for a writers management company. They get tons of script submissions every day from prospective and often unsolicited writers. The new site will allow a prospective writer to submit a short logline / sample of his or her idea. This idea gets sent to an email account at the management group. If the management group likes what they see, they want to be able to approve that submission from within the email and have a unique link dispatched to the submitter to upload their full script. This link would either only work once, or only for a certain amount of time so that only the intended recipient could use it.
So, can anyone point me in the direction of some sort of (I'm assumine PHP + mySQL) CMS or framework that could accomplish this? I've searched a lot, but I can't seem to figure out the right way to phrase this query to a search engine.
I have moderate programming experience, but not much with PHP outside of some simple Wordpress hacks.
Thanks!
I will just give you general guidelines on a simple way to construct such a system.
I assume that the Writer is somehow Registered into the system, and his/her profile contains a valid mail address.
So, when he submits the sample, you would create an entry on the "Sample" table. Then you would mail a Manager with the sample and a link. This link would point to a script giving the database "id" of the sample as a parameter (this script should verify that the manager is logged on -- if not, show the login screen and after successful login redirect him back).
This script would then be aware of the Manager's intention to allow the Writer to submit his work. Now the fun begins.
There are many possibilities:
You can create an entry in an appropriate "SubmitAuthorizations" DB table containing the id of the Writer and the date this authorization was given (ie, the date when the row was added to your DB). Then you simply send a mail to the Writer with a link like "upload.php?id=42", where the id is the authorization id. This script would check if the logged user is the correct Writer, and if he is within the allowed timeframe (by comparing the stored "authorization date" and the current date).
The next is the one I prefer: without a special table just for handling something trivial (let's say you will never want to "edit" an authorization, nor "cancel" it, but it may still "expire"). You simply simply give the Writer a link with 2 parameters: the date the authorization was given and an authorization key, like: "upload.php?authDate=20091030&key=87a62d726ef7..."
Let me explain how it works.
The script would first verify if the Writer is logged on (if not, show the login page with a redirection after successful login).
So, now it's time to validate the request: that is, check if this is not a "forged" link. How to do this? It's just a "smart" way of construction this authorization key.
You can do something like:
key = hash(concat(userId, ";", authDate, ";", seed));
Well, here hash() is what we call a "one-way function", like MD5, SHA1, etc. Then concat() is simply a string concatenation function. Finally seed is something like a "master password", completely random and that will not change (for if you change it all the issued links would stop working) just to increase security -- let's say a hacker correctly guesses you are using MD5 (which is easy) and the he tries to hack your system by hashing some combinations of the username and the date.
Also, for a request to be valid, it must be in the correct time frame.
So, if both the key is valid, and the date is within the time frame, you are able to accept an upload.
Some points to note:
This is a very simple system, but might be exactly what you need.
You should avoid MD5 for the hashing function, take something like SHA1 instead.
For the link sent to the Writer, you could "obfuscate" the parameter names, ie, call them "k" for the "key" and "d" for the "authDate".
For the date, you could chose another format, more "cryptic", like the unix epoch.
Finally, you can encode the parameters with something like "base64" (or simply apply some character replacing function like rot13 for instance, but that take digits into account aswell) just in order to make them more difficult to guessing
Just for completeness, in the validation script you can also check if the Writer has already sent a file on the time frame, thus making it impossible to him to send many files within the time frame.
I have recently implemented something like this twice on the company I work for, for two completely different uses. Once you get the idea, it is extremelly simple to implement it -- maybe less than 10 lines of code for the whole key-generation and validation process.
On one of them, the agent equivalent to your Writer had no account into the system (actually it would be his first contact with the system) -- there was only his "profile" on the system, managed by someone else. In this case, you would have to include the "Writer"'s id on the parameters to the "Upload" script aswell.
I hope this helps, and that it was clear enough. If I find the time, I will blog about it with an working example on some language.