En esta sección, se describe cómo enviar actualizaciones urgentes de sus feeds a Google. La API de Incremental Updates te permite actualizar y borrar entidades en tu de Google Cloud casi en tiempo real.
Esta función está diseñada principalmente para actualizaciones que no puedes prever como cierres por emergencia. Como regla general, cualquier cambio que se envíe a través del La API de Incremental Updates debería ser un cambio que debería publicarse en no más de una semana. Si no es necesario que el cambio se refleje de inmediato, puedes usar una actualización por lotes. Las actualizaciones incrementales se procesan en no más de cinco minutos.
Configuración
Para implementar actualizaciones incrementales, haz lo siguiente:
- Sigue los pasos descritos en Crea y configura un proyecto para crear un proyecto.
- Sigue los pasos que se describen en Configura una cuenta de servicio. para crear una cuenta de servicio. Ten en cuenta que debes ser "Propietario" de los proyecto para agregar un "Editor" rol de la cuenta de servicio
- (Opcional, pero recomendado) Instalar la biblioteca cliente de Google en el idioma que elijas para facilitar el uso de OAuth 2.0 cuando llames al en la API de Cloud. En las muestras de código que se incluyen a continuación, se usan estas bibliotecas. De lo contrario, debes manejar los intercambios de tokens de forma manual, tal como se describe en Cómo usar OAuth 2.0 para acceder a las APIs de Google.
Extremo
Para notificar a Google sobre una actualización, realiza una solicitud POST de HTTP al Actualizaciones de la API e incluye una carga útil de actualizaciones y adiciones. El esquema de inventario que uses determina a qué extremo realizar la solicitud:
Inventario v2
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID:push
Inventario v1
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/ENTITY_ID:push
Para quitar una entidad, realiza una solicitud HTTP DELETE al siguiente extremo que corresponde al esquema de inventario que uses:
Inventario v2
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Inventario v1
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
En las solicitudes anteriores, reemplaza lo siguiente:
- PROJECT_ID: Es el ID del proyecto de Google Cloud asociado al proyecto que creado en Cómo crear y configurar un proyecto.
- TYPE (solo esquema de inventario v2): El tipo de entidad (propiedad
@type
) del objeto del feed de datos que deseas actualizar. - ENTITY_ID: Es el ID de la entidad incluida en la carga útil. Asegúrate de Codifica el ID de la entidad como una URL.
- DELETE_TIME (borrar solo el extremo): Es un campo opcional que denota el
Hora en que se borró la entidad de tus sistemas (valor predeterminado es cuando la solicitud se
recibidos). El valor del tiempo no debe ser posterior al actual. Cuando se envía una entidad
a través de una llamada incremental, el control de versiones de entidades
También usa el campo
delete_time
en el caso de una llamada a borrar. Asignar formato valor comoyyyy-mm-ddTHH:mm:ssZ
Por ejemplo, si tienes un proyecto con el ID "delivery-provider-id" que utiliza el esquema del inventario v2. Quieres hacer cambios en el restaurante con una tipo de entidad de restaurante de "MenuSection" y un ID de entidad de "menuSection_122" El extremo para las actualizaciones de tus datos sería el siguiente:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122:push
Para quitar esta misma entidad, debes hacer esta llamada a la API de HTTP DELETE:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122?entity.vertical=FOODORDERING
Solicitudes a la zona de pruebas
Para las solicitudes de la zona de pruebas, sigue las instrucciones del apartado Extremo que aparece más arriba, pero
realiza solicitudes a /v2/sandbox/apps/
en lugar de a /v2/apps/
. Por ejemplo, un
La solicitud de eliminación de la zona de pruebas para el esquema de inventario v2 se estructura de la siguiente manera:
https://actions.googleapis.com/v2/sandbox/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Actualizaciones y incorporaciones
Tus feeds por lotes diarios también deben contener los cambios enviados a través de este en la API de Cloud. De lo contrario, las actualizaciones por lotes reemplazarán los cambios incrementales.
Carga útil
Cada solicitud POST debe incluir los parámetros de la solicitud junto con el archivo JSON carga útil que contiene datos estructurados de cualquier tipo de entidad enumerado en la de inventario.
El archivo JSON debería aparecer igual que en el feed por lotes, con el las siguientes diferencias:
- El cuerpo de la carga útil no debe superar los 5 MB de tamaño. De manera similar a lo que ocurre feeds, te sugerimos que quites los espacios en blanco para que quepan más datos.
- El sobre es el siguiente:
{ "entity": { "data":"ENTITY_DATA", "vertical":"FOODORDERING" }, "update_time":"UPDATE_TIMESTAMP" }
En la carga útil anterior, reemplaza lo siguiente:
- ENTITY_DATA: Entidad en formato JSON serializado como una cadena. El
La entidad JSON-LD se debe pasar como una cadena en el campo
data
. - UPDATE_TIMESTAMP (opcional): Marca de tiempo del momento en que se actualizó la entidad en
tus sistemas. El valor del tiempo no debe ser posterior al actual. La marca de tiempo predeterminada
Google recibe la solicitud. Cuando se envía una entidad a través de un
el control de versiones de la entidad también usa
update_time
en el caso de una solicitud de adición o actualización.
Actualiza una entidad
Ejemplo 1: Actualiza un restaurante
Supongamos que necesitas actualizar el número de teléfono de un restaurante con urgencia. Tu la actualización contiene el JSON de todo el restaurante.
Considera un feed por lotes que se vea de la siguiente manera:
{ "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501234567", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 }
Entonces, tu actualización incremental por HTTP POST sería la siguiente:
POST v2/apps/provider-project/entities/Restaurant/restaurant12345:push Host: actions.googleapis.com Content-Type: application/ld+json { "entity": { "data": { "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501235555", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 }, "vertical": "FOODORDERING" } }
Ejemplo 2: Actualiza el precio de un elemento de menú
Supongamos que necesitas cambiar el precio de un elemento del menú. Como en el ejemplo 1, tu update debe contener el JSON para toda la entidad de nivel superior (el menú), y el feed usa el esquema de inventario v1.
Considera un feed por lotes que se vea de la siguiente manera:
{ "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 3.00, "priceCurrency": "USD" }
Entonces, la actualización incremental a través de POST sería la siguiente:
POST v2/apps/provider-project/entities/MenuItemOffer/menuitemoffer6680262:push Host: actions.googleapis.com Content-Type: application/ld+json { "entity": { "data": { "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 1.00, "priceCurrency": "USD" }, "vertical": "FOODORDERING" } }
Agrega una entidad
Para agregar entidades, evita usar actualizaciones de inventario. En su lugar, usa los feeds por lotes como se describe en el esquema de inventario v2.
Quita una entidad
Para quitar entidades de nivel superior, usa un extremo ligeramente modificado. y usar HTTP DELETE en lugar de HTTP POST en la solicitud.
No uses HTTP DELETE para quitar una subentidad dentro de una entidad de nivel superior, como un elemento de menú dentro de un menú. En cambio, trata la eliminación de subentidades como un actualización a una entidad de nivel superior en la que la subentidad se quita del lista o parámetro relevante.
Ejemplo 1: Borra una entidad de nivel superior
Supongamos que quieres eliminar un restaurante de un feed que usa el esquema de inventario v1. También debes borrar sus servicios y menús.
Un extremo de muestra para una entidad de menú con ID "https://www.provider.com/restaurant/menu/nr":
DELETE v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fmenu%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Un extremo de muestra para una entidad de restaurante con ID "https://www.provider.com/restaurant/nr":
DELETE v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Un extremo de muestra para una entidad de servicio con ID "https://www.provider.com/restaurant/service/nr":
DELETE v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fservice%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
}
Ejemplo 2: Quita entidades
Para quitar una subentidad de una entidad de nivel superior, debe enviar la tiene la subentidad quitada del campo correspondiente. Lo siguiente ejemplo supone que el feed usa el esquema de inventario v1.
Por ejemplo, para quitar un área de servicio, actualiza el servicio con el campo correspondiente.
se quitó de la lista areaServed
.
POST v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fservice%2Fnr:push
Host: actions.googleapis.com
Content-Type: application/ld+json
{
"entity": {
// Note: "data" is not serialized as a string in our example for readability.
"data": {
"@type": "Service",
"provider": {
"@type": "Restaurant",
"@id": "https://www.provider.com/restaurant/nr"
},
"areaServed": [
{
"@type": "GeoCircle",
"geoMidpoint": {
"@type": "GeoCoordinates",
"latitude": "42.362757",
"longitude": "-71.087109"
},
"geoRadius": "10000"
}
// area2 is removed.
]
...
},
"vertical": "FOODORDERING"
}
}
Códigos de respuesta de la API
Una llamada exitosa no significa que el feed sea válido o correcto, sino que Se realizó una llamada a la API. Las llamadas correctas reciben el código 200 de respuesta HTTP, junto con un cuerpo de respuesta vacío:
{}
Para fallas, el código de respuesta HTTP no será 200, y el cuerpo de la respuesta indica qué salió mal.
Por ejemplo, si el usuario configuró la "vertical"; valor en el sobre para
FAKE_VERTICAL
, recibirás el siguiente mensaje:
{
"error": {
"code": 400,
"message": "Invalid value at 'entity.vertical' (TYPE_ENUM), \"FAKE_VERTICAL\"",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "entity.vertical",
"description": "Invalid value at 'entity.vertical' (TYPE_ENUM), \"FAKE_VERTICAL\""
}
]
}
]
}
}
Muestra de código
Estos son algunos ejemplos de cómo usar la API de Incremental Updates en diversos idiomas. Estas muestras usan las bibliotecas de autenticación de Google y suponen que un feed usa el esquema de inventario v1. Para encontrar soluciones alternativas, consulta Uso de OAuth 2.0 para aplicaciones de servidor a servidor.
Actualiza entidades
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') // entity.json is a file that contains the entity data in json format const entity = require('./entity.json') const ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' const PROJECT_ID = 'your-project-id' /** * Get the authorization token using a service account. */ async function getAuthToken() { let client = auth.fromJSON(serviceAccountJson) client.scopes = ['https://www.googleapis.com/auth/assistant'] const tokens = await client.authorize() return tokens.access_token; } /** * Send an incremental update to update or add an entity */ async function updateEntity(entityId, entity) { const token = await getAuthToken() request.post({ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, url: `https://actions.googleapis.com/v2/apps/${PROJECT_ID}/entities/${encodeURIComponent(entityId)}:push`, body: { entity: { data: JSON.stringify(entity), vertical: 'FOODORDERING', } }, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) } updateEntity(ENTITY_ID, entity)
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 import urllib PROJECT_ID = 'your-project-id' ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' ENDPOINT = 'https://actions.googleapis.com/v2/apps/%s/entities/%s:push' % ( PROJECT_ID, urllib.quote(ENTITY_ID, '')) # 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/assistant']) authed_session = AuthorizedSession(scoped_credentials) # Retrieving the entity update_file = open("entity.json") #JSON file containing entity data in json format. data = update_file.read() # Populating the entity with wrapper entity = {} entity['data'] = data #entity JSON-LD serialized as string entity['vertical'] = 'FOODORDERING' request = {} request['entity'] = entity response = authed_session.post(ENDPOINT, json=request) print(response.text) #if successful, will be '{}'
Java
Este código usa la biblioteca auth de Google para Java.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "http://www.provider.com/somerestaurant"; /** * 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/assistant")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an incremental update to update or add an entity. * @param entityId The id of the entity to update. * @param entity the json of the entity to be updated. */ public void updateEntity(String entityId, JSONObject entity) { String authToken = getAuthToken(); String endpoint = String.format( "https://actions.googleapis.com/v2/apps/%s/entities/%s:push", PROJECT_ID, URLEncoder.encode(entityId, "UTF-8")); JSONObject data = new JSONObject(); data.put("data", entity.toString()); data.put("vertical", "FOODORDERING"); JSONObject jsonBody = new JSONObject(); jsonBody.put("entity", data); // Execute POST request executePostRequest(endpoint, authToken, jsonBody); }
Cómo quitar entidades
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') // entity.json is a file that contains the entity data in json format const entity = require('./entity.json') const ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' const PROJECT_ID = 'your-project-id' /** * Get the authorization token using a service account. */ async function getAuthToken() { let client = auth.fromJSON(serviceAccountJson) client.scopes = ['https://www.googleapis.com/auth/assistant'] const tokens = await client.authorize() return tokens.access_token; } /** * Send an incremental update to delete an entity */ async function deleteEntity(entityId) { const token = await getAuthToken() request.delete({ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, url: `https://actions.googleapis.com/v2/apps/${PROJECT_ID}/entities/${encodeURIComponent(entityId)}?entity.vertical=FOODORDERING`, body: {}, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) } deleteEntity(ENTITY_ID)
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 import urllib # Service config PROJECT_ID = 'your-project-id' ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' DELETE_TIME = '2018-04-07T14:30:00-07:00' ENDPOINT = 'https://actions.googleapis.com/v2/apps/%s/entities/%s?entity.vertical=FOODORDERING&delete_time=%s' % ( PROJECT_ID, urllib.quote(ENTITY_ID, ''), urllib.quote(DELETE_TIME, '')) # 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/assistant']) authed_session = AuthorizedSession(scoped_credentials) response = authed_session.delete(ENDPOINT) print(response.text) #if successful, will be '{}'
Java
Este código usa la biblioteca auth de Google para Java.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "restaurant/http://www.provider.com/somerestaurant"; /** * 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/assistant")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an incremental update to delete an entity. * @param entityId The id of the entity to delete. */ public void deleteEntity(String entityId) { String authToken = getAuthToken(); String endpoint = String.format( "https://actions.googleapis.com/v2/apps/%s/entities/%s?entity.vertical=FOODORDERING", PROJECT_ID, URLEncoder.encode(entityId, "UTF-8")); // Execute DELETE request System.out.println(executeDeleteRequest(endpoint, authToken)); }
Casos de uso
Estos son ejemplos de actualizaciones incrementales, actualizaciones de feeds completas, y el contenido a un alto nivel en la llamada a la API:
Situación | Entidad de nivel superior | Descripción y efectos |
---|---|---|
Inhabilita un servicio | DisabledService |
Debes inhabilitar un servicio por un motivo imprevisto. Actualizaciones incrementales: Envía la entidad Feeds completos: Asegúrate de actualizar la entidad desde los feeds completos.
para que |
El artículo específico está agotado | Menu |
Actualizaciones incrementales: Envía el Menu de encapsulamiento.
con offer.inventoryLevel establecido en 0 para el valor especificado
MenuItem y todos los demás datos sin cambios. |
Cambio de precio de un elemento de menú | Menu |
Actualizaciones incrementales: Envía el Menu de encapsulamiento.
entidad con offer.price establecido en el precio actualizado del precio especificado
MenuItem y todos los demás datos sin cambios. |
Agregar nueva entidad de nivel superior Solo se aplica a entidades de los tipos |
Menu , Restaurant , Service |
Por ejemplo, si necesitas agregar un nuevo menú a un restaurante. Actualizaciones incrementales: Envía la nueva entidad del menú, junto con el restaurante.
con su campo |
Borrar la entidad de nivel superior de forma permanente Solo se aplica a entidades de los tipos |
Menu , Restaurant , Service |
Actualizaciones incrementales: Envía un Eliminación explícita: Feeds completos: Asegúrate de quitar la entidad de los feeds completos antes de la siguiente recuperación de Google. De lo contrario, se volverá a agregar la entidad. |
Agrega una nueva área de entrega en una Service específica |
Service |
Feeds incrementales: Envía la entidad Service en cuestión con todos sus
intactos, como lo harías normalmente en los feeds completos, con un área de entrega nueva
se especifica en areaServed de Service . |
Actualiza la hora estimada de entrega en Service |
Service |
Feeds incrementales: Envía el Service igual que en
los feeds, excepto que se actualiza su hoursAvailable.deliveryHours
según corresponda. |
Actualiza los precios de entrega en Service |
Service |
Feeds incrementales: Envía el Service completo con
Se actualizó offers.priceSpecification.price . |
Actualiza los horarios de comida para llevar o entrega a domicilio en Service |
Service |
Feeds incrementales: Envía el Service igual que en
los feeds, excepto que se actualiza su hoursAvailable
según corresponda. |
Service (cambiar el importe mínimo del pedido) |
Service |
Feeds incrementales: Envía el Service completo con
Service.offers.priceSpecification.eligibleTransactionVolume
actualizado |
Borrar MenuItem de forma permanente |
Menu |
Feeds incrementales: Envía el Menu igual que en el
feeds, pero como se quita este MenuItem de
Lista hasMenuItems |
SLO en el tiempo de procesamiento para trabajos por lotes y actualizaciones incrementales
Una entidad agregada a través de una actualización por lotes o incremental se procesará en De 1 a 2 días. Una entidad actualizada o borrada a través de un lote se procesará en 2 horas, mientras que una entidad actualizada a través de una actualización incremental se procesará en 5 minutos. Una entidad inactiva se borra dentro de 7 días.
Puedes enviarle a Google una de las siguientes opciones:
- Múltiples trabajos por lotes por día para mantener tu inventario actualizado
- Un trabajo por lotes al día y APIs incrementales para mantener tu inventario actualizado