Asynchrone Bestellaktualisierung

Nachdem ein Kunde eine Essensbestellung aufgegeben hat, können Sie eine Nachricht zum Aktualisieren der Bestellung an den End-to-End-Bestellservice senden, um uns über die Änderung zu informieren.

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

  • Die voraussichtliche Auftragserfüllung 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 in der Bestellung enthaltenen Menüpunkts hat sich geändert.
  • Der Kunde hat eine neue Möglichkeit, seine Bestellung zu verwalten, z. B. eine Telefonnummer des Kundensupports oder des Restaurants.
  • Der Beleg für die Bestellung ist verfügbar.

In den folgenden Abschnitten erfahren Sie, wie Sie diese verschiedenen Szenarien mithilfe von Bestellaktualisierungen beheben können.

Statusänderungen bei Bestellungen

Eine Bestellung kann sechs Status haben. Diese Status und ihre möglichen Übergänge sind im folgenden Diagramm dargestellt:

Statusänderungen bei Bestellungen

Wenn ein Kunde zum ersten Mal eine Bestellung aufgibt, beginnt die Bestellung mit dem Status CREATED, CONFIRMED oder REJECTED. Sie können eine Bestellaktualisierungsnachricht senden, um den Status einer Bestellung zu aktualisieren, sofern der Statusübergang gültig ist. Der Status CREATED wird verwendet, wenn die Bestellung auf der Plattform des Partners nicht sofort bestätigt oder abgelehnt werden kann. Ein Beispiel für einen Anwendungsfall ist, wenn ein Kunde über einen Lieferaggregator bestellt. Der Lieferaggregator empfängt die Bestellung von Google und sendet die Informationen an das Restaurant. Sobald das Restaurant die Verfügbarkeit der Bestellung erhalten und bestätigt hat, kann der Status jetzt CONFIRMED sein, andernfalls REJECTED.

Eine Bestellung im Status CONFIRMED wechselt als Nächstes in den Status IN_PREPARATION. Je nachdem, ob die Bestellung zur Abholung oder Lieferung ist, verwenden Sie als Nächstes den Status READY_FOR_PICKUP oder IN_TRANSIT. Wenn das Essen geliefert oder abgeholt wurde, wird der Status der Bestellung auf FULFILLED gesetzt.

Wenn Sie es Kunden erlauben, Bestellungen zu stornieren, können Sie den Status CANCELLED verwenden. Eine Bestellung kann im Status CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP oder IN_TRANSIT storniert werden. Ihr End-to-End-Bestellservice sollte Erstattungen vornehmen, je nach Ihren Kündigungsrichtlinien und dem Zahlungsstatus zum Zeitpunkt der Kündigung.

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

Voraussichtliche Auftragserfüllung angeben

Sie können Nutzern einen geschätzten Zeitraum angeben, in dem ihre Bestellung zur Abholung bereit ist (oder geliefert wird). Verwenden Sie das Feld estimatedFulfillmentTimeIso8601 von FoodOrderUpdateExtension, um einen geschätzten Zeitraum anzugeben, in dem die Bestellung eines Kunden zur Abholung bereitsteht oder geliefert wird.

Senden Sie die estimatedFulfillmentTimeIso8601 zu den folgenden Zeiten:

  • Sobald die geschätzte Zeit verfügbar ist, idealerweise wenn der Bestellstatus CREATED oder CONFIRMED ist.
  • Wenn sich die geschätzte Zeit ändert, z. B. wenn die geschätzte Zeit aktualisiert wird, um genauer zu sein, wenn die Bestellung IN_TRANSIT ist.

Um die Erwartungen der Nutzer effektiv zu steuern, sollten Sie konservativ schätzen und einen Zeitraum angeben, anstatt ein festes Datum und eine feste Uhrzeit. Sie sollten nach Möglichkeit auch Faktoren wie die Verkehrslage berücksichtigen. Sie können beispielsweise eine Schätzung von 12:45 Uhr (untere Grenze) bis 13:15 Uhr (obere Grenze) für eine Bestellung senden, bei der die geschätzte Lieferzeit 13:00 Uhr ist.

Aktionen zur Bestellverwaltung bereitstellen

Wenn Sie eine Bestellaktualisierung senden, können Sie Kunden Ressourcen in Form eines OrderManagementAction zur Verfügung stellen, mit denen sie ihre Bestellung verwalten können. Nachdem ein Kunde eine Bestellung aufgegeben hat, muss er sich möglicherweise an Sie oder das Restaurant wenden, das die Bestellung ausführt, um den Fortschritt zu verfolgen, Änderungen vorzunehmen oder die Bestellung zu stornieren.

Mit einem OrderManagementAction können Kunden direkt über ihr Gerät 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 Aktionen zur Bestellverwaltung gehören die folgenden Typen:

  • CUSTOMER_SERVICE: Bieten Sie Kunden eine Möglichkeit, den Kundenservice zu kontaktieren. Dieser Verwaltungsaktionstyp ist für die Aktualisierung von Bestellungen erforderlich.
  • EMAIL: Bieten Sie Kunden die Möglichkeit, eine E-Mail an die angegebene E-Mail-Adresse zu senden.
  • CALL: Kunden die Möglichkeit geben, die angegebene Telefonnummer anzurufen.
  • VIEW_DETAIL: Bieten Sie Kunden eine Aktion an, mit der sie sich die Details ihrer Bestellung ansehen können.

Jede Bestellaktualisierung muss mindestens eine Aktion zur Bestellverwaltung enthalten. Die verfügbaren Aktionen zur Bestellverwaltung können jedoch je nach Status der Bestellung variieren. Wenn sich eine Bestellung beispielsweise im Status CONFIRMED befindet, kann die Aktion CUSTOMER_SERVICE auf Ihre Kundenservicetelefonnummer verweisen. Wenn dieser Bestellstatus in IN_TRANSIT aktualisiert wird, kann die Aktion CUSTOMER_SERVICE auf die Telefonnummer des Restaurants verweisen, das die Bestellung ausführt.

Bestellupdates senden

Mit dem Nachrichtentyp AsyncOrderUpdateRequestMessage senden Sie eine Bestellaktualisierung an den End-to-End-Bestellservice. 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 Bestellaktualisierung festlegen

Wenn Sie eine AsyncOrderUpdateRequestMessage an Google senden, müssen Sie im Feld OrderUpdate Informationen zum Status der Bestellung angeben.

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

BESTÄTIGT

Dieses Beispiel zeigt eine Beispielanfrage zur Aktualisierung einer Bestellung, über die der Nutzer darüber informiert wird, dass die Bestellung mit einem Beleg und einer geschätzten 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 Anfrage zum Aktualisieren einer Bestellung, bei der der Nutzer darüber informiert wird, dass die Bestellung abgelehnt wurde, und den Ablehnungsgrund enthält.

{
  "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 zum Aktualisieren einer Bestellung, bei der der Nutzer über die Stornierung der Bestellung mit einem Stornierungsgrund informiert wird.

{
  "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 Anfrage zum Aktualisieren einer Bestellung, bei der der Nutzer darüber informiert wird, dass die Speisen gerade zubereitet werden.

{
  "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 Anfrage zum Aktualisieren einer Bestellung, über die der Nutzer darüber informiert wird, dass die Bestellung 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 zum Aktualisieren einer Bestellung, in der der Nutzer darüber informiert wird, dass die Bestellung auf dem Weg ist, und eine geschätzte Lieferzeit angegeben wird.

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

AUSGEFÜHRT

Dieses Beispiel zeigt eine Beispielanfrage zum Aktualisieren einer Bestellung, über die der Nutzer darüber informiert wird, dass die Bestellung abgeholt oder geliefert wurde:

{
  "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 Aktualisierungsanfragen für Bestellungen in verschiedenen Anwendungsfällen finden Sie unter Erweiterte Aktualisierungen von Bestellungen implementieren.

Autorisierungstoken generieren und Nachricht senden

Für Bestellaktualisierungen ist ein Autorisierungstoken erforderlich, damit der Ordering End-to-End-Dienst prüfen kann, ob die Nachricht von Ihrem Ordering End-to-End-Webdienst stammt.

So implementieren Sie Auftragsaktualisierungen für Ihr Projekt:

  1. So generieren Sie ein Autorisierungstoken:
    1. Verwenden Sie die Google Authentifizierungsbibliothek, um die Anmeldedaten aus Ihrer Dienstkontodatei zu lesen.
    2. Fordere ein Token mit dem folgenden API-Umfang an: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Verwende dieses Token, um eine authentifizierte HTTP-POST-Anfrage an den folgenden Endpunkt zu senden: https://actions.googleapis.com/v2/conversations:send.
  3. Setzen Sie den Header Content-Type in Ihrer Anfrage auf application/json.

In den folgenden Beispielen wird gezeigt, wie Sie Bestellaktualisierungen implementieren:

Node.js

In diesem Code wird die Google Auth-Bibliothek 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 Auth-Bibliothek 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

In diesem Code wird die Google Auth-Bibliothek für Java verwendet.

/**
 * 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-Antwort 200 mit einer leeren Nutzlast zurück. Wenn ein Problem aufgetreten ist, z. B. wenn das Update fehlerhaft ist, gibt Google einen Fehler zurück.