Cette section explique comment envoyer des mises à jour urgentes de votre inventaire. à Google. L'API Progressive Update permet de déployer des mises à jour et de supprimer dans votre inventaire de bac à sable ou de production, quasiment en temps réel.
Cette fonctionnalité est principalement destinée aux mises à jour que vous ne pouvez pas prévoir, comme les routes fermées en urgence. En règle générale, toute modification soumise via le L'API de mise à jour incrémentielle doit être une modification qui ne doit pas être mise en ligne au plus tard une heure. Si votre modification n'a pas besoin d'être appliquée immédiatement, vous pouvez utiliser l'ingestion par lots. Les mises à jour incrémentielles sont traitées en cinq minutes maximum.
Prérequis
Les éléments suivants sont requis pour implémenter les mises à jour incrémentielles:
- Un compte de service est créé avec le rôle d'éditeur pour votre projet Actions. Pour en savoir plus, consultez Créez et configurez un projet.
- Les flux de données de production ou de bac à sable sont hébergés et ingérés. Pour en savoir plus, consultez Ingestion par lots.
- (Facultatif, mais recommandé) Installez la bibliothèque cliente Google. dans le langage de votre choix afin de faciliter l'utilisation d'OAuth 2.0 lors de l'appel de la méthode API. Les exemples de code inclus ci-dessous utilisent ces bibliothèques. Sinon, vous devez gérer manuellement les échanges de jetons, comme décrit dans la section Utiliser OAuth 2.0 pour accéder aux API Google.
Points de terminaison
Dans les requêtes ci-dessous, remplacez les éléments suivants:
- PROJECT_ID: ID du projet Google Cloud associé au projet que vous dans la section Créer et configurer un projet.
- TYPE: type d'entité (propriété
@type
) de l'objet de votre flux de données à mettre à jour. - ENTITY_ID (supprimer le point de terminaison uniquement): ID de l'entité à supprimer. Veillez à Encodez votre ID d'entité en URL.
- DELETE_TIME (supprimer le point de terminaison uniquement): champ facultatif permettant d'indiquer
l'heure à laquelle l'entité a été supprimée de vos systèmes (par défaut, lorsque la requête est
reçu). La valeur de l'heure ne doit pas se situer dans le futur. Lors de l'envoi d'une entité
via un appel incrémentiel, la gestion des versions d'entités
utilise également le champ
delete_time
dans le cas d'un appel de suppression. Mettre en forme valeuryyyy-mm-ddTHH:mm:ssZ
Mettre à jour le point de terminaison
Pour modifier une entité, envoyez une requête HTTP POST au point de terminaison suivant et inclure une charge utile de mises à jour et ajouts. Vous pouvez mettre à jour jusqu'à 1 000 entités dans un seul appel d'API.
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities:batchPush
Par exemple, si vous souhaitez mettre à jour les entités d'un projet ayant l'ID "delivery-provider-id" le point de terminaison est le suivant:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities:batchpush
Supprimer un point de terminaison
Pour supprimer une entité de votre inventaire, envoyez une requête HTTP DELETE au point de terminaison suivant.
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Par exemple, pour supprimer une "MenuSection", entité associée à l'ID "menuSection_122" à partir de l'ID du fournisseur de livraison (delivery-provider-id) vous devez effectuer un appel d'API HTTP DELETE vers:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122?entity.vertical=FOODORDERING
Environnement de bac à sable
Pour utiliser l'API de mise à jour incrémentielle dans votre inventaire de bac à sable, suivez les instructions de la section Points de terminaison ci-dessus, mais
envoyer des requêtes à /v2/sandbox/apps/
au lieu de /v2/apps/
.
https://actions.googleapis.com/v2/sandbox/apps/PROJECT_ID/entities:batchPush
https://actions.googleapis.com/v2/sandbox/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Mettre à jour des entités
Chaque requête POST doit inclure les paramètres de requête avec le fichier contenant les données structurées de tout type d'entité listé dans le d'inventaire.
Mettre à jour la charge utile
Le fichier JSON doit apparaître de la même manière que dans le flux par lot, avec le préfixe différences suivantes:
- La taille du corps de la charge utile ne doit pas dépasser 5 Mo. Comme pour le traitement par lot nous vous conseillons de supprimer les espaces blancs afin d'insérer davantage de données.
- L'enveloppe se présente comme suit:
{ "requests": [ { "entity": { "data":"ENTITY_DATA", "name": "apps/project_id>/entities/type/entity_id" }, "update_time":"UPDATE_TIMESTAMP" }, ], "vertical": "FOODORDERING" }
Dans la charge utile ci-dessus, remplacez les éléments suivants:
- ENTITY_DATA: entité au format JSON sérialisée en tant que chaîne. La
L'entité JSON-LD doit être transmise sous forme de chaîne dans le champ
data
. - UPDATE_TIMESTAMP (facultatif): horodatage de la mise à jour de l'entité dans
vos systèmes. La valeur de l'heure ne doit pas se situer dans le futur. Le code temporel par défaut est le moment
Google reçoit la demande. Lors de l'envoi d'une entité via un
la gestion des versions des entités utilise également
update_time
dans le cas d'une requête d'ajout/de mise à jour.
Exemples
Exemple 1: Mettre à jour un restaurant
Supposons que vous ayez besoin de mettre à jour en urgence le numéro de téléphone d'un restaurant. Votre contient le fichier JSON de tout le restaurant.
Prenons l'exemple d'un flux par lot qui se présente comme suit:
{ "@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 }
Votre mise à jour incrémentielle par HTTP POST se présenterait comme suit:
POST v2/sandbox/apps/provider-project/entities:batchPush Host: actions.googleapis.com Content-Type: application/ld+json { "requests": [ { "entity": { "name": "apps/provider-project/entities/restaurant/restaurant12345", "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" }
Exemple 2: Mettre à jour plusieurs restaurants
Pour mettre à jour deux entités de restaurant dans un seul appel d'API, la requête HTTP POST se présente comme suit:
POST v2/sandbox/apps/provider-project/entities:batchPush Host: actions.googleapis.com Content-Type: application/ld+json { "requests": [ { "entity": { "name": "apps/provider-project/entities/restaurant/restaurant12345", "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 } } }, { "entity": { "name": "apps/provider-project/entities/restaurant/restaurant123", "data": { "@type": "Restaurant", "@id": "restaurant123", "name": "Some Other Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501231235", "streetAddress": "385 Spear St", "addressLocality": "San Mateo", "addressRegion": "CA", "postalCode": "94115", "addressCountry": "US" } } } ] "vertical": "FOODORDERING" }
Exemple 3: Mettre à jour le prix d'un élément de menu
Supposons que vous deviez modifier le prix d'un élément de menu. Comme dans l'exemple 1, doit contenir le fichier JSON de l'ensemble de l'entité de premier niveau (le menu) ; utilise le schéma d'inventaire v1.
Prenons l'exemple d'un flux par lot qui se présente comme suit:
{ "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 3.00, "priceCurrency": "USD" }
Votre mise à jour incrémentielle via la méthode POST se présenterait comme suit:
POST v2/sandbox/apps/provider-project/entities:batchPush Host: actions.googleapis.com Content-Type: application/ld+json { "requests": [ { "entity": { "name": "apps/provider-project/entities/menuitemoffer/menuitemoffer6680262", "data": { "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 1.00, "priceCurrency": "USD" }, "vertical": "FOODORDERING" } } ] "vertical": "FOODORDERING" }
Ajouter une entité
Pour ajouter des entités, évitez d'utiliser des mises à jour d'inventaire. Utilisez plutôt les flux par lot comme décrit pour le schéma d'inventaire v2.
Supprimer une entité
Pour supprimer des entités de niveau supérieur, utilisez un point de terminaison légèrement modifié, et utiliser HTTP DELETE au lieu de HTTP POST dans la requête.
Suppression d'une entité de niveau supérieur
Imaginons que vous souhaitiez supprimer un restaurant d'un flux. Vous devez supprimera également ses services et ses menus.
Exemple de point de terminaison pour une entité de menu ayant un ID "provider/restaurant/menu/nr":
DELETE v2/apps/delivery-provider-id/entities/menu/provider%2Frestaurant%2Fmenu%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Exemple de point de terminaison pour une entité de restaurant ayant un ID "https://www.provider.com/restaurant/nr":
DELETE v2/apps/delivery-provider-id/entities/restaurant/provider%2Frestaurant%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Exemple de point de terminaison pour une entité de service avec ID "https://www.provider.com/restaurant/service/nr":
DELETE v2/apps/delivery-provider-id/entities/service/provider%2Frestaurant%2Fservice%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
}
Supprimer des sous-entités
N'utilisez pas HTTP DELETE pour supprimer une sous-entité au sein d'une entité de niveau supérieur, telle que un élément de menu dans un menu. Considérez plutôt la suppression de sous-entités comme une une mise à jour d'une entité de niveau supérieur dans laquelle la sous-entité est supprimée de la liste pertinente ou reverseReference.
Codes de réponse de l'API
Un appel réussi ne signifie pas que le flux est valide ou correct, mais uniquement que le L'appel d'API a été effectué. Les appels réussis reçoivent un code de réponse HTTP 200, ainsi que avec un corps de réponse vide:
{}
En cas d'échec, le code de réponse HTTP n'est pas 200 et le corps de la réponse indique ce qui s'est mal passé.
Par exemple, si l'utilisateur a défini le "vertical" de l'enveloppe à
FAKE_VERTICAL
, vous devriez recevoir le message ci-dessous:
{
"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\""
}
]
}
]
}
}
Exemple de code
Vous trouverez ci-dessous quelques exemples d'utilisation de l'API incrémentiel de mise à jour dans différents langues. Ces exemples utilisent les bibliothèques Google Auth et supposent qu'un flux utilise du schéma d'inventaire v1. Pour d'autres solutions, reportez-vous à Utiliser OAuth 2.0 pour l'authentification serveur à serveur
Mettre à jour des entités
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') // entity.json is a file that contains the entity data in json format const entity = require('./entity.json') const ENTITY_ID = 'your/entity/id' const PROJECT_ID = 'type/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(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:batchPush`, body: { requests: [ { entity: { data: JSON.stringify(entity) name: `apps/${PROJECT_ID}/entities/${ENTITY_ID}` } } ], vertical: 'FOODORDERING' }, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) } updateEntity(entity)
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 import urllib PROJECT_ID = 'your-project-id' ENTITY_ID = 'type/your/entity/id' ENDPOINT = 'https://actions.googleapis.com/v2/apps/%s/entities:batchPush' % ( PROJECT_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() entity = {} entity['data'] = data #entity JSON-LD serialized as string entity['name'] = 'apps/%s/entities/%s' % (PROJECT_ID, urllib.quote(ENTITY_ID, '') ) # Populating the request request = {} request['entity'] = entity requestArray = [request] # Populating the payload payload = {} payload['requests'] = requestArray payload['vertical'] = 'FOODORDERING' response = authed_session.post(ENDPOINT, json=payload) print(response.text) #if successful, will be '{}'
Java
Ce code utilise la bibliothèque d'authentification Google pour Java.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "type/your-entity-id"; /** * 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 data) { String authToken = getAuthToken(); String endpoint = String.format("https://actions.googleapis.com/v2/apps/%s/entities/:batchPush", PROJECT_ID); JSONObject entity = new JSONObject(); entity.put("data", data.toString()); entity.put("name", String.format("apps/%s/entities/%s", PROJECT_ID, URLEncoder.encode(ENTITY_ID, "UTF-8"))); JSONObject request = new JSONObject(); request.put("entity", entity); JSONArray requestArray = new JSONArray(); requestArray.put(request); JSONObject payload = new JSONObject(); payload.put("requests", requestArray); payload.put("vertical", FOODORDERING); // Execute POST request executePostRequest(endpoint, authToken, payload); }
Supprimer des entités
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') // 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
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 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
Ce code utilise la bibliothèque d'authentification Google pour 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)); }
Cas d'utilisation
Voici des exemples de mises à jour incrémentielles, de mises à jour de flux complètes, et le contenu à un niveau élevé dans l'appel d'API:
Scénario | Entité à mettre à jour | Description et effets |
---|---|---|
Désactiver un service | Service |
Vous devez désactiver un service pour une raison imprévue. Mises à jour incrémentielles:mettez à jour l'entité Flux complets:veillez à mettre à jour l'entité à partir des flux complets.
de définir |
Un article spécifique n'est pas disponible | MenuItemOffer |
Mises à jour incrémentielles:envoyez le MenuItemOffer d'encapsulation.
entité avec inventoryLevel défini sur 0 pour l'entité
MenuItem et toutes les autres données inchangées. |
Changement de prix de l'élément de menu | MenuItemOffer |
Mises à jour incrémentielles:envoyez le MenuItemOffer d'encapsulation.
entité avec price défini sur le nouveau prix pour l'entité donnée
MenuItem et toutes les autres données inchangées. |
Ajouter une entité de niveau supérieur S'applique uniquement aux entités de type |
Menu , Restaurant , Service |
Par exemple, vous devez ajouter un nouveau menu à un restaurant. Flux complets:ajoutez l'entité à vos flux de données et attendez l'ingestion par lots. |
Supprimer définitivement l'entité de premier niveau S'applique uniquement aux entités de type |
Menu , Restaurant , Service |
Mises à jour incrémentielles:envoyez un suppression explicite. Flux complets:veillez à supprimer l'entité des flux complets avant lors de la prochaine extraction par Google, sinon l'entité sera de nouveau ajoutée. |
Ajouter une zone de livraison dans un Service spécifique |
ServiceArea |
Flux partiels:envoyez l'entité ServiceArea en question avec tous ses
les champs restent intacts, comme vous le feriez dans les flux complets, avec une nouvelle zone de livraison
spécifié dans polygon , geoRadius ou postalCode . |
Modifier l'heure d'arrivée estimée pour la livraison à Service |
ServiceHours |
Flux partiels:envoyez l'ServiceHours de la même manière que dans
les flux, sauf que son leadTimeMin est mis à jour
en conséquence. |
Modifier les prix de livraison dans le pays suivant : Service |
Fee |
Flux partiels:envoyer la version complète Fee avec
price mis à jour. |
Modifier les horaires de livraison ou de vente à emporter dans Service |
ServiceHours |
Flux partiels:envoyez l'ServiceHours de la même manière que dans
les flux, sauf que ses propriétés opens et closes sont mises à jour
en conséquence. |
Service (modifier le montant minimal de commande) |
Fee |
Flux partiels:envoyer la version complète de Fee avec
minPrice
mis à jour |
Supprimer définitivement un(e) MenuItem |
Menu |
Flux partiels:envoyez l'MenuItem de la même manière que dans les
flux, mais avec parentMenuSectionId vide.
|
SLO sur le temps de traitement des jobs par lot et des mises à jour incrémentielles
Une entité mise à jour ou supprimée par lot est traitée sous 2 heures, alors qu'une entité mise à jour par incréments est traitée en 5 minutes. Une entité obsolète est supprimée au bout de sept jours.
Vous pouvez envoyer à Google:
- Effectuer plusieurs tâches par lot par jour pour maintenir votre inventaire à jour
- Un job par lot par jour et des API supplémentaires pour maintenir votre inventaire à jour.