Jak renderować listę zwróconą przez webhook

Nov 06 2020

Używam Akcji Google. Zwracam kod JSON z mojego elementu webhook i otrzymuję następujący błąd podczas testowania akcji w symulatorze:

„Nie udało się wyrenderować monitu o listę lub kolekcję z powodu braku zastąpienia typu dla boksu. Uwaga: lista i kolekcja powinny być używane tylko do wypełniania boksu. Powinno istnieć odpowiednie zastąpienie typu opisujące sposób renderowania listy lub kolekcji dla tego typu. "

JSON to nieco zmodyfikowana próbka pobrana z dokumentów pod adresem https://developers.google.com/assistant/conversational/prompts-selection.

Nazwa typeOverrides „items” odpowiada nazwie slotu dla sceny.

Oto żądanie webhooka i odpowiedź JSON.

*** ŻĄDANIE ***

 {
  "handler": {
    "name": "aa"
  },
  "intent": {
    "name": "searchIntent",
    "params": {
      "searchParm": {
        "original": "milk",
        "resolved": "milk"
      }
    },
    "query": "milk"
  },
  "scene": {
    "name": "Start",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {},
    "next": {
      "name": "SearchScene"
    }
  },
  "session": {
    "id": "ABwppHGln0UTzfUPqJ1SMr1Cuw2TyPjJQoGUkULazcObus3vUwJCJCpba--5PSRwjqMQelRqMAUnwPvl",
    "params": {},
    "typeOverrides": [],
    "languageCode": ""
  },
  "user": {
    "locale": "en-AU",
    "params": {},
    "accountLinkingStatus": "ACCOUNT_LINKING_STATUS_UNSPECIFIED",
    "verificationStatus": "VERIFIED",
    "packageEntitlements": [],
    "lastSeenTime": "2020-11-05T21:24:16Z"
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

*** ODPOWIEDŹ ***

{
  "session": {
    "id": "ABwppHGln0UTzfUPqJ1SMr1Cuw2TyPjJQoGUkULazcObus3vUwJCJCpba--5PSRwjqMQelRqMAUnwPvl",
    "params": {},
    "typeOverrides": [
      {
        "name": "items",
        "synonym": {
          "entries": [
            {
              "name": "ITEM_1",
              "synonyms": [
                "Item 1",
                "First item"
              ],
              "display": {
                "title": "Item #1",
                "description": "Description of Item #1",
                "image": {
                  "alt": "Google Assistant logo",
                  "height": 0,
                  "url": "https://developers.google.com/assistant/assistant_96.png",
                  "width": 0
                }
              }
            },
            {
              "name": "ITEM_2",
              "synonyms": [
                "Item 2",
                "Second item"
              ],
              "display": {
                "title": "Item #2",
                "description": "Description of Item #2",
                "image": {
                  "alt": "Google Assistant logo",
                  "height": 0,
                  "url": "https://developers.google.com/assistant/assistant_96.png",
                  "width": 0
                }
              }
            },
            {
              "name": "ITEM_3",
              "synonyms": [
                "Item 3",
                "Third item"
              ],
              "display": {
                "title": "Item #3",
                "description": "Description of Item #3",
                "image": {
                  "alt": "Google Assistant logo",
                  "height": 0,
                  "url": "https://developers.google.com/assistant/assistant_96.png",
                  "width": 0
                }
              }
            },
            {
              "name": "ITEM_4",
              "synonyms": [
                "Item 4",
                "Fourth item"
              ],
              "display": {
                "title": "Item #4",
                "description": "Description of Item #4",
                "image": {
                  "alt": "Google Assistant logo",
                  "height": 0,
                  "url": "https://developers.google.com/assistant/assistant_96.png",
                  "width": 0
                }
              }
            }
          ]
        },
        "typeOverrideMode": "TYPE_REPLACE"
      }
    ]
  },
  "prompt": {
    "override": false,
    "content": {
      "list": {
        "items": [
          {
            "key": "ITEM_1"
          },
          {
            "key": "ITEM_2"
          },
          {
            "key": "ITEM_3"
          },
          {
            "key": "ITEM_4"
          }
        ],
        "subtitle": "List subtitle",
        "title": "List title"
      }
    },
    "firstSimple": {
      "speech": "This is a list.",
      "text": "This is a list."
    }
  }
}

Odpowiedzi

Prisoner Nov 06 2020 at 18:39

TypeOverride nazwa powinna odpowiadać Rodzaj gniazda, a nie nazwa gniazda.

CarlosHerrera Nov 27 2020 at 14:39

Dzielę się z wami rozwiązaniem tego problemu.

To prawda, że ​​dokumentacja pomija pewne części, aby to działało, ale jeśli zwrócimy uwagę na przeczytanie i przestrzeganie jej co do litery, to naprawdę działa.

Gdy już mamy projekt Actions Builder, pierwszą rzeczą, którą robimy, jest utworzenie encji w sekcji typów. Po prostu nie musimy dodawać danych wejściowych ani wartości, po prostu tworzymy typ.

Kolejnym krokiem jest przygotowanie sceny, w której pokażemy naszą kolekcję. W tym przypadku stworzyłem taki o nazwie INTRO.

Tutaj masz błąd. Próbujesz wyświetlić kolekcję w webhooku, który jest uruchamiany po wejściu na scenę. Nic tam nie ma, musi być puste.

Następnym krokiem jest dodanie typu slotu i nazwy. Musimy także skonfigurować jeszcze 2 rzeczy, jedną z nich jest to, aby wspomniane gniazdo było obowiązkowe, a drugą jest aktywowanie checkboxa, aby dzwonił do naszego handlera, który jest odpowiedzialny za malowanie kolekcji.

Jeśli zauważysz, nazwałem gniazdo: type_option i jest to typ prompt_type , czyli typ, który zadeklarowałem w pierwszym kroku. Następnie oznaczyłem ten slot jako wymagany i na koniec aktywowałem go, aby wywołać procedurę obsługi o nazwie LaunchRequest, która jest w moim webhooku.

Teraz zobaczmy kod.

const LaunchRequestHandler = app => {

  app.handle('LaunchRequest', conv => {
    conv.session.typeOverrides = [
      {
        name: 'prompt_option', // We reference the type of slot, not the name
        mode: 'TYPE_REPLACE',
        synonym: {
          entries: [
            {
              name: 'ITEM_1',
              synonyms: ['Item 1', 'First item'],
              display: {
                title: 'Element 1',
                description: 'This is the element 1',
                image: new Image({
                  url: '<YOUR URL>',
                  alt: 'example'
                })
              }
            },
            {
              name: 'ITEM_2',
              synonyms: ['Item 2', 'Second item'],
              display: {
                title: 'Element 2',
                description: 'This is the element 2',
                image: new Image({
                  url: '<YOUR URL>',
                  alt: 'example 2'
                })
              }
            }
          ]
        }
      }
    ];

    const items = [{ key: 'ITEM_1' }, { key: 'ITEM_2' }]

    conv.add(new Collection({ title: '<YOUR TITLE>', subtitle: '<YOUR SUBTITLE>', items }))
  })
}

Jest to fragment kodu, który konfigurujemy do wywołania, gdy chcemy zaprezentować kolekcję. Jeśli przyjrzymy się bliżej, odnosimy się do typu, a nie do nazwy gniazda.

Dzięki temu wszystko powinno działać, jeśli wykonamy test z symulatora. Wszystko jest perfekcyjne.

Mam nadzieję, że moja pomoc dobrze ci służyła.