Estoy implementando un webhookreceiver como una aplicación web ASP.Net Core para mi agente de Google Dialogflow. Para eso estoy usando el paquete nuget Google.Cloud.Dialogflow.V2 (1.0.0-beta02). Cuando Dialogflow coincide con una determinada intención, quiero que mi aplicación web ASP llame a la API TMDb para recuperar información sobre películas específicas. Me gustaría enviar esta información a Dialogflow como tarjetas de google. Para enviar cosas a Dialogflow, uso la clase WebhookResponse (proporcionada por Google.Cloud.Dialogflow.V2). Ahora mi problema radica en cómo hacer coincidir el patrón que Dialogflow espera, que se ve así:

"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
  }
]

Lo que he descubierto hasta ahora es que necesito que el Json anterior sea parte de la carga útil de la respuesta Webhook. (https://github.com/googleapis/google-cloud -dotnet / issues / 2425 # issuecomment-459885762)

Pero es difícil hacer coincidir el patrón anterior utilizando el método proporcionado en el comentario de Github. Sé que los objetos Json (todo entre un par de llaves) son equivalentes a esta línea de código

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

Lo que parece que no puedo descubrir es cuál es el equivalente a las matrices Json (todo entre un par de corchetes) Supongo que tengo que usar

Value.ForList()

Pero no se compilará cuando lo intente (vea el código a continuación cómo lo intenté).

 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")}
                                   })
                        } })
                }
           }

Se supone que este fragmento son las primeras 8 líneas de la estructura Json del primer Codeblock. (Intenté formatearlo lo mejor que pude, no debería faltar ningún paréntesis)

El error en VS2017 es:

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

¿Alguien sabe cómo usar Google.Protobuf o podría haber otra forma de hacer que mi agente de Dialogflow muestre tarjetas?

Cualquier ayuda es apreciada.

2
gertmenq 10 may. 2019 a las 16:30

3 respuestas

La mejor respuesta

Bien, gracias a la respuesta de Jon Skeets pude obtener el formato correcto para WebhookResponse, pero no funcionó como pensaba. Dialogflow necesita obtener la información para mostrar una tarjeta a través del atributo FulfillmentMessages que es de solo lectura. Mi solución era no usar la clase WebhookResponse en absoluto y simplemente enviar una cadena JSON que armé yo mismo. La cadena que envío de vuelta se ve así:

    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/""
                    }]
                }
    }]
}";
2
gertmenq 13 may. 2019 a las 10:43

Un Struct no es un Value en sí mismo; debe usar Struct.ForValue para crear el Value. Todo es algo detallado, pero funciona. Sin embargo, parece que buttons necesita ser otra lista de todos modos. Aquí hay un ejemplo completo que crea el JSON original para la carga útil:

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);
    }
}

Sospecho que algunos métodos de ayuda podrían hacer esto mucho más simple, pero esto al menos debería desbloquearte.

4
Jon Skeet 10 may. 2019 a las 13:56

Esta es una publicación antigua, pero la forma correcta de hacerlo usando la API de flujo de diálogo es:

FulfillmentMessages =
{
 new Intent.Types.Message
 {
     new Intent.Types.Message
       {
          Platform = Platform.ActionsOnGoogle,
          BasicCard = new BasicCard
          {
              Title = "<Your Title>",
              Subtitle="<Your SubTitle>",
              FormattedText = "<Your Text>",
              Image = new Image
              {    ImageUri = "<your Image Url>",
                   AccessibilityText = "<your text here>"
              },
           Buttons =
            {
               new BasicCard.Types.Button
                 {
                    Title = "<Your Button Text>",
                    OpenUriAction = new BasicCard.Types.Button.Types.OpenUriAction
                    {
                       Uri = "<your visit url>"
                    }
                }
              }
            }
          }
       }
     };

Espero que esto pueda ayudar a otros o a ti si es el caso, aún necesitas usar la v2 api

0
Ray 20 feb. 2020 a las 22:23