I am trying to build an Actions on Google Agent via DialogFlow and keep getting errors when trying to ask the user a question while including ssml.
I have built the agent on DialogFlow, have logic implemented using the fulfillment webhook (implemented via the node module dialogflow-fulfillment) and have been able to test on DialogFlow successfully using the test console on the right side DialogFlow.
I therefore hooked up the DialogFlow Integrations to Google Assistant.
I first tried unsuccessfully:
const client = new WebhookClient({ req, res });
let qToSnd = 'Hi <break time=\"500ms\"/> Can I help you?';
let conv = client.conv();
conv.ask(qToSnd);
client.add(conv);
The above would work (not give errors) but would result in the question being asked while speaking out the <break> tag.
I have also tried:
conv.ask(
new Text({
text: _stripTags(qToSnd),
ssml: qToSnd
}));
However, when I test this using the Actions on Google simulator I get the error message:
[Agent] isn't responding right now. Try again soon.
Digging into the logs viewer shows the following error message:
MalformedResponse: ErrorId: ... Failed to parse Dialogflow response into AppResponse because of invalid platform response. : Could not find a RichResponse or SystemIntent in the platform response for agentId: ... and intentId: ...
My fulfillment API is returning:
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"text": "Hi - Can I help you?",
"ssml": "Hi <break time=\"500ms\"/> Can I help you?"
}
]
}
}
}
}
I will appreciate any pointers in the right direction.
Looking at the JSON snippet for a simple response in the documentation, you should wrap your item in a simpleResponse element. Additionally, the keys you are using for text and audio responses are incorrect, and should be textToSpeech and displayText.
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Howdy, this is GeekNum. I can tell you fun facts about almost any number, my favorite is 42. What number do you have in mind?",
"displayText": "Howdy! I can tell you fun facts about almost any number. What do you have in mind?"
}
}
]
}
}
}
}
Inspired by #NickFelker's answer below and researching more into this topic, I was able to get the SSML working by making sure to add the <speak> tags. So this works:
const client = new WebhookClient({ req, res });
let qToSnd = 'Hi <break time=\"500ms\"/> Can I help you?';
let conv = client.conv();
conv.ask('<speak>' + qToSnd + '</speak>');
client.add(conv);
The fulfillment API returns:
{
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "<speak>Hi <break time=\"500ms\"/> Can I help you</speak>"
}
}
]
}
}
}
}
Related
We have created a bot on google assistant using https://console.actions.google.com/u/2/ and also have added our webhook to receive the user's message.
We are getting the user's message and we are also able to reply back to those messages. But the message that we send is getting reflected twice in the end-users mobile app.
Also, this is happening only when the user types the messages or selects any provided options. When the user provides a voice input we are able to get only a single response in the bot as expected.
Have attached the response that we return back in the API.
{
'conversationToken': 'USER_TOKEN',
'expectUserResponse': true,
'expectedInputs': [
{
'inputPrompt': {
'richInitialPrompt': {
"items": [
{
'simpleResponse': {
'textToSpeech': 'Hey there...',
'displayText': 'Hey there...'
}
}
],
'suggestions': false
}
},
'possibleIntents': [
{
'intent': 'actions.intent.TEXT'
}
]
}
]
};
How to send extra data to DialogFlow while calling it using some SDK?
I understand that in v1, originalRequest.data was used for this purpose.
Basically I want to send username, mobile number etc from website session and pass it to DialogFlow so that I can get it in webhook and perform some operation.
I am using below code to call DialogFlow:
import dialogflow
def detect_intent_texts(text, session_id):
session_client = dialogflow.SessionsClient()
session = session_client.session_path(project_id, session_id)
text_input = dialogflow.types.TextInput(
text=text, language_code=language_code)
query_input = dialogflow.types.QueryInput(text=text_input)
response = session_client.detect_intent(
session=session, query_input=query_input)
return response.query_result.fulfillment_text
detect_intent_texts('hello how are you', 'some_session_id')
You need to set parameters in the context.
create a context
add parameter
extract the context and parameter in the next interaction.
In JSON, it will look like this
{
"fulfillmentText":"This is a text response",
"fulfillmentMessages":[ ],
"source":"example.com",
"payload":{
"google":{ },
"facebook":{ },
"slack":{ }
},
"outputContexts":[
{
"name":"context name",
"lifespanCount":5,
"parameters":{
"param":"param value"
}
}
],
"followupEventInput":{ }
}
You can take a look how it can be done in python using create_context in dialogflow-python-client
I want to trigger my test issue's current status, for example A to B via Rest call.
I've searched on the web and come across Atlassian Documentation. What it says:
->You must use POST method.
->You must define transition id in rest call body. Like following:
{
"update": {
"comment": [
{
"add": {
"body": "Aok was here"
}
}
]
},
"transitions": {
"id": "471"
}
}
->You must construct an url like: http://test/jira/rest/api/latest/issue/{ISSUE-KEY}/transitions
When i test above with post-man, i get nothing but a white page response body.
What may be wrong here?
Thanks
Anyone who faces this problem, here is the solution:
You need to make http request with Content-Type:application/json in header.
I write a controller and it contain multi POST action but whene i post data to these actions my response is :
{ "name": "The request has been black-holed", "url": "/rest_sms_boxs.json" }
Now how can i resolve this problem.
Certainly the security mode.
Try in your controller:
public function beforeFilter()
{
parent::beforeFilter();
$this->Security->unlockedActions = array('your_method');
}
I get errors when posting prediction requests, but when posting the same requests from the online interface (from Google's API reference page) works well.
I have also posted a new issue on the Git repository, but it seems that no-one even looks at these issues. How lame of Google !!
Well I am posting predict request, which look like this:
var parameters = {
auth: jwtClient,
project: googleProjectID,
id: 'interest_classifier',
input: {
csvInstance: ["country united states", "/location/location"]
}
};
return prediction.trainedmodels.predict(parameters, function(err, response) {
if (err) {
logger.info(null, "prediction err ", err);
}
logger.info(null, "response from predict ", response);
return callback(null, response);
});
And I get this:
err { [Error: Input data invalid.]
code: 400,
errors:
[ { domain: 'global',
reason: 'invalidValue',
message: 'Input data invalid.' } ] }
To clarify: my trained model contains a value and two textual features.
Again, when running this from the online tool (client side) it works well, only when I run it from my node.js server, does it fail.
What's up with that? Anyone knows?
Could this be some encoding issue? request headers?
EDIT:
this is how i authenticate :
var jwtClient = new google.auth.JWT('*****#developer.gserviceaccount.com', 'keys/key.pem', null, ['https://www.googleapis.com/auth/prediction']);
jwtClient.authorize(function(err, tokens) {
logger.info(null, "authorizing");
if (err) {
logger.info(null, "error ", err);
} else {
return logger.info(null, "authenticated ", tokens);
}
});
OK,
So I've dug into Google's code and found out an important detail that is not properly documented.
I think this might be relevant to other people using this library, not only the ones who use google predict.
So most requests need to include a project id in the parameters, but in some cases you also need to include post data (like in my case).
I was trying to include this post data directly in the parameters like so :
var parameters = {
auth: jwtClient,
project: googleProjectID,
id: 'interest_classifier',
input: {
csvInstance: ["country united states", "/location/location"]
}
};
Now I found (this is not documented !!) that the whole part which belongs to the post data should be included within a "resource" field, like this:
var parameters = {
auth: jwtClient,
project: googleProjectID,
id: 'interest_classifier',
resource:{
input: {
csvInstance: ["country united states", "/location/location"]
}
}
};
I believe this will be relevant to any request which includes post data.
Cheers,
Ilan