Mise à jour de la commande asynchrone

Lorsqu'un client envoie une commande de repas, vous pouvez envoyer un message de mise à jour de commande à le service de commande de bout en bout pour nous informer du changement.

Voici quelques raisons courantes pour lesquelles vous pouvez envoyer des mises à jour de commandes:

  • Le délai de traitement estimé de la commande devient disponible ou est modifié.
  • L'état d'un ordre change.
  • La commande ne peut plus être traitée.
  • Le prix d'un élément de menu inclus dans la commande a été modifié.
  • Le client dispose d'une nouvelle façon de gérer sa commande, comme un service client ou le numéro de téléphone du restaurant.
  • Le reçu de la commande est alors disponible.

Les sections suivantes fournissent des détails sur la façon de traiter ces différents scénarios à l'aide de mises à jour des commandes.

Transition des états des commandes

Un ordre a six états possibles. Ces états et leurs éventuelles transitions sont décrits dans le schéma suivant:

Transitions d'état de commande

Lorsqu'un client envoie une commande pour la première fois, celle-ci commence par l'état CREATED, CONFIRMED ou REJECTED. Vous pouvez envoyer un message de mise à jour de commande à mettre à jour l'état d'un ordre, tant que la transition d'état est valide. CREATED est utilisé lorsque la plate-forme du partenaire ne peut pas confirmer ni refuser la commande immédiatement. Exemple de cas d'utilisation : lorsqu'un client passe une commande via un agrégateur. L'agrégateur de diffusion reçoit la livraison de la part de Google, et envoie les informations au restaurant. Une fois que le restaurant a reçu et confirmé la disponibilité de la commande, l'état peut maintenant être CONFIRMED. Sinon, REJECTED

Une commande à l'état CONFIRMED passe ensuite à l'état IN_PREPARATION. Selon que la commande est en retrait ou en livraison, utilisez ensuite l'état READY_FOR_PICKUP ou IN_TRANSIT. Lorsque les plats sont livrés ou retirés, la commande est définie sur l'état FULFILLED.

Si vous autorisez les clients à annuler des commandes, vous pouvez utiliser l'état CANCELLED. Une commande peut être annulée lorsqu'elle est à l'état CREATED, CONFIRMED, IN_PREPARATION, READY_FOR_PICKUP ou IN_TRANSIT. Votre service de commande de bout en bout devrait émettre des remboursements en fonction de votre les modalités d'annulation et l'état des paiements au moment de l'annulation.

Votre service de commande de bout en bout ne doit pas nécessairement prendre en charge tous les états disponibles. et les transitions. Toutefois, l'état final de la commande doit être FULFILLED. REJECTED ou CANCELLED.

Fournir une estimation du délai de traitement

Vous pouvez fournir aux utilisateurs une estimation de la période pendant laquelle leur commande sera prête à être retirée (ou livrée). Utiliser le champ estimatedFulfillmentTimeIso8601 de FoodOrderUpdateExtension afin d'estimer la période pendant laquelle la commande du client sera prête à être retirée ou livrée.

Envoyez le estimatedFulfillmentTimeIso8601 aux heures suivantes:

  • Lorsque le délai estimé devient disponible, idéalement dans l'ordre CREATED ou CONFIRMED.
  • Lorsque l'heure estimée change, par exemple pour mettre à jour l'heure estimée plus précis lorsque la commande est IN_TRANSIT.

Pour gérer efficacement les attentes des utilisateurs, soyez prudent dans vos estimations et fournir une plage de dates et d'heures plutôt qu'une date et une heure fixes. Vous devez tenez compte des variations telles que les conditions de circulation lorsque cela est possible. Pour Par exemple, vous pouvez envoyer une estimation de 12h45 (limite inférieure) à 13h15 (limite supérieure) liée) pour une commande dont le délai de livraison estimé est 13h.

Proposer des actions de gestion des commandes

Lorsque vous envoyez une mise à jour de commande, vous pouvez fournir aux clients des ressources qui les aident gérer sa commande sous la forme d'un OrderManagementAction. Après un client passe commande, il peut avoir besoin de vous contacter ou de contacter le restaurant l’exécution de la commande pour suivre la progression, la modifier ou l’annuler.

Un OrderManagementAction permet aux clients d'envoyer un e-mail ou d'appeler une directement sur leur appareil. Utilisez les mêmes informations dans OrderManagementAction comme dans l'e-mail de confirmation de commande que vous avez envoyé à l'adresse utilisateur.

Voici les types d'actions de gestion des commandes:

  • CUSTOMER_SERVICE: inviter les clients à contacter le client Google Cloud. Ce type d'action de gestion est obligatoire pour la mise à jour des commandes.
  • EMAIL: indiquer aux clients l'action d'envoyer un e-mail à l'adresse fournie adresse e-mail.
  • CALL: proposer aux clients une action pour appeler le numéro de téléphone indiqué.
  • VIEW_DETAIL: proposer aux clients une action permettant d'afficher les détails de leur commande.

Chaque mise à jour de commande doit contenir au moins une action de gestion des commandes. Toutefois, les actions de gestion des commandes proposées peuvent varier en fonction de l'état de la commande. Par exemple, lorsqu'une commande est à l'état CONFIRMED, CUSTOMER_SERVICE peut pointer vers le numéro de téléphone de votre service client. Lorsque cette commande indique mises à jour de IN_TRANSIT, l'action CUSTOMER_SERVICE peut pointer vers le numéro de téléphone du restaurant de vente.

Envoyer des mises à jour de commandes

Vous utilisez le type de message AsyncOrderUpdateRequestMessage pour envoyer une commande. du service de commande de bout en bout. Google répond avec un AsyncOrderUpdateResponseMessage Par exemple, si vous voulez informer un au client que sa commande est valide et acceptée, vous pouvez lui envoyer un AsyncOrderUpdateRequestMessage pour remplacer l'état de la commande par CONFIRMED. avec l'étiquette Accepted by restaurant.

Schéma de mise à jour de la commande

Définir le message de mise à jour de la commande

Lorsque vous envoyez un AsyncOrderUpdateRequestMessage à Google, vous devez inclure des informations sur l'état de la commande à l'aide du champ OrderUpdate.

Les exemples suivants illustrent un exemple de AsyncOrderUpdateRequestMessage pour chaque état de commande:

CONFIRMED

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que la commande est confirmée avec un reçu et une date de livraison estimée ; en temps réel.

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

REFUSÉE

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que la commande est rejetée avec un motif de refus.

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

ANNULÉ

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que la commande est annulée avec un motif d'annulation.

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

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que la nourriture est en cours de préparation.

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

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que les aliments sont prêts à être retirés.

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

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que la commande est en cours d’acheminement avec un délai de livraison estimé.

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

TRAITÉE

Exemple de requête de mise à jour de commande qui avertit l'utilisateur que la commande est retirée ou livrée:

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

Pour plus d'exemples de demandes de mise à jour de commande dans différents cas d'utilisation, consultez Mettre en œuvre les mises à jour avancées des commandes

Générer un jeton d'autorisation et envoyer le message

Les mises à jour de commandes nécessitent un jeton d'autorisation afin que la commande service peut vérifier que le message provient de votre service Web de commande de bout en bout.

Pour mettre à jour les commandes de votre projet, procédez comme suit:

  1. Générez un jeton d'autorisation en procédant comme suit: <ph type="x-smartling-placeholder">
      </ph>
    1. Utiliser la bibliothèque Google Auth pour lire les identifiants de votre service fichier de compte.
    2. Demandez un jeton à l'aide du champ d'application d'API suivant: https://www.googleapis.com/auth/actions.fulfillment.conversation
  2. Utilisez ce jeton pour envoyer une requête HTTP POST authentifiée au point de terminaison suivant: https://actions.googleapis.com/v2/conversations:send
  3. Dans votre requête, définissez l'en-tête Content-Type sur application/json.

Les exemples suivants montrent comment mettre en œuvre la mise à jour des commandes:

Node.js

Ce code utilise la bibliothèque d'authentification Google pour Node.js.

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

Ce code utilise la bibliothèque d'authentification Google pour Python.

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

Ce code utilise la bibliothèque d'authentification Google pour 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",);
}
    

Pour les mises à jour de commandes réussies sans erreur, Google renvoie une réponse HTTP 200 avec une charge utile vide. S'il y a eu un problème, par exemple, si la mise à jour incorrect, Google renvoie une erreur.