Después de que un cliente envía un pedido de comida, puedes enviar un mensaje de actualización del pedido a el servicio de Pedidos de extremo a extremo para notificarnos sobre el cambio.
Estos son algunos de los motivos comunes por los que envías actualizaciones de pedidos:
- El tiempo de entrega estimado del pedido pasa a estar disponible o cambia.
- Cambia el estado de un pedido.
- Ya no se puede completar el pedido.
- Cambió el precio de un elemento del menú incluido en el pedido.
- El cliente tiene una nueva forma de administrar su pedido, como una asistencia al cliente o el número de teléfono del restaurante.
- El recibo del pedido estará disponible.
En las siguientes secciones, se explica cómo abordar estas diferentes situaciones con las actualizaciones de pedidos.
Estados del pedido en transición
Un pedido tiene seis estados posibles. Estos estados y sus posibles transiciones se describen en el siguiente diagrama:
Cuando un cliente envía un pedido por primera vez, este comienza con el estado
CREATED
, CONFIRMED
o REJECTED
. Puedes enviar un mensaje de actualización del pedido a
actualizar el estado de un pedido, siempre que la transición de estado sea válida. CREATED
se usa cuando la plataforma del socio no puede confirmar o rechazar el pedido.
de inmediato. Un ejemplo de caso de uso es cuando un cliente realiza un pedido a través de una entrega
agregador. El agregador de entregas recibe la entrega de Google, y el
y el agregador envía la información al restaurante. Una vez que el restaurante recibió
y confirmaste la disponibilidad del pedido, el estado ahora puede ser CONFIRMED
; de lo contrario,
REJECTED
Un pedido en el estado CONFIRMED
pasa a continuación al estado IN_PREPARATION
. En función de si el pedido es para retiro o entrega, luego usa el estado READY_FOR_PICKUP
o IN_TRANSIT
. Cuando se entrega o se recoge la comida, el pedido se establece en el estado FULFILLED
.
Si permites que los clientes cancelen pedidos, puedes usar el estado CANCELLED
. Se puede cancelar un pedido en el estado CREATED
, CONFIRMED
, IN_PREPARATION
, READY_FOR_PICKUP
o IN_TRANSIT
.
El servicio de Pedidos de extremo a extremo debería emitir reembolsos según tu
política de cancelación y el estado de los pagos en el momento de la cancelación.
El servicio de pedidos de extremo a extremo no tiene que ser compatible con todos los estados disponibles
y transiciones. Sin embargo, el estado final del pedido debe ser FULFILLED
.
REJECTED
o CANCELLED
.
Proporcionar un tiempo de entrega estimado
Puedes proporcionar a los usuarios un intervalo de tiempo estimado en el que se completará el pedido
listo para su retiro (o entregado). Usa el campo estimatedFulfillmentTimeIso8601
de FoodOrderUpdateExtension
para proporcionar un intervalo de tiempo estimado para cuando un
el pedido del cliente estará listo para su retiro o entregado.
Envía estimatedFulfillmentTimeIso8601
en los siguientes horarios:
- Cuando el tiempo estimado esté disponible, idealmente en el pedido
CREATED
oCONFIRMED
. - Cuando cambia la hora estimada, como actualizar la hora estimada
será más preciso cuando el pedido sea
IN_TRANSIT
.
Para gestionar las expectativas de los usuarios de forma eficaz, sé conservador en tus estimaciones y proporcionan una fecha y un intervalo de tiempo en lugar de una fecha y hora fijas. Deberías tenga en cuenta variaciones, como las condiciones del tráfico, siempre que sea posible. Para ejemplo, puedes enviar una estimación de 12:45 p. m. (límite inferior) a 1:15 p. m. (límite superior) bound) para un pedido cuyo tiempo de entrega estimado es a la 1:00 p.m.
Proporcionar acciones de administración de pedidos
Al enviar la actualización de un pedido, puedes brindar a los clientes recursos que ayuden
que administre su pedido en forma de un OrderManagementAction
. Después de un
un cliente hace un pedido, es posible que deba comunicarse contigo o con el restaurante
completar el pedido para hacer un seguimiento del progreso, realizar cambios o cancelar el pedido.
Un OrderManagementAction
permite a los clientes enviar un correo electrónico, llamar o vincular a un
URL directamente desde su dispositivo. Usa la misma información en
OrderManagementAction
como en la confirmación del pedido por correo electrónico que envía a
usuario.
Las acciones de administración de pedidos incluyen los siguientes tipos:
CUSTOMER_SERVICE
: Proporciona a los clientes una acción para comunicarse con ellos servicio. Este tipo de acción de administración es obligatorio para las actualizaciones de pedidos.EMAIL
: Brinda a los clientes una acción para enviar un correo electrónico a la dirección de correo electrónico.CALL
: Brinda a los clientes una acción para llamar al número de teléfono proporcionado.VIEW_DETAIL
: Brinda a los clientes una acción para ver los detalles de su en el orden personalizado.
Cada actualización de pedido debe contener al menos una acción de administración de pedidos. Sin embargo,
las acciones de administración de pedidos proporcionadas pueden variar según el estado del pedido.
Por ejemplo, cuando un pedido se encuentra en el estado CONFIRMED
, el elemento CUSTOMER_SERVICE
acción puede dirigir a tu número de teléfono de atención al cliente. Cuando ese estado de pedido
se actualiza a IN_TRANSIT
, la acción CUSTOMER_SERVICE
puede apuntar a la
número de teléfono del restaurante de entrega.
Enviando actualizaciones de pedidos
Usas el tipo de mensaje AsyncOrderUpdateRequestMessage
para enviar un pedido.
en el servicio de Pedidos de extremo a extremo. Google responde con un
AsyncOrderUpdateResponseMessage
Por ejemplo, si quieres informar
cliente de que su pedido era válido y se aceptó, podría enviar un
AsyncOrderUpdateRequestMessage
para cambiar el estado del pedido a CONFIRMED
con la etiqueta Accepted by restaurant
.
Configura el mensaje de actualización del pedido
Cuando envías un AsyncOrderUpdateRequestMessage
a Google, debes incluir lo siguiente:
información sobre el estado del pedido con el campo OrderUpdate
.
En los siguientes ejemplos, se muestra un AsyncOrderUpdateRequestMessage
de muestra para
cada estado de pedido:
CONFIRMED
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario que el pedido se confirme con un recibo y una entrega estimada tiempo.
{ "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" } } } }
RECHAZADA
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario que el pedido se rechazó con un motivo del rechazo.
{ "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." } ] } } } }
CANCELADO
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario que el pedido se canceló con un motivo de cancelación.
{ "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
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario de que se está preparando la comida en ese momento.
{ "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
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario de que la comida está lista para retirarla.
{ "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
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario que el pedido esté en tránsito con un tiempo de entrega estimado.
{ "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" } } } }
COMPLETADO
En este ejemplo, se muestra una solicitud de actualización del pedido de muestra que notifica al usuario de que el pedido se recoja o se entrega:
{ "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" } } } ] } } }
Para ver más ejemplos de solicitudes de actualización de pedidos en diferentes casos de uso, lee Implementa actualizaciones avanzadas de pedidos.
Genera un token de autorización y envía el mensaje
Las actualizaciones de pedidos requieren un token de autorización para que puede verificar que el mensaje provenga de tu servicio web de pedidos de extremo a extremo.
Para implementar actualizaciones de pedidos en tu proyecto, sigue estos pasos:
- Genera un token de autorización mediante los siguientes pasos:
- Usa la biblioteca de Google Auth para leer las credenciales de tu servicio archivo de cuenta.
- Solicita un token con el siguiente alcance de API:
https://www.googleapis.com/auth/actions.fulfillment.conversation
- Usa este token para enviar una solicitud HTTP POST autenticada al
siguiente extremo:
https://actions.googleapis.com/v2/conversations:send
- Configura el encabezado
Content-Type
comoapplication/json
como parte de tu solicitud.
En los siguientes ejemplos, se muestra cómo implementar actualizaciones de pedidos:
Node.js
Este código usa la biblioteca auth de Google para 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
Este código usa la biblioteca auth de Google para 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
Este código usa la biblioteca auth de Google para 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",); }
Para que los pedidos se actualicen correctamente sin errores, Google muestra una respuesta HTTP 200. con una carga útil vacía. Si hubo un problema, como que la actualización con el formato incorrecto, Google mostrará un error.