Aktualisierung der asynchronen Bestellung

Nachdem ein Kunde eine Essensbestellung aufgegeben hat, kannst du eine Nachricht über die Aktualisierung der Bestellung an den End-to-End-Dienst für Bestellungen senden, um uns über die Änderung zu informieren.

Hier sind einige häufige Gründe für das Senden von Bestellaktualisierungen:

  • Die voraussichtliche Ausführungszeit für die Bestellung wird verfügbar oder ändert sich.
  • Der Status einer Bestellung ändert sich.
  • Die Bestellung kann nicht mehr ausgeführt werden.
  • Der Preis eines Artikels auf der Speisekarte, der in der Bestellung enthalten ist, hat sich geändert.
  • Der Kunde hat eine neue Möglichkeit, seine Bestellung zu verwalten, z. B. den Kundensupport oder die Telefonnummer des Restaurants.
  • Der Beleg für die Bestellung wird verfügbar.

In den nächsten Abschnitten wird beschrieben, wie Sie mit Bestellaktualisierungen auf diese verschiedenen Szenarien reagieren können.

Bestellstatus umstellen

Ein Auftrag hat sechs mögliche Status. Diese Zustände und ihre möglichen Übergänge sind im folgenden Diagramm dargestellt:

Übergänge des Bestellstatus

Wenn ein Kunde zum ersten Mal eine Bestellung aufgibt, beginnt die Bestellung mit dem Status CREATED, CONFIRMED oder REJECTED. Sie können eine Nachricht zur Bestellaktualisierung senden, um den Status einer Bestellung zu aktualisieren, solange der Statuswechsel gültig ist. Der Status CREATED wird verwendet, wenn die Plattform des Partners die Bestellung nicht sofort bestätigen oder ablehnen kann. Ein Beispiel für einen Anwendungsfall ist, wenn ein Kunde über einen Lieferdienstleister bestellt. Der Lieferdienstleister erhält die Lieferung von Google und der Dienstleister sendet die Informationen an das Restaurant. Sobald das Restaurant die Verfügbarkeit der Bestellung erhalten und bestätigt hat, kann der Status CONFIRMED lauten, andernfalls REJECTED.

Ein Auftrag mit dem Status CONFIRMED wird als Nächstes in den Status IN_PREPARATION verschoben. Je nachdem, ob zur Abholung oder Lieferung vorgesehen ist, verwende als Nächstes entweder den Bundesstaat READY_FOR_PICKUP oder IN_TRANSIT. Wenn das Essen geliefert oder abgeholt wurde, wird der Status der Bestellung auf FULFILLED gesetzt.

Wenn Sie Kunden erlauben, Bestellungen zu stornieren, können Sie den Status CANCELLED verwenden. Eine Bestellung kann storniert werden, wenn sie sich im Status CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP oder IN_TRANSIT befindet. Erstattungen sollten von Ihrem End-to-End-Bestellservice abhängig von Ihren Stornierungsrichtlinien und dem Zahlungsstatus zum Zeitpunkt der Stornierung veranlasst werden.

Ihr End-to-End-Bestelldienst muss nicht alle verfügbaren Status und Übergänge unterstützen. Der endgültige Zustand der Bestellung muss jedoch FULFILLED, REJECTED oder CANCELLED sein.

Geschätzte Ausführungszeit angeben

Du kannst Nutzern eine voraussichtliche Zeitspanne nennen, bis zu der ihre Bestellung zur Abholung (oder Lieferung) bereitsteht. Geben Sie im Feld estimatedFulfillmentTimeIso8601 von FoodOrderUpdateExtension einen geschätzten Zeitraum an, in dem die Bestellung eines Kunden zur Abholung oder Lieferung bereit ist.

Senden Sie estimatedFulfillmentTimeIso8601 zu folgenden Zeiten:

  • Wenn die geschätzte Zeit verfügbar wird, idealerweise im Status CREATED oder CONFIRMED.
  • Wenn sich die geschätzte Zeit ändert, z. B. eine Aktualisierung der geschätzten Zeit, um genauer zu sein, wenn die Bestellung IN_TRANSIT ist.

Um die Erwartungen der Nutzer effektiv zu erfüllen, geben Sie konservative Schätzungen an und geben Sie anstelle eines festen Datums und einer Uhrzeit ein Datum und einen Zeitraum an. Sie sollten nach Möglichkeit Abweichungen wie die Verkehrslage berücksichtigen. Beispiel: Für eine Bestellung mit einer voraussichtlichen Lieferzeit von 13:00 Uhr können Sie eine Schätzung von 12:45 Uhr (Untergrenze) bis 13:15 Uhr (Obergrenze) senden.

Bestellverwaltungsaktionen bereitstellen

Wenn du eine Bestellaktualisierung sendest, kannst du Kunden Ressourcen in Form einer OrderManagementAction zur Verfügung stellen, die ihnen bei der Verwaltung ihrer Bestellung helfen. Nachdem ein Kunde eine Bestellung aufgegeben hat, muss er sich möglicherweise an dich oder das Restaurant wenden, das die Bestellung aufgibt, um den Fortschritt zu verfolgen, Änderungen vorzunehmen oder die Bestellung zu stornieren.

Mit OrderManagementAction können Kunden direkt von ihrem Gerät aus eine E-Mail senden, anrufen oder eine URL verlinken. Verwenden Sie in OrderManagementAction dieselben Informationen wie in der E-Mail-Bestellbestätigung, die Sie an den Nutzer senden.

Zu den Bestellverwaltungsaktionen gehören die folgenden Arten:

  • CUSTOMER_SERVICE: Bietet Kunden die Möglichkeit, den Kundenservice zu kontaktieren. Dieser Verwaltungsaktionstyp ist für Bestellaktualisierungen erforderlich.
  • EMAIL: Geben Sie Kunden die Möglichkeit, eine E-Mail an die angegebene E-Mail-Adresse zu senden.
  • CALL: Bieten Sie Kunden die Möglichkeit, bei der angegebenen Telefonnummer anzurufen.
  • VIEW_DETAIL: Biete Kunden eine Aktion an, mit der sie die Details ihrer Bestellung aufrufen können.

Jede Bestellaktualisierung muss mindestens eine Bestellverwaltungsaktion enthalten. Die bereitgestellten Bestellverwaltungsaktionen können jedoch je nach Status der Bestellung variieren. Wenn eine Bestellung beispielsweise den Status CONFIRMED hat, kann die Aktion CUSTOMER_SERVICE auf die Telefonnummer deines Kundenservice verweisen. Wenn sich der Status dieser Bestellung zu IN_TRANSIT ändert, kann die Aktion CUSTOMER_SERVICE auf die Telefonnummer des Restaurants mit der Auftragsausführung verweisen.

Bestellaktualisierungen werden gesendet

Mit dem Nachrichtentyp AsyncOrderUpdateRequestMessage senden Sie eine Auftragsaktualisierung an den End-to-End-Dienst für Bestellvorgänge. Google antwortet mit einer AsyncOrderUpdateResponseMessage. Wenn Sie beispielsweise einen Kunden darüber informieren möchten, dass seine Bestellung gültig und angenommen wurde, können Sie eine AsyncOrderUpdateRequestMessage senden, um den Status der Bestellung mit dem Label Accepted by restaurant in CONFIRMED zu ändern.

Diagramm zur Bestellaktualisierung

Nachricht zur Aktualisierung der Bestellung einstellen

Wenn du eine AsyncOrderUpdateRequestMessage an Google sendest, musst du im Feld OrderUpdate Informationen zum Status der Bestellung angeben.

Die folgenden Beispiele zeigen ein AsyncOrderUpdateRequestMessage-Beispiel für jeden Bestellstatus:

BESTÄTIGT

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, durch die der Nutzer benachrichtigt wird, dass die Bestellung mit einem Beleg und einer voraussichtlichen Lieferzeit bestätigt wurde.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "CONFIRMED",
        "label": "Provider confirmed"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime": "2017-07-17T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "2017-07-17T13:00:00Z/2017-07-17T13:30:00Z"
      }
    }
  }
}
    

ABGELEHNT

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, in der der Nutzer darüber informiert wird, dass die Bestellung mit einem Ablehnungsgrund abgelehnt wurde.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "REJECTED",
        "label": "Order rejected"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "rejectionInfo": {
        "type": "UNKNOWN",
        "reason": "Sorry, the restaurant cannot take your order right now."
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
      "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
      "foodOrderErrors": [
        {
        "error": "NO_CAPACITY",
        "description": "Sorry, the restaurant cannot take your order right now."
        }
      ]
      }
    }
  }
}
    

CANCELLED

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, bei der der Nutzer darüber informiert wird, dass die Bestellung mit einem Stornierungsgrund storniert wurde.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "CANCELLED",
        "label": "Order cancelled"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "cancellationInfo": {
        "reason": "Customer requested"
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ]
    }
  }
}
    

IN_PREPARATION

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, mit der der Nutzer darüber informiert wird, dass das Essen gerade zubereitet wird.

{
  "isInSandbox":true,
  "customPushMessage":{
    "orderUpdate":{
      "actionOrderId":"sample_action_order_id",
      "orderState":{
        "state":"IN_PREPARATION",
        "label":"Order is being prepared"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime":"2018-04-15T11:30:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension":{
        "@type":"type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601":"PT20M"
      }
    }
  }
}
    

READY_FOR_PICKUP

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, mit der der Nutzer darüber informiert wird, dass das Essen abgeholt werden kann.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "READY_FOR_PICKUP",
        "label": "Order is ready for pickup"
      },
      "receipt": {
        "userVisibleOrderId": "userVisibleId1234"
      },
      "updateTime": "2018-04-15T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "PT20M"
      }
    }
  }
}
    

IN_TRANSIT

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, bei der der Nutzer mit einer voraussichtlichen Lieferzeit darüber informiert wird, dass die Bestellung auf dem Weg ist.

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
        "state": "IN_TRANSIT",
        "label": "Order is on the way"
      },
      "inTransitInfo": {
        "updatedTime": "2017-07-17T12:00:00Z"
      },
      "updateTime": "2017-07-17T12:00:00Z",
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ],
      "infoExtension": {
        "@type": "type.googleapis.com/google.actions.v2.orders.FoodOrderUpdateExtension",
        "estimatedFulfillmentTimeIso8601": "PT20M"
      }
    }
  }
}
  

ERFÜLLT

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, mit der der Nutzer darüber informiert wird, dass die Bestellung abgeholt oder geliefert wird:

{
  "isInSandbox": true,
  "customPushMessage": {
    "orderUpdate": {
      "actionOrderId": "sample_action_order_id",
      "orderState": {
      "state": "FULFILLED",
      "label": "Order delivered"
      },
      "updateTime": "2017-05-10T02:30:00.000Z",
      "fulfillmentInfo": {
        "deliveryTime": "2017-05-10T02:30:00.000Z"
      },
      "orderManagementActions": [
        {
          "type": "CUSTOMER_SERVICE",
          "button": {
            "title": "Contact customer service",
            "openUrlAction": {
              "url": "mailto:support@example.com"
            }
          }
        },
        {
          "type": "EMAIL",
          "button": {
            "title": "Email restaurant",
            "openUrlAction": {
              "url": "mailto:person@example.com"
            }
          }
        },
        {
          "type": "CALL_RESTAURANT",
          "button": {
            "title": "Call restaurant",
            "openUrlAction": {
              "url": "tel:+16505554679"
            }
          }
        },
        {
          "type": "CALL_DRIVER",
          "button": {
            "title": "Call driver",
            "openUrlAction": {
              "url": "tel:+16505554681"
            }
          }
        }
      ]
    }
  }
}
    

Weitere Beispiele für Bestellaktualisierungsanfragen in verschiedenen Anwendungsfällen finden Sie unter Erweiterte Bestellaktualisierungen implementieren.

Autorisierungstoken generieren und Nachricht senden

Bestellaktualisierungen erfordern ein Autorisierungstoken, mit dem der Bestell-End-to-End-Dienst prüfen kann, ob die Nachricht von Ihrem End-to-End-Webdienst für Bestellungen stammt.

So implementieren Sie Bestellaktualisierungen für Ihr Projekt:

  1. Generieren Sie mit den folgenden Schritten ein Autorisierungstoken:
    1. Verwenden Sie die Google-Authentifizierungsbibliothek, um die Anmeldedaten aus Ihrer Dienstkontodatei zu lesen.
    2. Fordern Sie ein Token mit dem folgenden API-Bereich an: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Verwenden Sie dieses Token, um eine authentifizierte HTTP-POST-Anfrage an folgenden Endpunkt zu senden: https://actions.googleapis.com/v2/conversations:send
  3. Legen Sie den Header Content-Type als Teil Ihrer Anfrage auf application/json fest.

Die folgenden Beispiele veranschaulichen, wie Bestellaktualisierungen implementiert werden:

Node.js

In diesem Code wird die Google-Authentifizierungsbibliothek für Node.js verwendet.

const {auth} = require('google-auth-library')
const request = require('request');
// The service account client secret file downloaded from the Google Cloud Console
const serviceAccountJson = require('./service-account.json')
// order-update.json is a file that contains the payload
const jsonBody = require('./order-update.json')

/**
 * Get the authorization token using a service account.
 */
async function getAuthToken() {
  let client = auth.fromJSON(serviceAccountJson)
  client.scopes = ['https://www.googleapis.com/auth/actions.fulfillment.conversation']
  const tokens = await client.authorize()
  return tokens.access_token;
}

/**
 * Send an order update request
 */
async function sendOrderUpdate() {
  const token = await getAuthToken()
  request.post({
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`
    },
    url: 'https://actions.googleapis.com/v2/conversations:send',
    body: jsonBody,
    json: true
  },
  (err, res, body) => {
    if (err) { return console.log(err); }
    console.log(`Response: ${JSON.stringify(res)}`)
  })
}
    

Python

In diesem Code wird die Google-Authentifizierungsbibliothek für Python verwendet.

from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
import json

# service-account.json is the service account client secret file downloaded from the
# Google Cloud Console
credentials = service_account.Credentials.from_service_account_file(
    'service-account.json')

scoped_credentials = credentials.with_scopes(
    ['https://www.googleapis.com/auth/actions.fulfillment.conversation'])

authed_session = AuthorizedSession(scoped_credentials)

# order-update.json is a file that contains the payload
json_payload=json.load(open('order-update.json'))

response = authed_session.post(
    'https://actions.googleapis.com/v2/conversations:send',
    json=json_payload)
    

Java

Dieser Code verwendet die Google-Authentifizierungsbibliothek für Java.

/**
 * Get the authorization token using a service account.
 */
private static String getAuthToken() {
  InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json");
  ServiceAccountCredentials.Builder credentialsSimpleBuilder =
      ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder();
  credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/actions.fulfillment.conversation"));
  AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken();
  return accessToken.getTokenValue();
}

/**
 * Send an order update request
 */
public void sendOrderUpdate() {
  String authToken = getAuthToken();
  // Execute POST request
  executePostRequest("https://actions.googleapis.com/v2/conversations:send",
      authToken, "update_order_example.json",);
}
    

Bei erfolgreichen Bestellaktualisierungen ohne Fehler gibt Google eine HTTP 200-Antwort mit einer leeren Nutzlast zurück. Wenn ein Problem aufgetreten ist, z. B. wenn das Update fehlerhaft ist, gibt Google einen Fehler zurück.