I tried to access the user's input as described here: http://www.ibm.com/watson/developercloud/doc/conversation/advanced_overview.shtml based on the car-dashboard dialog.
{
"output": {
"text": "Great choice! Playing some #genre music for you. <?input text?>"
}
}
Error:
Dialog node error
Error when updating output with output of dialog node id:node_5_1469049934217. Fix the dialog node. Node output was:{"text":"Great choice! Playing some #genre music for you. "} org.springframework.expression.spel.SpelParseException: EL1041E:(pos 6): After parsing a valid expression, there is still more data in the expression: 'text'
To access user input you can use the input object.
For example:
<? input.text ?>;
The following help page has more details under accessing inputs.
Related
I'm having issues with implementation of Enhanced conversions in Google Ads. Would be really appreciative if someone could give me some pointers to the right direction or any suggestion regarding what to try.
The error message I'm receiving is the one below:
"User address data field is incorrectly formatted
Make sure user address is correctly formatted and hashed using the SHA-256 algorithm. See instructions and double-check your setup."
I've been following the instructions specified here: https://support.google.com/google-ads/answer/10172785?hl=en#zippy=%2Cenable-enhanced-conversions-in-google-tag-manager-and-create-custom-javascript-variable
The part regarding "hashed using the SHA-256" appears to be incorrect, since Google in another part of their documentation say that the data shouldn't be se sent hashed, unless you're using the Google API (which is not the case here).
The only value not available in the data layer on the conversion page is "street" so I've left that field out entirely. The other attributes should be present in the data layer.
Which steps have I taken?
Step 1 - Selected "Include user-provided data from your website" in the existing Google Ads pixel/tag.
Step 2 - Configured the variable type "User-provided data" and selected "Code" as type
Step 3 - The data source has the below code:
function () {
return {
"email": {{data.email}} ,
"phone_number": {{Telephone}} ,
"address": {
"first_name": {{First Name}} ,
"last_name": {{Last name}} ,
"city": {{City}} ,
"postal_code": {{zipCode}} ,
"country": {{Country ID}}
}
}
}
Can anyone see if their perhaps is something in the code that's not correct or if their could be any other possible reason why the enhanced conversions aren't collecting data?
Thanks in advance!
I've looked in to using the CSS selector method, but the conversion page only has email data.
Also tried "Manual configuration", but this requires all values to be present, otherwise you can't save (e.g. if "Address" is missing, you can't save)
I've also made test purchases and from what I can see, the conversion tag is picking up the attributes for enhanced conversions correctly.
I'm attempting to use follow-on prompts within QnAMaker but am confused about the purpose of the field labelled "Display text" in the "Follow-up prompt" creation dialogue. https://learn.microsoft.com/en-us/azure/cognitive-services/qnamaker/how-to/multiturn-conversation describes this field as "The custom text to display in the follow-up prompt.". To me, that suggests that it's just a label for the follow-up prompt which is typically rendered as a button. I therefore assumed that the text had no purpose other than as a label and that the button would be directly linked to the chosen question / answer pair. However, from experimenting with a QnAMaker knowledge base, it seems that the "Display text" is actually passed to the QnAMaker service and this text is used to search for the answer. This means that the "Display text" value has to be chosen for the purpose of both labelling the button and successfully finding the follow-on answer.
This means I can't use short follow-on prompts such as "How do I pay for it?" or "How do I join it?" where the main Q/A pair relates to one of various services as these strings won't reliably return the intended answer. Rather, the prompts will have to be the more verbose "How do I pay for service A" and "How do I join service A".
Have I understood this correctly? I don't think the documentation makes this at all clear...
Multi-turn QnA Maker conversations are still in preview and there is currently no SDK to help you build a bot that knows how to interact with the follow-up prompt API. You are ultimately in control, and so you get to have your bot treat the display text however it wants. All the "display text" is is a value that you've inserted into an answer in your knowledge base so that it gets returned along with the answer after a call to generateAnswer.
It can be very helpful to have your display text match the text of the question you're linking to because then the prompt's display text can be used to access the correct follow-up QnA pair, so long as the context is included in the API call. That's what happens in this sample. It sounds like you want to get it to work without having the prompt's display text match the text of the follow-up question. That can get tricky, but here's something you can do.
Remember that you specify more than just display text when you make follow-up prompts. You also link to a specific QnA pair. This allows the API to return that QnA ID to you along with the display text. You haven't mentioned which channel your bot is targeting, but if you're using a channel that supports postBack or messageBack actions then you can pass the QnA ID to your bot invisibly and then your bot can use that to access the answer. If you go this route, you may not even need to worry about dialogs or state. You also haven't mentioned what language you're coding your bot in, but here's an example of how this might be implemented in Node.js:
async testQnAMaker(turnContext) {
var qna = new QnAMaker({
knowledgeBaseId: '<GUID>',
endpointKey: '<GUID>',
host: 'https://<APPNAME>.azurewebsites.net/qnamaker'
});
var value = turnContext.activity.value;
var qnaId = value && value.qnaId;
// qnaId will be undefined if value is empty
var results = await qna.getAnswers(turnContext, { qnaId });
var firstResult = results[0];
if (firstResult) {
var answer = firstResult.answer;
var resultContext = firstResult.context;
var prompts = resultContext && resultContext.prompts;
if (prompts && prompts.length) {
var card = CardFactory.heroCard(
answer,
[],
prompts.map(prompt => ({
type: 'messageBack',
title: prompt.displayText,
displayText: prompt.displayText,
text: prompt.displayText,
value: { qnaId: prompt.qnaId }
}))
);
answer = MessageFactory.attachment(card);
}
await turnContext.sendActivity(answer);
} else {
await turnContext.sendActivity("I can't answer that");
}
}
Note that this does have some limitations. Because it works by retreiving the QnA ID from the activity's value property, it may not be able to find the correct QnA pair if the user types in the text of the button manually instead of clicking the button.
If you want to make the display text work on its own without relying on the QnA ID, you could save your own mappings so that your bot knows which display text values correspond to each QnA ID in each context. However, you might also consider just adding the display text as an alternative phrasing of the question in the QnA pair. So "How do I pay for service A" and "How do I pay for service B" could both have "How do I pay for it" as a form of the question. Because you'll now have duplicated phrasings in multiple QnA pairs, you'll need to pass the context in your calls to generateAnswer for this to work.
See this answer for more info about multi-turn conversations.
we'd like to keep user on the same prompt when they enter the wrong number, we have tried anything_else, and "true", "jump to", but it messed up, please take a look at the attached to reproduce it, Thanks
pleae enter "how much"
if you enter 6, it will lock the prompt(I assign 1 to 5 to different identification), this behavior is correct .
then enter 2, we will get messed up...
please import this json to reproduce it, thanks
https://drive.google.com/file/d/0B1YdUMoS4l7ub1BZdUg1c1dQeG8/view?usp=sharing
The better form is use the entitie pre-defined by IBM, #sys-number to get numbers from the user input. And you can use use with conditions and to get the number with context variable too, check the JSON example:
{
"context": {
"number": "<? #sys-number ?>"
},
"output": {
"text": {
"values": [
"Now is $hora. Sector please?"
],
"selection_policy": "sequential"
}
}
}
If user type two or 2, the entitie recognize!
You can use regex expression to obtain only the numbers you have pre-defined too!
How to active: -> Entities -> System Entities -> sys-number = ON:
Obs.: Waiting Watson TRAINNING after you active this entitie.
Example, with sys-number add in your node condition:
#sys-number:1
Check the image:
If user type the number correct:
Check the dialog if user dont type the correct number with true condition:
I did the example for you understand what I do for that:
Download the JSON for verify how to do it with REGEX here.
Download the JSON for verify how to do it with SYS-NUMBER here.
EDIT:
Refer your questions
In this case you can use regex, and use the context variable for make conditions in other node. My workspace with regex can help you with numbers. And, the variable $number you can use in the next node to verify if the user typed correctly the number.
And, the other case is to use the Jump to inside conversation. And use true if the user dont type the number correctly again.
Check my image:
Download the new workspace here.
Study more about conditions here.
I have list of values defined in the values of array inside the text element.
Now, when the value of the aray is "Counting finished" I would like to route the flow to new node and pass some text to the user. How to achive the condition?
As that is output text the conversation tree can't see it unless you put it into the input or a context variable, and send it back into the tree.
The easier option is to create a counter. There is more details and an example conversation file here:
https://sodoherty.com/2016/09/22/using-counters-in-conversation/
Summary:
You create a context variable like countdown for example, and set it with a value to countdown from.
Then in your input text you can add the following code to initiate a decrement.
<? context.countdown-- ?>
This will be outputted though, so you can use a continue from to jump to another node which has append set to false. This will erase the counter from being displayed.
Optionally you can set the context variable directly like as follows.
{
"output": {
"text": "Decrementing countdown counter"
},
"context": {
"countdown": "<? context.countdown-- ?>"
}
}
This had issues in earlier versions of conversation though. I believe it should work now without issue.
Taking the car dashboard example, I altered the initial #genre node to be #genre:classical. I also added a list to the contex
"choices":["Beethoven","Mahler 9","Brahms 3rd"]
and the Watson response is "I have 3 selections". The condition on the next node is $choices.contains(input.text). The "Found a match" response is just for testing. It looks like this:
When I test this in the api tool and type "Beethoven" both "Found a match" and "Great choice!..." appear. Same for the other two choices, but only if I type the exact choice, e.g., "Mahler 9". Typing "Mahler" or "mahler" doesn't get a match. I read through the SpEL documentation but couldn't see a way in a one-line condition to parse through the list looking for partial matches.
So my question is, is there an condition expression that would match partial user input, e.g., "Mahler"? I'll be using the Java SDK to code the app server, so alternatively I wondered if I could add a temporary #entity just for this sequence instead of using the context list then delete it when the conversation is done? Or is there a way to construct a more complex condition in the MessageRequest and will Watson recognize it? Or is this just not the right way to go about this? Any pointers, examples or docs much appreciated.
So my question is, is there an condition expression that would match partial user input
You can't add temporary entities or intents. As adding them forces Watson to start training itself (even if you could it through code).
You can however create quite complex regular expressions, pass them in as a context variable.
For example your advanced node can have:
{
"output": {
"text": "Please ask me a question."
},
"context": {
"rx": "fish|[0-9]+"
}
}
Then in you condition you would write.
input.text.matches(context.rx)
This will then trigger if the person mentions a number, or the word fish. So you can create your partial user input checking that way.