Google操作无法解析JSON响应

时间:2018-01-31 11:29:19

标签: json parsing actions-on-google

我一直在努力让助理应用程序正确回应。

此应用程序是使用Google Actions SDK编写的(没有其他组件,如Dialogflow或Converse.ai)。

该应用的操作包如下所示:

{
    "actions":[
       {
         "description": "Default Welcome Intent",
         "name": "MAIN",
         "fulfillment": {
            "conversationName": "ACTION_INTENT_MAIN"
          },
          "intent": {
             "name": "actions.intent.MAIN",
             "trigger": {
                 "queryPatterns": [
                    "talk to gactions integration"
                  ]
             }
          }
       }
    ],
    "conversations":{
        "ACTION_INTENT_MAIN": {
           "name": "ACTION_INTENT_MAIN",
           "url": "https://my.custom.end/point"
        }
    },
    "locate":"en"
}

这是我在https://my.custom.end/pont上收到的JSON请求:

{
     "user": {
     "userId": "<a-user-id-sent-by-GOOG>",
     "locale": "en-US",
     "lastSeen": "2018-01-31T09:33:07Z"
   },
   "conversation": {
     "conversationId": "1517393479793",
     "type": "NEW"
   },
   "inputs": [
     {
       "intent": "actions.intent.MAIN",
       "rawInputs": [
         {
           "inputType": "KEYBOARD",
           "query": "Talk to Gactions Integration"
         }
       ]
     }
   ],
   "surface": {
     "capabilities": [
       {
         "name": "actions.capability.AUDIO_OUTPUT"
       },
       {
         "name": "actions.capability.SCREEN_OUTPUT"
       },
       {
         "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
       },
       {
         "name": "actions.capability.WEB_BROWSER"
       }
     ]
   },
   "isInSandbox": true,
   "availableSurfaces": [
     {
       "capabilities": [
         {
           "name": "actions.capability.AUDIO_OUTPUT"
         },
         {
           "name": "actions.capability.SCREEN_OUTPUT"
         }
       ]
     }
   ]
 }

在模拟器上,我最终得到了这个回复:API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: ": Cannot find field.".

我可以确认传入的请求已将google-actions-api-version设置为2

这是Google模拟器上的操作的sharedDebugInfo部分:

[
    {
      "name": "ResponseValidation",
      "subDebugEntry": [
        {
          "debugInfo": "API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: \": Cannot find field.\".",
          "name": "UnparseableJsonResponse"
        }
      ]
    }
  ]

信息量大的错误信息缺少无法找到的字段名称。

这就是我正在做的所有描述here

更新 - 2018年2月1日,上午11:52 这些是调试选项卡的全部内容:

{
  "audioResponse": "//NExAAQaE...",
  "conversationToken": "GidzaW11bG...",
  "debugInfo": {
    "agentToAssistantDebug": {
      "agentToAssistantJson": "{\"conversationToken\":\"{\\\"state\\\":null,\\\"data\\\":{}}\",\"expectUserResponse\":true,\"expectedInputs\":[{\"inputPrompt\":{\"noInputPrompts\":[],\"richInitialPrompt\":{\"items\":[{\"simpleResponse\":{\"textToSpeech\":\"You're now talking to GActions Integration\",\"displayText\":\"You're now talking to GActions Integration\"}},{\"basicCard\":{\"buttons\":[{\"title\":\"Some Reddit to chill\",\"openUrlAction\":{\"url\":\"https://www.reddit.com\"}}],\"formattedText\":\"Here's some simp-wave to relax and chill out to\",\"image\":{\"url\":\"http://tracks.arte.tv/sites/default/files/styles/jscrop_1007x566/public/c_simpsons_2.jpg?itok=INzKpsvK\",\"accessibilityText\":\"A World of Simpsonwave\"},\"title\":\"A World of Simpsonwave\",\"imageDisplayOptions\":\"CROPPED\"}}],\"suggestions\":[]}},\"possibleIntents\":[{\"intent\":\"actions.intent.TEXT\"}]}],\"resetUserStorage\":false,\"userStorage\":\"{}\",\"finalResponse\":null,\"isInSandbox\":true,\"customPushMessage\":null,\"speech\":\"You're now talking to GActions Integration. \",\"displayText\":\"You're now talking to GActions Integration. \"}"
    },
    "assistantToAgentDebug": {
      "assistantToAgentJson": "{\"user\":{\"userId\":\"ABwppHHHw9N9TYh-scJ5GhZtmpfFcQU2xbQBAgW1qhdllI45fimQ5QKFEVRfs2iMm6uCDJIQMApo1UZLmmnif8wqlNARnsVH744\",\"locale\":\"en-US\",\"lastSeen\":\"2018-02-01T06:04:59Z\"},\"conversation\":{\"conversationId\":\"1517465629416\",\"type\":\"NEW\"},\"inputs\":[{\"intent\":\"actions.intent.MAIN\",\"rawInputs\":[{\"inputType\":\"VOICE\",\"query\":\"Talk to Gactions Integration\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"},{\"name\":\"actions.capability.MEDIA_RESPONSE_AUDIO\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.SCREEN_OUTPUT\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"}]}]}",
      "curlCommand": "curl -v https://firedev.arrowai.com/integrations/goog-actions/messages/59f6b4bf8d16126f008b456a/5a619bf72c971189008b4569 -H 'Content-Type: application/json;charset=UTF-8' -H 'Google-Actions-API-Version: 2' -H 'Authorization: eyJhbGciOiJSUzI1NiIsImtpZCI6IjI2YzAxOGIyMzNmZTJlZWY0N2ZlZGJiZGQ5Mzk4MTcwZmM5YjI5ZDgifQ.eyJhdWQiOiJnYWN0aW9ucy1hcnJvd2FpLWludGVncmF0ZSIsImF6cCI6IjQ2NDA5MDk1NDc2Ny0xOWl2bnUxdjFwYXFpdWdodDJqYXJwcTJwaGtmNGRyMS5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImV4cCI6MTUxNzQ2NTc0OSwiaXNzIjoiaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tIiwianRpIjoiZTgxNzlmN2FkZGYwYWZmYjYwNzk0MDg5MzIyN2E0MWU1NDZkZWMyOCIsImlhdCI6MTUxNzQ2NTYyOSwibmJmIjoxNTE3NDY1MzI5fQ.rmUxBhIirV0UnZvTLYYw4AtRQfNDF-3O6CaoXxD2BDZSufgfKFHz7aIUgJzUillBm4zOLFiV6SnXndIoYCG6JK60YK5tHLpqbV-P3C-5U3N05RuY7hpj1Q_B027bgUv-p7QWlg-7DmPkROmN3b3a_FsUeWqTxx5Bu5M551k_CpKvSSBzPMEB2Cw9TzGkiY9avYrISTLLxWl2JE7qKAT6P0zBbE6cdO04CxGddGNmEPkckRICsdSJ5j_wmjy3I-ItAgx3dKoDfFLW6gCI4y5MFsGFJY6cFc2e01nodslf9GlQzAhR_a4aHRRIDl47HT_b9aKpyULV3kiRR41mUkyYZw'  -A 'Mozilla/5.0 (compatible; Google-Cloud-Functions/2.1; +http://www.google.com/bot.html)' -X POST -d '{\"user\":{\"userId\":\"ABwppHHHw9N9TYh-scJ5GhZtmpfFcQU2xbQBAgW1qhdllI45fimQ5QKFEVRfs2iMm6uCDJIQMApo1UZLmmnif8wqlNARnsVH744\",\"locale\":\"en-US\",\"lastSeen\":\"2018-02-01T06:04:59Z\"},\"conversation\":{\"conversationId\":\"1517465629416\",\"type\":\"NEW\"},\"inputs\":[{\"intent\":\"actions.intent.MAIN\",\"rawInputs\":[{\"inputType\":\"VOICE\",\"query\":\"Talk to Gactions Integration\"}]}],\"surface\":{\"capabilities\":[{\"name\":\"actions.capability.WEB_BROWSER\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"},{\"name\":\"actions.capability.SCREEN_OUTPUT\"},{\"name\":\"actions.capability.MEDIA_RESPONSE_AUDIO\"}]},\"isInSandbox\":true,\"availableSurfaces\":[{\"capabilities\":[{\"name\":\"actions.capability.SCREEN_OUTPUT\"},{\"name\":\"actions.capability.AUDIO_OUTPUT\"}]}]}'"
    },
    "sharedDebugInfo": [
      {
        "name": "ResponseValidation",
        "subDebugEntry": [
          {
            "debugInfo": "API Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: \": Cannot find field.\".",
            "name": "UnparseableJsonResponse"
          }
        ]
      }
    ]
  },
  "response": "Gactions integration isn't responding right now. Try again soon.",
  "visualResponse": {
    "visualElements": []
  }
}

这是agentToAssistantDebug对象:

{
  "conversationToken": "{\"state\":null,\"data\":{}}",
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "noInputPrompts": [],
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "You're now talking to GActions Integration",
                "displayText": "You're now talking to GActions Integration"
              }
            },
            {
              "basicCard": {
                "buttons": [
                  {
                    "title": "Some Reddit to chill",
                    "openUrlAction": {
                      "url": "https://www.reddit.com"
                    }
                  }
                ],
                "formattedText": "Here's some simp-wave to relax and chill out to",
                "image": {
                  "url": "http://tracks.arte.tv/sites/default/files/styles/jscrop_1007x566/public/c_simpsons_2.jpg?itok=INzKpsvK",
                  "accessibilityText": "A World of Simpsonwave"
                },
                "title": "A World of Simpsonwave",
                "imageDisplayOptions": "CROPPED"
              }
            }
          ],
          "suggestions": []
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ]
    }
  ],
  "resetUserStorage": false,
  "userStorage": "{}",
  "finalResponse": null,
  "isInSandbox": true,
  "customPushMessage": null,
  "speech": "You're now talking to GActions Integration. ",
  "displayText": "You're now talking to GActions Integration. "
}

此外,这是正在生成的JSON响应:

{
   "conversationToken": "{\"state\":null,\"data\":{}}",
   "expectUserResponse": true,
   "expectedInputs": [
     {
       "inputPrompt": {
         "noInputPrompts": [],
         "richInitialPrompt": {
           "items": [
             {
               "simpleResponse": {
                 "textToSpeech": "You're now talking to GActions Integration",
                 "displayText": "You're now talking to GActions Integration"
               }
             },
             {
               "basicCard": {
                 "buttons": [
                   {
                     "title": "Some Reddit to chill",
                     "openUrlAction": {
                       "url": "https://www.reddit.com"
                     }
                   }
                 ],
                 "formattedText": "Here's some simp-wave to relax and chill out to",
                 "image": {
                   "url": "http://tracks.arte.tv/sites/default/files/styles/jscrop_1007x566/public/c_simpsons_2.jpg?itok=INzKpsvK",
                   "accessibilityText": "A World of Simpsonwave"
                 },
                 "title": "A World of Simpsonwave",
                 "imageDisplayOptions": "CROPPED"
               }
             }
           ],
           "suggestions": []
         }
       },
       "possibleIntents": [
         {
           "intent": "actions.intent.TEXT"
         }
       ]
     }
   ],
   "resetUserStorage": false,
   "userStorage": "{}",
   "finalResponse": null,
   "isInSandbox": true,
   "customPushMessage": null,
   "speech": "You're now talking to GActions Integration. ",
   "displayText": "You're now talking to GActions Integration. "
 }

3 个答案:

答案 0 :(得分:2)

这个问题似乎与您的回复JSON有关。正如您在documentation中看到的有关响应JSON的内容。

for node_id in g.nodes:
    print g._node[node_id]['label'] # here, 'node_id' is the 'str' you said

以上都不是有效参数。相反,您的响应JSON应该如下所示:

"speech": "You're now talking to GActions Integration. ",
"displayText": "You're now talking to GActions Integration. "

答案 1 :(得分:0)

编辑如果你使用nodejs sdk检查来自google sdk函数的响应是否正确json以及你的服务器是否使用正确的json回答。也许它会改变格式等?

尝试使用与第一个类似的action.json样式。 更重要的问题是你对请求的回复看起来如何?尝试下面最后一个代码创建的样式中的json

{
  "locale": "en",
  "actions": [
    {
      "name": "text",
      "intent": {
        "name": "actions.intent.TEXT",
        "trigger": {
          "queryPatterns": [
            "some text"
          ]
        }
      },
      "fulfillment": {
        "conversationName": "conv name"
      }
    },
    {
      "description": "Default Welcome Intent",
      "name": "MAIN",
      "fulfillment": {
        "conversationName": "conv name"
      },
      "intent": {
        "name": "actions.intent.MAIN",
        "trigger": {
          "queryPatterns": [
            "open my test app",
            "open hi fish"
          ]
        }
      }
    }
  ],
  "types": [],
  "conversations": {
    "conv name": {
      "name": "conv name",
      "url": "https://yourendpoint.com/something",
      "fulfillmentApiVersion": 2,
      "in_dialog_intents": [
        {
          "name": "actions.intent.NO_INPUT"
        },
      ]
    }
  }
}

这是一个创建有效响应的函数:

/**
message = string
slots = array
state = object
**/

    function answerWithMessage(message,slots,state){   
           let display = message.replace(/<[^>]*>/g, '');   
           let voicemessage = message.toLowerCase();

          let jsonResponse = {
            conversationToken: JSON.stringify(state),
            expectUserResponse: true,
            expectedInputs: [
              {
                inputPrompt: {
                  richInitialPrompt: {
                    items: [
                      {
                        simpleResponse: {
                          ssml: voicemessage,
                          displayText: display,
                        },
                      }
                    ],
                  }
                },
                possibleIntents: [
                  {
                    intent: "actions.intent.TEXT"
                  }
                ],
               speechBiasingHints: slots
              }
            ]   
         };   
       return JSON.stringify(jsonResponse,null, 4); 
    }

这里有一个带有示例google actions sdk:https://github.com/haukedau/googleActionsInit的复制品,但是那里的答案并不完全正确,但它会完成上面的响应消息样式更好。

答案 2 :(得分:0)

您好我认为您的问题只是您调用了一个对象

    "inputPrompt": { 

和一个数组,但两者在同一位置看下面的解释。

    "noInputPrompts": [],

https://developers.google.com/actions/assistant/helpers#calling_the_helper_1

我希望我能帮到你。

最好的问候 帕特里克