How to use Google.Protobuf.WellknownTypes.Struct in ASP.Net Core

匆匆过客 提交于 2019-12-08 00:11:04

问题


I'm implementing a webhookreceiver as an ASP.Net Core Webapp for my Google Dialogflow Agent. For that I'm using the Google.Cloud.Dialogflow.V2(1.0.0-beta02) nuget package. When a certain intent is matched by Dialogflow I want my ASP webapp to call the TMDb API to retrieve information on specfic movies. I'd like to send this information back to Dialogflow as google cards. To send stuff back to Dialogflow I use the WebhookResponse class (provided by Google.Cloud.Dialogflow.V2). Now my problem lies in how to match the pattern that Dialogflow expects, which looks like this:

"messages": [
  {
    "buttons": [
      {
        "postback": "Card Link URL or text",
        "text": "Card Link Title"
      }
    ],
    "imageUrl": "http://urltoimage.com",
    "platform": "facebook",
    "subtitle": "Card Subtitle",
    "title": "Card Title",
    "type": 1
  }
]

What I've found out so far is that I need the above Json to be part of the Payload of the Webhookresponse. (https://github.com/googleapis/google-cloud-dotnet/issues/2425#issuecomment-459885762)

But it's difficult to match the above pattern using the method provided in the Github comment. I know that Json Objects (everything between a pair of curly brackets) are equivalent to this line of code

Value.ForStruct(new Struct { Fields = { ["expectUser"] = Value.ForBool(true) } })

What I can't seem to find out is what is the equivalent to Json Arrays(everything between a pair of square brackets) I assume that I have to use

Value.ForList()

But it won't compile when i try it (see code below how i tried it).

 Payload = new Struct {
               Fields ={["messages"] = Value.ForList(new Struct {
                        Fields = {["buttons"] = Value.ForStruct(new Struct {
                                   Fields = {["postback"] = Value.ForString("Card link url or test"),
                                             ["text"] = Value.ForString("card link title")}
                                   })
                        } })
                }
           }

This snippet is supposed to be the first 8 lines of the Json structure from the first Codeblock. (I've tried formatting it as good as I can, there shouldn't be any missing brackets)

The error in VS2017 is:

Argument 1: cannot convert from 'Google.Protobuf.WellKnownTypes.Struct' to 'Google.Protobuf.WellKnownTypes.Value'

Does anyone know how to use Google.Protobuf or might there be another way of getting my Dialogflow agent to display cards?

Any help is appreciated.


回答1:


A Struct isn't a Value in itself - you need to use Struct.ForValue to create the Value. It's all somewhat verbose, but it does work. However, it looks like buttons needs to be another list anyway. Here's a complete example which creates the original JSON for the payload:

using Google.Protobuf.WellKnownTypes;
using System;

class Program
{
    static void Main(string[] args)
    {
        var button = Value.ForStruct(new Struct
        {
            Fields =
            {
                ["postback"] = Value.ForString("Card Link URL or text"),
                ["text"] = Value.ForString("Card Link Title")
            }
        });
        var message = Value.ForStruct(new Struct
        {
            Fields =
            {
                ["buttons"] = Value.ForList(button),
                ["imageUrl"] = Value.ForString("http://urltoimage.com"),
                ["platform"] = Value.ForString("facebook"),
                ["subtitle"] = Value.ForString("Card Subtitle"),
                ["title"] = Value.ForString("Cart Title"),
                ["type"] = Value.ForNumber(1)
            }
        });
        var payload = new Struct { Fields = { ["messages"] = Value.ForList(message) } };
        Console.WriteLine(payload);
    }
}

I suspect some helper methods could make this a lot simpler, but this should at least unblock you.




回答2:


Okay so thanks to Jon Skeets answer I was able to get the right format for the WebhookResponse, but it didn't work as I thought. Dialogflow needs to get the Information to display a card via the FulfillmentMessages Attribute which is read-only. My workaround was to not use the WebhookResponse class at all and to just send back a JSON string I put together myself. The string I send back looks like this:

    string testResponse = @"{
  ""fulfillmentText"": ""This is a text response"",
  ""fulfillmentMessages"": [
    {
                ""card"":
                {
                    ""title"": ""card title"",
                    ""subtitle"": ""card text"",
                    ""imageUri"": ""https://assistant.google.com/static/images/molecule/Molecule-Formation-stop.png"",
                    ""buttons"": [
                    {
                        ""text"": ""button text"",
                        ""postback"": ""https://assistant.google.com/""
                    }]
                }
    }]
}";


来源:https://stackoverflow.com/questions/56078753/how-to-use-google-protobuf-wellknowntypes-struct-in-asp-net-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!