Reservierungen erstellen (Dialogflow)

Dieser Leitfaden führt Sie durch die Entwicklung eines Actions-Projekts. das die Orders API für Reservierungen nutzt.

Transaktionsablauf

Wenn in Ihrem Actions-Projekt Reservierungen verarbeitet werden, verwendet den folgenden Ablauf:

  1. Transaktionsanforderungen validieren (optional): Verwenden Sie den Hilfeassistenten für Transaktionsanforderungen. zu Beginn des Gesprächs ein, um sicherzustellen, dass die Nutzenden Durchführung einer Transaktion.
  2. Erstellen der Bestellung: Gehen Sie den Nutzer durch eine „cartmontage“ in dem sie die Details ihrer Reservierung angeben.
  3. Bestellung vorschlagen: Sobald der „Einkaufswagen“ abgeschlossen ist, schlagen Sie die Reservierung vor, bis damit diese die Richtigkeit bestätigen können. Wenn die Reservierung bestätigt wird, erhalten Sie eine Antwort mit Reservierungsdetails.
  4. Bestellung abschließen und Beleg senden: Sobald die Bestellung bestätigt wurde, aktualisieren Sie an Ihr Reservierungssystem senden und eine Quittung senden, für den Nutzer.
  5. Updates zu Bestellungen senden: Während der Laufzeit der Reservierung Aktualisierungen des Reservierungsstatus des Nutzers durch Senden von PATCH-Anfragen an den Orders API

Einschränkungen und Richtlinien für Überprüfungen

Beachten Sie, dass für Aktionen, die die Transaktionen und die Orders API verwenden, zusätzliche Richtlinien gelten. Die Überprüfung von Aktionen mit Transaktionen kann bis zu sechs Wochen dauern. Berücksichtigen Sie diese Zeit also bei der Planung Ihres Veröffentlichungszeitplans. Achte darauf, dass du die Richtlinien für Transaktionen einhältst, bevor du deine Aktion zur Überprüfung einreichst.

Aktionen, die die Orders API verwenden, können nur in den folgenden Ländern bereitgestellt werden:

Australien
Brasilien
Kanada
Indonesien
Japan
Mexiko
Katar
Russland
Singapur
Schweiz
Thailand
Türkei
Vereinigtes Königreich
USA

Projekt erstellen

Ausführliche Beispiele für Transaktionsunterhaltungen finden Sie in unseren Transaktionsbeispielen in Node.js und Java.

Projekt einrichten

Beim Erstellen der Aktion musst du angeben, dass du Transaktionen durchführen möchtest. in der Actions Console. Wenn Sie Node.JS-Clientbibliothek verwenden, die Auftragsausführung so einrichten, dass die neuesten der Orders API.

So richten Sie Ihr Projekt und die Auftragsausführung ein:

  1. Erstellen Sie ein neues Projekt oder importieren Sie ein vorhandenes Projekt.
  2. Gehen Sie zu Bereitstellen > Verzeichnisinformationen.
  3. Unter Weitere Informationen > Transaktionen > aktiviere das Kontrollkästchen „Führe deine Aktionen aus“ die Transactions API für Transaktionen mit physischen Waren verwenden?“.

  4. Wenn du die Node.JS-Clientbibliothek verwendest, um die Auftragsausführung für deine Aktion zu erstellen, Öffnen Sie den Auftragsausführungscode und aktualisieren Sie Ihre App-Bereitstellung, um die Flag ordersv3 in true. Das folgende Code-Snippet zeigt eine Beispiel-App: für Bestellungen Version 3.

Node.js

const {dialogflow} = require('actions-on-google');
let app = dialogflow({
  clientId, // If using account linking
  debug: true,
  ordersv3: true,
});

Node.js

const {actionssdk} = require('actions-on-google');
let app = actionssdk({
  clientId, // If using account linking
  debug: true,
  ordersv3: true,
});

1. Transaktionsanforderungen validieren (optional)

Nutzererfahrung

Sobald der Nutzer angegeben hat, dass er eine Reservierung einrichten möchte, empfiehlt es sich, das Ereignis actions.intent.TRANSACTION_REQUIREMENTS_CHECK-Intent, um sicherzustellen, dass sie eine Reservierung anfordern. Wenn deine Aktion beispielsweise aufgerufen wird, könnte sie Folgendes fragen: „Möchten Sie einen Platz reservieren?“ Wenn Nutzende sagen, „yes“, sollten Sie diesen Intent sofort anfordern. Dadurch wird sichergestellt, damit er fortfahren und die Möglichkeit hat, Einstellungen zu korrigieren. sodass er die Transaktion nicht fortsetzen kann.

Transaktionen anfordern Anforderungen prüfen Intents zu einem der folgenden Ergebnisse:

  • Wenn die Anforderungen erfüllt sind, erhält Ihre Auftragsausführung einen Intent mit einem und Sie können mit dem Aufbau der Bestellung für die Nutzenden fortfahren.
  • Ist eine oder mehrere Anforderungen nicht erfüllt, erhält Ihre Auftragsausführung Intent mit einer Fehlerbedingung. Beenden Sie in diesem Fall das Gespräch oder vom Reservierungsablauf weg.

    Wenn der Nutzer den Fehler beheben kann, wird er automatisch aufgefordert, die Probleme zu beheben. auf ihrem Gerät. Wenn das Gespräch auf einer Oberfläche nur mit Spracheingabe stattfindet wie ein intelligenter Lautsprecher, wird er an das Smartphone des Nutzers übergeben.

Auftragsausführung

Um sicherzustellen, dass Nutzende Anforderungen erfüllt, fordern Sie die Erfüllung der Intent actions.intent.TRANSACTION_REQUIREMENTS_CHECK mit einem Objekt TransactionRequirementsCheckSpec übergeben.

Anforderungen

Prüfen Sie mit der Clientbibliothek, ob ein Nutzer die Reservierungsanforderungen erfüllt:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
conv.ask(new TransactionRequirements());
<ph type="x-smartling-placeholder">
</ph>
Java
return getResponseBuilder(request)
    .add("Placeholder for transaction requirements text")
    .add(new TransactionRequirements())
    .build();
<ph type="x-smartling-placeholder">
</ph>
Dialogflow-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec"
        }
      }
    }
  }
}
<ph type="x-smartling-placeholder">
</ph>
Actions SDK-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TRANSACTION_REQUIREMENTS_CHECK",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionRequirementsCheckSpec"
          }
        }
      ]
    }
  ]
}
Ergebnis einer Anforderungsprüfung erhalten

Nachdem Assistant den Intent erfüllt hat, sendet er Ihnen eine Anfrage zur Auftragsausführung mit dem Intent actions.intent.TRANSACTION_REQUIREMENTS_CHECK und dem Ergebnis der Prüfung.

Deklarieren Sie einen Dialogflow-Intent, der durch Das actions_intent_TRANSACTION_REQUIREMENTS_CHECK-Ereignis. Wenn sie ausgelöst wird, wie dieser Intent bei der Auftragsausführung verarbeitet wird:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
const arg = conv.arguments.get('TRANSACTION_REQUIREMENTS_CHECK_RESULT');
if (arg && arg.resultType === 'CAN_TRANSACT') {
  // Normally take the user through cart building flow
  conv.ask(`Looks like you're good to go!`);
} else {
  conv.close('Transaction failed.');
}
<ph type="x-smartling-placeholder">
</ph>
Java
Argument transactionCheckResult = request
    .getArgument("TRANSACTION_REQUIREMENTS_CHECK_RESULT");
boolean result = false;
if (transactionCheckResult != null) {
  Map<String, Object> map = transactionCheckResult.getExtension();
  if (map != null) {
    String resultType = (String) map.get("resultType");
    result = resultType != null && resultType.equals("CAN_TRANSACT");
  }
}
ResponseBuilder responseBuilder = getResponseBuilder(request);
if (result) {
  responseBuilder.add("Looks like you're good to go! Now say 'confirm transaction'");
} else {
  responseBuilder.add("Transaction failed");
}
return responseBuilder.build();
<ph type="x-smartling-placeholder">
</ph>
Dialogflow-JSON

Im JSON-Format wird eine Webhook-Anfrage beschrieben.

{
  "responseId": "",
  "queryResult": {
    "queryText": "",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [],
    "intent": {
      "name": "reservation_transaction_check_complete_df",
      "displayName": "reservation_transaction_check_complete_df"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": ""
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [],
          "intent": "",
          "arguments": [
            {
              "extension": {
                "@type": "type.googleapis.com/google.transactions.v3.TransactionRequirementsCheckResult",
                "resultType": "CAN_TRANSACT"
              },
              "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT"
            }
          ]
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": ""
}
<ph type="x-smartling-placeholder">
</ph>
Actions SDK-JSON

Im JSON-Format wird eine Webhook-Anfrage beschrieben.

{
  "user": {},
  "device": {},
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "conversation": {},
  "inputs": [
    {
      "rawInputs": [],
      "intent": "reservation_transaction_check_complete_asdk",
      "arguments": [
        {
          "extension": {
            "@type": "type.googleapis.com/google.transactions.v3.TransactionRequirementsCheckResult",
            "resultType": "CAN_TRANSACT"
          },
          "name": "TRANSACTION_REQUIREMENTS_CHECK_RESULT"
        }
      ]
    }
  ],
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

2. Auftrag erstellen

Nutzererfahrung

Sobald Sie die benötigten Informationen haben, erstellen Sie einen Warenkorb Montage“ die den Nutzer dabei unterstützt, eine Reservierung vorzunehmen. Jeden Die Aktion unterscheidet sich je nach Bedarf des .

Bei einer einfachen Einkaufswagen-Montage wählt ein Nutzer Optionen aus einer Liste aus, um sie hinzuzufügen. Sie können das Gespräch jedoch so gestalten, User Experience aus. Erstellen Sie zum Beispiel eine Warenkorb-Montageumgebung, die die Nutzer können mit einer einfachen Ja-oder-Nein-Frage eine monatliche Reservierung vornehmen. Sie können dem Nutzer auch ein Karussell oder eine Listenkarte Reservierungen.

Wir empfehlen die Verwendung von Rich Media- Antworten, um die Optionen des Nutzers aber Sie sollten das Gespräch auch so gestalten, dass die Nutzenden ihre mit ihrer Stimme. Einige Best Practices und Beispiele für finden Sie in den Designrichtlinien für Transaktionen.

Auftragsausführung

Sammeln Sie während der gesamten Unterhaltung die Reservierungsdetails, die der Nutzer benötigt. und dann ein Order-Objekt zu erstellen.

Ihr Order muss mindestens Folgendes enthalten:

  • buyerInfo: Informationen zum Nutzer, der die Reservierung plant.
  • transactionMerchant – Informationen zum Händler, der die Teilnahme ermöglicht die Reservierung vornehmen.
  • contents: Die tatsächlichen Details der Reservierung, aufgeführt als lineItems.

Weitere Informationen finden Sie in der Antwortdokumentation zu Order. um Ihren Einkaufswagen zusammenzustellen. Möglicherweise müssen Sie verschiedene Felder abhängig von der Reservierung.

Der folgende Beispielcode zeigt einen vollständigen Reservierungsauftrag mit optionalen Feldern:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
app.intent('build_reservation_df', (conv) => {
  const now = new Date().toISOString();
  const order = {
    createTime: now,
    lastUpdateTime: now,
    merchantOrderId: 'UNIQUE_ORDER_ID',
    userVisibleOrderId: 'USER_VISIBLE_ORDER_ID',
    transactionMerchant: {
      id: 'https://www.example.com',
      name: 'Example Merchant',
    },
    contents: {
      lineItems: [
        {
          id: 'LINE_ITEM_ID',
          name: 'Dinner reservation',
          description: 'A world of flavors all in one destination.',
          reservation: {
            status: 'PENDING',
            userVisibleStatusLabel: 'Reservation is pending.',
            type: 'RESTAURANT',
            reservationTime: {
              timeIso8601: '2020-01-16T01:30:15.01Z',
            },
            userAcceptableTimeRange: {
              timeIso8601: '2020-01-15/2020-01-17',
            },
            partySize: 6,
            staffFacilitators: [
              {
                name: 'John Smith',
              },
            ],
            location: {
              zipCode: '94086',
              city: 'Sunnyvale',
              postalAddress: {
                regionCode: 'US',
                postalCode: '94086',
                administrativeArea: 'CA',
                locality: 'Sunnyvale',
                addressLines: [
                  '222, Some other Street',
                ],
              },
            },
          },
        },
      ],
    },
    buyerInfo: {
      email: 'janedoe@gmail.com',
      firstName: 'Jane',
      lastName: 'Doe',
      displayName: 'Jane Doe',
    },
    followUpActions: [
      {
        type: 'VIEW_DETAILS',
        title: 'View details',
        openUrlAction: {
          url: 'https://example.com',
        },
      },
      {
        type: 'CALL',
        title: 'Call us',
        openUrlAction: {
          url: 'tel:+16501112222',
        },
      },
      {
        type: 'EMAIL',
        title: 'Email us',
        openUrlAction: {
          url: 'mailto:person@example.com',
        },
      },
    ],
    termsOfServiceUrl: 'https://www.example.com',
  };
<ph type="x-smartling-placeholder">
</ph>
Java
private static OrderV3 createOrder() {
  // Transaction Merchant
  MerchantV3 transactionMerchant = new MerchantV3()
      .setId("http://www.example.com")
      .setName("Example Merchant");

  // Line Item

  // Reservation Item Extension
  ReservationItemExtension reservationItemExtension = new ReservationItemExtension()
      .setStatus("PENDING")
      .setUserVisibleStatusLabel("Reservation pending.")
      .setType("RESTAURANT")
      .setReservationTime(new TimeV3()
          .setTimeIso8601("2020-01-16T01:30:15.01Z"))
      .setUserAcceptableTimeRange(new TimeV3()
          .setTimeIso8601("2020-01-15/2020-01-17"))
      .setPartySize(6)
      .setStaffFacilitators(Collections.singletonList(new StaffFacilitator()
          .setName("John Smith")))
      .setLocation(new Location()
          .setZipCode("94086")
          .setCity("Sunnyvale")
          .setPostalAddress(new PostalAddress()
              .setRegionCode("US")
              .setPostalCode("94086")
              .setAdministrativeArea("CA")
              .setLocality("Sunnyvale")
              .setAddressLines(
                  Collections.singletonList("222, Some other Street"))));

  LineItemV3 lineItem = new LineItemV3()
      .setId("LINE_ITEM_ID")
      .setName("Dinner reservation")
      .setDescription("A world of flavors all in one destination.")
      .setReservation(reservationItemExtension);

  // Order Contents
  OrderContents contents = new OrderContents()
      .setLineItems(Collections.singletonList(lineItem));

  // User Info
  UserInfo buyerInfo = new UserInfo()
      .setEmail("janedoe@gmail.com")
      .setFirstName("Jane")
      .setLastName("Doe")
      .setDisplayName("Jane Doe");

  // Follow up actions
  Action viewDetails = new Action()
      .setType("VIEW_DETAILS")
      .setTitle("View details")
      .setOpenUrlAction(new OpenUrlAction()
          .setUrl("https://example.com"));

  Action call = new Action()
      .setType("CALL")
      .setTitle("Call us")
      .setOpenUrlAction(new OpenUrlAction()
          .setUrl("tel:+16501112222"));

  Action email = new Action()
      .setType("EMAIL")
      .setTitle("Email us")
      .setOpenUrlAction(new OpenUrlAction()
          .setUrl("mailto:person@example.com"));

  // Terms of service and order note
  String termsOfServiceUrl = "https://example.com";

  String now = Instant.now().toString();

  OrderV3 order = new OrderV3()
      .setCreateTime(now)
      .setLastUpdateTime(now)
      .setMerchantOrderId("UNIQUE_ORDER_ID")
      .setUserVisibleOrderId("UNIQUE_USER_VISIBLE_ORDER_ID")
      .setTransactionMerchant(transactionMerchant)
      .setContents(contents)
      .setBuyerInfo(buyerInfo)
      .setFollowUpActions(Arrays.asList(
          viewDetails,
          call,
          email
      ))
      .setTermsOfServiceUrl(termsOfServiceUrl);

  return order;
}
<ph type="x-smartling-placeholder">
</ph>
JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
          "order": {
            "createTime": "2019-07-17T18:25:30.182Z",
            "lastUpdateTime": "2019-07-17T18:25:30.182Z",
            "merchantOrderId": "UNIQUE_ORDER_ID",
            "userVisibleOrderId": "USER_VISIBLE_ORDER_ID",
            "transactionMerchant": {
              "id": "https://www.example.com",
              "name": "Example Merchant"
            },
            "contents": {
              "lineItems": [
                {
                  "id": "LINE_ITEM_ID",
                  "name": "Dinner reservation",
                  "description": "A world of flavors all in one destination.",
                  "reservation": {
                    "status": "PENDING",
                    "userVisibleStatusLabel": "Reservation is pending.",
                    "type": "RESTAURANT",
                    "reservationTime": {
                      "timeIso8601": "2020-01-16T01:30:15.01Z"
                    },
                    "userAcceptableTimeRange": {
                      "timeIso8601": "2020-01-15/2020-01-17"
                    },
                    "partySize": 6,
                    "staffFacilitators": [
                      {
                        "name": "John Smith"
                      }
                    ],
                    "location": {
                      "zipCode": "94086",
                      "city": "Sunnyvale",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94086",
                        "administrativeArea": "CA",
                        "locality": "Sunnyvale",
                        "addressLines": [
                          "222, Some other Street"
                        ]
                      }
                    }
                  }
                }
              ]
            },
            "buyerInfo": {
              "email": "janedoe@gmail.com",
              "firstName": "Jane",
              "lastName": "Doe",
              "displayName": "Jane Doe"
            },
            "followUpActions": [
              {
                "type": "VIEW_DETAILS",
                "title": "View details",
                "openUrlAction": {
                  "url": "https://example.com"
                }
              },
              {
                "type": "CALL",
                "title": "Call us",
                "openUrlAction": {
                  "url": "tel:+16501112222"
                }
              },
              {
                "type": "EMAIL",
                "title": "Email us",
                "openUrlAction": {
                  "url": "mailto:person@example.com"
                }
              }
            ],
            "termsOfServiceUrl": "https://www.example.com"
          },
          "orderOptions": {
            "requestDeliveryAddress": false,
            "userInfoOptions": {
              "userInfoProperties": [
                "EMAIL"
              ]
            }
          },
          "presentationOptions": {
            "actionDisplayName": "RESERVE"
          }
        }
      }
    }
  }
}

3. Bestellung vorschlagen

Präsentieren Sie dem Nutzer Ihre Reservierungsbestellung, damit er sie bestätigen kann. ablehnen. actions.intent.TRANSACTION_DECISION anfordern Intent und geben Sie die von Ihnen erstellte Order an.

User Experience

Wenn Sie den Intent actions.intent.TRANSACTION_DECISION anfordern, initiiert eine integrierte Websitevariante, in der die Order direkt auf einer „Warenkorb-Vorschaukarte“ gerendert. Die Nutzenden können „Reservierung planen“ sagen, die Transaktion ablehnen oder die Änderung der Reservierungsdetails anfordern.

Der Nutzer kann zu diesem Zeitpunkt auch Änderungen an der Bestellung anfordern. In diesem Fall sollten Sie dafür sorgen, dass die Auftragsausführung Anfragen für Bestelländerungen bearbeiten kann, den Einkaufswagen zusammenbauen.

Auftragsausführung

Wenn Sie die actions.intent.TRANSACTION_DECISION-Intent, erstellen Sie einen TransactionDecision, die Order enthält und orderOptions

Der folgende Code zeigt ein TransactionsDecision-Beispiel für eine Bestellung:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
conv.ask(new TransactionDecision({
  orderOptions: {
    requestDeliveryAddress: 'false',
  },
  presentationOptions: {
    actionDisplayName: 'RESERVE',
  },
  order: order,
}));
<ph type="x-smartling-placeholder">
</ph>
Java
// Create order options
OrderOptionsV3 orderOptions = new OrderOptionsV3()
    .setRequestDeliveryAddress(false)
    .setUserInfoOptions(new UserInfoOptions()
        .setUserInfoProperties(Collections.singletonList("EMAIL")));

// Create presentation options
PresentationOptionsV3 presentationOptions = new PresentationOptionsV3()
    .setActionDisplayName("RESERVE");

// Ask for transaction decision
return getResponseBuilder(request)
    .add("Placeholder for transaction decision text")
    .add(new TransactionDecision()
        .setOrder(order)
        .setOrderOptions(orderOptions)
        .setPresentationOptions(presentationOptions)
    )
    .build();
<ph type="x-smartling-placeholder">
</ph>
Dialogflow-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "systemIntent": {
        "intent": "actions.intent.TRANSACTION_DECISION",
        "data": {
          "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
          "orderOptions": {
            "requestDeliveryAddress": "false"
          },
          "presentationOptions": {
            "actionDisplayName": "RESERVE"
          },
          "order": {
            "createTime": "2019-07-17T18:25:30.184Z",
            "lastUpdateTime": "2019-07-17T18:25:30.184Z",
            "merchantOrderId": "UNIQUE_ORDER_ID",
            "userVisibleOrderId": "USER_VISIBLE_ORDER_ID",
            "transactionMerchant": {
              "id": "https://www.example.com",
              "name": "Example Merchant"
            },
            "contents": {
              "lineItems": [
                {
                  "id": "LINE_ITEM_ID",
                  "name": "Dinner reservation",
                  "description": "A world of flavors all in one destination.",
                  "reservation": {
                    "status": "PENDING",
                    "userVisibleStatusLabel": "Reservation is pending.",
                    "type": "RESTAURANT",
                    "reservationTime": {
                      "timeIso8601": "2020-01-16T01:30:15.01Z"
                    },
                    "userAcceptableTimeRange": {
                      "timeIso8601": "2020-01-15/2020-01-17"
                    },
                    "partySize": 6,
                    "staffFacilitators": [
                      {
                        "name": "John Smith"
                      }
                    ],
                    "location": {
                      "zipCode": "94086",
                      "city": "Sunnyvale",
                      "postalAddress": {
                        "regionCode": "US",
                        "postalCode": "94086",
                        "administrativeArea": "CA",
                        "locality": "Sunnyvale",
                        "addressLines": [
                          "222, Some other Street"
                        ]
                      }
                    }
                  }
                }
              ]
            },
            "buyerInfo": {
              "email": "janedoe@gmail.com",
              "firstName": "Jane",
              "lastName": "Doe",
              "displayName": "Jane Doe"
            },
            "followUpActions": [
              {
                "type": "VIEW_DETAILS",
                "title": "View details",
                "openUrlAction": {
                  "url": "https://example.com"
                }
              },
              {
                "type": "CALL",
                "title": "Call us",
                "openUrlAction": {
                  "url": "tel:+16501112222"
                }
              },
              {
                "type": "EMAIL",
                "title": "Email us",
                "openUrlAction": {
                  "url": "mailto:person@example.com"
                }
              }
            ],
            "termsOfServiceUrl": "https://www.example.com"
          }
        }
      }
    }
  }
}
<ph type="x-smartling-placeholder">
</ph>
Actions SDK-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TRANSACTION_DECISION",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.transactions.v3.TransactionDecisionValueSpec",
            "orderOptions": {
              "requestDeliveryAddress": "false"
            },
            "presentationOptions": {
              "actionDisplayName": "RESERVE"
            },
            "order": {
              "createTime": "2019-07-17T18:25:30.057Z",
              "lastUpdateTime": "2019-07-17T18:25:30.057Z",
              "merchantOrderId": "UNIQUE_ORDER_ID",
              "userVisibleOrderId": "USER_VISIBLE_ORDER_ID",
              "transactionMerchant": {
                "id": "https://www.example.com",
                "name": "Example Merchant"
              },
              "contents": {
                "lineItems": [
                  {
                    "id": "LINE_ITEM_ID",
                    "name": "Dinner reservation",
                    "description": "A world of flavors all in one destination.",
                    "reservation": {
                      "status": "PENDING",
                      "userVisibleStatusLabel": "Reservation is pending.",
                      "type": "RESTAURANT",
                      "reservationTime": {
                        "timeIso8601": "2020-01-16T01:30:15.01Z"
                      },
                      "userAcceptableTimeRange": {
                        "timeIso8601": "2020-01-15/2020-01-17"
                      },
                      "partySize": 6,
                      "staffFacilitators": [
                        {
                          "name": "John Smith"
                        }
                      ],
                      "location": {
                        "zipCode": "94086",
                        "city": "Sunnyvale",
                        "postalAddress": {
                          "regionCode": "US",
                          "postalCode": "94086",
                          "administrativeArea": "CA",
                          "locality": "Sunnyvale",
                          "addressLines": [
                            "222, Some other Street"
                          ]
                        }
                      }
                    }
                  }
                ]
              },
              "buyerInfo": {
                "email": "janedoe@gmail.com",
                "firstName": "Jane",
                "lastName": "Doe",
                "displayName": "Jane Doe"
              },
              "followUpActions": [
                {
                  "type": "VIEW_DETAILS",
                  "title": "View details",
                  "openUrlAction": {
                    "url": "https://example.com"
                  }
                },
                {
                  "type": "CALL",
                  "title": "Call us",
                  "openUrlAction": {
                    "url": "tel:+16501112222"
                  }
                },
                {
                  "type": "EMAIL",
                  "title": "Email us",
                  "openUrlAction": {
                    "url": "mailto:person@example.com"
                  }
                }
              ],
              "termsOfServiceUrl": "https://www.example.com"
            }
          }
        }
      ]
    }
  ]
}
Entscheidungen des Nutzers verarbeiten

Nachdem der Nutzer auf die vorgeschlagene Bestellung geantwortet hat, erhält Ihre Auftragsausführung Intent actions_intent_TRANSACTION_DECISION mit einem Argument, das einen TransactionDecisionValue. Dieser Wert enthält Folgendes:

  • transactionDecision – die Entscheidung des Nutzers in Bezug auf den Vorschlag Reihenfolge. Mögliche Werte sind ORDER_ACCEPTED, ORDER_REJECTED, CART_CHANGE_REQUESTED und USER_CANNOT_TRANSACT.

Deklarieren Sie zur Verarbeitung dieser Anfrage einen Dialogflow-Intent, der durch Das actions_intent_TRANSACTION_DECISION-Ereignis. Verarbeiten Sie diesen Intent in Ihre Auftragsausführung:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
const arg = conv.arguments.get('TRANSACTION_DECISION_VALUE');
if (arg && arg.transactionDecision === 'ORDER_ACCEPTED') {
  console.log('order accepted');
  const order = arg.order;
}
<ph type="x-smartling-placeholder">
</ph>
Java
Argument transactionDecisionValue = request
    .getArgument("TRANSACTION_DECISION_VALUE");
Map<String, Object> extension = null;
if (transactionDecisionValue != null) {
  extension = transactionDecisionValue.getExtension();
}

String transactionDecision = null;
if (extension != null) {
  transactionDecision = (String) extension.get("transactionDecision");
}
if ((transactionDecision != null && transactionDecision.equals("ORDER_ACCEPTED"))) {
  OrderV3 order = ((OrderV3) extension.get("order"));
}
<ph type="x-smartling-placeholder">
</ph>
Dialogflow-JSON

Im JSON-Format wird eine Webhook-Anfrage beschrieben.

{
  "responseId": "",
  "queryResult": {
    "queryText": "",
    "action": "",
    "parameters": {},
    "allRequiredParamsPresent": true,
    "fulfillmentText": "",
    "fulfillmentMessages": [],
    "outputContexts": [],
    "intent": {
      "name": "reservation_get_transaction_decision_df",
      "displayName": "reservation_get_transaction_decision_df"
    },
    "intentDetectionConfidence": 1,
    "diagnosticInfo": {},
    "languageCode": ""
  },
  "originalDetectIntentRequest": {
    "source": "google",
    "version": "2",
    "payload": {
      "isInSandbox": true,
      "surface": {
        "capabilities": [
          {
            "name": "actions.capability.SCREEN_OUTPUT"
          },
          {
            "name": "actions.capability.AUDIO_OUTPUT"
          },
          {
            "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
          },
          {
            "name": "actions.capability.WEB_BROWSER"
          }
        ]
      },
      "inputs": [
        {
          "rawInputs": [],
          "intent": "",
          "arguments": []
        }
      ],
      "user": {},
      "conversation": {},
      "availableSurfaces": [
        {
          "capabilities": [
            {
              "name": "actions.capability.SCREEN_OUTPUT"
            },
            {
              "name": "actions.capability.AUDIO_OUTPUT"
            },
            {
              "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
            },
            {
              "name": "actions.capability.WEB_BROWSER"
            }
          ]
        }
      ]
    }
  },
  "session": ""
}
<ph type="x-smartling-placeholder">
</ph>
Actions SDK-JSON

Im JSON-Format wird eine Webhook-Anfrage beschrieben.

{
  "user": {},
  "device": {},
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "conversation": {},
  "inputs": [
    {
      "rawInputs": [],
      "intent": "reservation_get_transaction_decision_asdk",
      "arguments": []
    }
  ],
  "availableSurfaces": [
    {
      "capabilities": [
        {
          "name": "actions.capability.SCREEN_OUTPUT"
        },
        {
          "name": "actions.capability.AUDIO_OUTPUT"
        },
        {
          "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
        },
        {
          "name": "actions.capability.WEB_BROWSER"
        }
      ]
    }
  ]
}

4. Reservierung abschließen und Beleg senden

Wenn der Intent actions.intent.TRANSACTION_DECISION mit einem transactionDecision von ORDER_ACCEPTED, mach was Verarbeitung erforderlich ist, um die Reservierung zu planen (z. B. Ihrer eigenen Datenbank).

Senden Sie eine einfache Antwort. um das Gespräch am Laufen zu halten. Der Nutzer erhält eine minimierte Belegkarte zusammen mit Ihrer Antwort.

Auftragsausführung

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
// Set lastUpdateTime and update status of reservation
order.lastUpdateTime = new Date().toISOString();
order.reservation.status = 'CONFIRMED';
order.reservation.userVisibleStatusLabel = 'Reservation confirmed';
order.reservation.confirmationCode = '123ABCDEFGXYZ';

// Send synchronous order update
conv.ask(`Transaction completed! You're all set!`);
conv.ask(new OrderUpdate({
  type: 'SNAPSHOT',
  reason: 'Reason string',
  order: order,
}));
<ph type="x-smartling-placeholder">
</ph>
Java
ResponseBuilder responseBuilder = getResponseBuilder(request);
order.setLastUpdateTime(Instant.now().toString());

// Set reservation status to confirmed and provide confirmation code
LineItemV3 lineItem = order.getContents().getLineItems().get(0);
ReservationItemExtension reservationItemExtension = lineItem.getReservation();
reservationItemExtension.setStatus("CONFIRMED");
reservationItemExtension.setUserVisibleStatusLabel("Reservation confirmed.");
reservationItemExtension.setConfirmationCode("123ABCDEFGXYZ");
lineItem.setReservation(reservationItemExtension);
order.getContents().getLineItems().set(0, lineItem);

// Order update
OrderUpdateV3 orderUpdate = new OrderUpdateV3()
    .setType("SNAPSHOT")
    .setReason("Reason string")
    .setOrder(order);

responseBuilder
    .add("Transaction completed! You're all set! Would you like to do anything else?")
    .add(new StructuredResponse().setOrderUpdateV3(orderUpdate));
return responseBuilder.build();
<ph type="x-smartling-placeholder">
</ph>
Dialogflow-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "Transaction completed! You're all set!"
            }
          },
          {
            "structuredResponse": {
              "orderUpdateV3": {
                "type": "SNAPSHOT",
                "reason": "Reason string",
                "order": {
                  "merchantOrderId": "UNIQUE_ORDER_ID",
                  "reservation": {
                    "status": "CONFIRMED",
                    "userVisibleStatusLabel": "Reservation confirmed",
                    "confirmationCode": "123ABCDEFGXYZ"
                  },
                  "lastUpdateTime": "2019-07-17T18:25:30.187Z"
                }
              }
            }
          }
        ]
      }
    }
  }
}
<ph type="x-smartling-placeholder">
</ph>
Actions SDK-JSON

Im folgenden JSON-Code wird eine Webhook-Antwort beschrieben.

{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT"
        }
      ],
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Transaction completed! You're all set!"
              }
            },
            {
              "structuredResponse": {
                "orderUpdateV3": {
                  "type": "SNAPSHOT",
                  "reason": "Reason string",
                  "order": {
                    "merchantOrderId": "UNIQUE_ORDER_ID",
                    "reservation": {
                      "status": "CONFIRMED",
                      "userVisibleStatusLabel": "Reservation confirmed",
                      "confirmationCode": "123ABCDEFGXYZ"
                    },
                    "lastUpdateTime": "2019-07-17T18:25:30.059Z"
                  }
                }
              }
            }
          ]
        }
      }
    }
  ]
}

5. Updates zu Bestellungen senden

Der Reservierungsstatus ändert sich im Laufe ihrer Lebensdauer. Aktualisierungen der Reservierungsreihenfolge des Nutzers mit HTTP senden PATCH-Anfragen an die Orders API, die den Bestellstatus und die Bestelldetails enthalten.

Asynchrone Anfragen an die Orders API einrichten

Anfragen zur Aktualisierung von Bestellungen an die Orders API sind durch einen Zugriff autorisiert Token. Lade eine JSON-Datei herunter, um ein Update für eine Bestellung per PATCH in die Orders API aufzunehmen. Dienstkontoschlüssel, der mit Ihrem Actions Console-Projekt verknüpft ist, und tauschen Sie dann Den Dienstkontoschlüssel für ein Inhabertoken, das an die Authorization-Header der HTTP-Anfrage.

So rufen Sie den Dienstkontoschlüssel ab:

  1. Führen Sie in der Google Cloud Console folgende Schritte aus: Gehe zum Menü Ђ > APIs und Dienste > Anmeldedaten > Anmeldedaten erstellen > Dienstkontoschlüssel.
  2. Wählen Sie unter Dienstkonto die Option Neues Dienstkonto aus.
  3. Legen Sie für das Dienstkonto service-account fest.
  4. Legen Sie die Rolle auf Projekt > Inhaber.
  5. Legen Sie den Schlüsseltyp auf JSON fest.
  6. Wählen Sie Erstellen aus.
  7. Ein privater JSON-Dienstkontoschlüssel wird auf Ihren lokalen Computer heruntergeladen.

Tauschen Sie im Code für Bestellaktualisierungen Ihren Dienstschlüssel gegen ein Inhabertoken ein mithilfe der Google APIs-Clientbibliothek und des Bereichs &quot;https://www.googleapis.com/auth/actions.order.developer&quot;. Dort finden Sie die Installationsschritte und Beispiele auf der GitHub-Seite der API-Clientbibliothek

Verweisen Sie auf order-update.js in unseren Node.js- und Java-Beispielen für ein Beispiel für den Schlüsselaustausch.

Updates zu Bestellungen senden

Nachdem du deinen Dienstkontoschlüssel gegen ein OAuth-Inhabertoken ausgetauscht hast, Bestellaktualisierungen als autorisierte PATCH-Anfragen an die Orders API.

Orders API-URL: PATCH https://actions.googleapis.com/v3/orders/${orderId}

Geben Sie in Ihrer Anfrage die folgenden Header an:

  • "Authorization: Bearer token" durch das OAuth-Inhabertoken für den Sie Ihren Dienstkontoschlüssel ausgetauscht haben.
  • "Content-Type: application/json".

Die PATCH-Anfrage sollte einen JSON-Text im folgenden Format annehmen:

{ "orderUpdate": OrderUpdate }

Die OrderUpdate besteht aus den folgenden Feldern der obersten Ebene:

  • updateMask: die Felder des Auftrags, den Sie aktualisieren So aktualisieren Sie die Reservierungsstatus, Legen Sie den Wert auf reservation.status, reservation.userVisibleStatusLabel fest.
  • order: Der Inhalt der Aktualisierung. Wenn Sie die der Reservierung enthält, legen Sie den Wert auf das aktualisierte Objekt Order fest. Wenn Sie nur den Status der Reservierung aktualisieren (z. B. von "PENDING" bis "FULFILLED"), enthält das Objekt den Parameter folgenden Feldern:

    • merchantOrderId: Dies ist die ID, die Sie im Objekt Order festgelegt haben.
    • lastUpdateTime: Der Zeitstempel dieser Aktualisierung.
    • purchase – ein Objekt, das Folgendes enthält: <ph type="x-smartling-placeholder">
        </ph>
      • status: der Status der Bestellung als ReservationStatus z. B. "CONFIRMED" oder "CANCELLED".
      • userVisibleStatusLabel – ein für den Nutzer sichtbares Label mit Details zu Bestellstatus, z. B. „Ihre Reservierung wurde bestätigt“.
  • userNotification (optional): A userNotification Objekt, das auf dem Gerät des Nutzers angezeigt werden kann, wenn dieses Update gesendet wird. Hinweis dass die Angabe dieses Objekts nicht garantiert, dass auf dem das Gerät der Nutzenden.

Der folgende Beispielcode zeigt ein OrderUpdate-Beispiel, mit dem die Status des Reservierungsauftrags auf FULFILLED:

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder">
</ph>
Node.js
// Import the 'googleapis' module for authorizing the request.
const {google} = require('googleapis');
// Import the 'request' module for sending an HTTP POST request.
const request = require('request');
// Import the OrderUpdate class from the Actions on Google client library.
const {OrderUpdate} = require('actions-on-google');
// Import the service account key used to authorize the request. Replace the string path with a path to your service account key.
const key = require('./service-account.json');
// Create a new JWT client for the Actions API using credentials from the service account key.
let jwtClient = new google.auth.JWT(
    key.client_email,
    null,
    key.private_key,
    ['https://www.googleapis.com/auth/actions.order.developer'],
    null
);
// Authorize the client asynchronously, passing in a callback to run upon authorization.
jwtClient.authorize((err, tokens) => {
    if (err) {
        console.log(err);
        return;
    }
    // Declare the ID of the order to update.
    const orderId = '<UNIQUE_MERCHANT_ORDER_ID>';

    const orderUpdateJson = new OrderUpdate({
        updateMask: [
          'lastUpdateTime',
          'contents.lineItems.reservation.status',
          'contents.lineItems.reservation.userVisibleStatusLabel',
      ].join(','),
        order: {
          merchantOrderId: orderId,
          lastUpdateTime: new Date().toISOString(),
          contents: {
            lineItems: [
              {
                reservation: {
                  status: 'FULFILLED',
                  userVisibleStatusLabel: 'Reservation fulfilled',
                },
              }
            ]
          }
        },
        reason: 'Reservation status was updated to fulfilled.',
    });

    // Set up the PATCH request header and body, including the authorized token
    // and order update.
    const bearer = 'Bearer ' + tokens.access_token;
    const options = {
        method: 'PATCH',
        url: `https://actions.googleapis.com/v3/orders/${orderId}`,
        headers: {
          'Authorization': bearer,
        },
        body: {
          header: {
            'isInSandbox': true,
          },
          orderUpdate: orderUpdateJson,
        },
        json: true,
      };
    // Send the PATCH request to the Orders API.
    request.patch(options, (err, httpResponse, body) => {
        if (err) {
            console.log('There was an error...');
            console.log(err);
            return;
        }
    });
});
<ph type="x-smartling-placeholder">
</ph>
Java
// Create order update
FieldMask fieldMask = FieldMask.newBuilder().addAllPaths(Arrays.asList(
    "lastUpdateTime",
    "contents.lineItems.reservation.status",
    "contents.lineItems.reservation.userVisibleStatusLabel"))
    .build();

OrderUpdateV3 orderUpdate = new OrderUpdateV3()
    .setOrder(new OrderV3()
        .setMerchantOrderId(orderId)
        .setLastUpdateTime(Instant.now().toString())
        .setContents(new OrderContents()
        .setLineItems(Collections.singletonList(new LineItemV3()
            .setReservation(new ReservationItemExtension()
                .setStatus("FULFILLED")
                .setUserVisibleStatusLabel("Reservation fulfilled."))))))
    .setUpdateMask(FieldMaskUtil.toString(fieldMask))
    .setReason("Reservation status was updated to fulfilled.");

// Setup JSON body containing order update
JsonParser parser = new JsonParser();
JsonObject orderUpdateJson =
    parser.parse(new Gson().toJson(orderUpdate)).getAsJsonObject();
JsonObject body = new JsonObject();
body.add("orderUpdate", orderUpdateJson);
JsonObject header = new JsonObject();
header.addProperty("isInSandbox", true);
body.add("header", header);
StringEntity entity = new StringEntity(body.toString());
entity.setContentType(ContentType.APPLICATION_JSON.getMimeType());
request.setEntity(entity);

// Make request
HttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse response = httpClient.execute(request);
Reservierungsstatus festlegen

ReservationStatus eines Bestellupdates muss den aktuellen Status der Bestellung beschreiben. Im order.ReservationStatus deines Updates einen der folgenden Werte verwenden:

  • PENDING: Die Reservierung wurde „erstellt“. Aktion ausgeführt. Er muss jedoch zusätzliche Verarbeitung im Back-End.
  • CONFIRMED: Die Reservierung wurde im Backend für die Planung bestätigt.
  • CANCELLED: Der Nutzer hat seine Reservierung storniert.
  • FULFILLED: Die Reservierung des Nutzers wurde vom Dienst erfüllt.
  • CHANGE_REQUESTED: Der Nutzer hat eine Reservierungsänderung angefordert, die: verarbeitet wird.
  • REJECTED – wenn Sie nicht in der Lage waren oder anderweitig verarbeitet werden konnten um die Reservierung zu bestätigen.

Senden Sie für jeden Status, der für Ihr Reservierung. Wenn Ihre Reservierung z. B. eine manuelle Verarbeitung erfordert, die Reservierung nach ihrer Anfrage bestätigen, eine Aktualisierung der Bestellung über PENDING senden bis dass eine zusätzliche Verarbeitung erfolgt. Nicht jede Reservierung erfordert jeden Statuswert.

Fehlerbehebung

Falls während des Tests Probleme auftreten, lesen Sie unsere Schritte zur Fehlerbehebung. für Transaktionen.