Cette section explique comment envoyer des mises à jour urgentes de votre inventaire. à Google. L'API Realtime Updates 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 une fermeture en urgence, la suppression d'éléments du menu ou la mise à jour du prix d'un élément de menu, qui doit apparaître rapidement dans l'interface utilisateur Google. Si votre modification n'a pas besoin d'être reflété immédiatement, vous pouvez utiliser ingestion par lots à la place. Les mises à jour en temps réel sont traitées pas plus de cinq minutes.
Prérequis
Les éléments suivants sont requis pour implémenter les mises à jour en temps réel:
- L'API Maps Booking est activée:
<ph type="x-smartling-placeholder">
- </ph>
- Dans GCP, accédez à API et Services > Bibliothèque
- Recherchez "API Google Maps Booking".
- Recherchez l'instance de bac à sable ("API Google Maps Booking (Dev)"), puis cliquez sur Activer
- Recherchez l'instance de production ("API Google Maps Booking", puis cliquez sur Activer .
- Un compte de service est créé avec le rôle d'éditeur pour votre projet GCP. Pour pour en savoir plus, consultez Configuration du compte
- Les flux de données de production ou de bac à sable sont hébergés et ingérés. Pour en savoir plus, consultez la section Ingestion par lots.
- Pour l'authentification de l'API, il est recommandé d'installer bibliothèque cliente Google, dans le langage de de votre choix. Utilisez "https://www.googleapis.com/auth/mapsbooking" comme protocole OAuth le champ d'application. Les exemples de code inclus ci-dessous utilisent ces bibliothèques. Sinon, vous devrez gérer manuellement les échanges de jetons, comme décrit dans Utiliser le protocole OAuth 2.0 pour accéder aux API Google
Présentation
L'API Realtime Updates accepte deux types d'opérations. La première opération est upsert pour mettre à jour des entités existantes. La la deuxième opération est "delete" pour supprimer des entités de votre inventaire. Les deux sont effectuées sur une plage d'entités répertoriées dans le corps de la requête. Toi peut mettre à jour jusqu'à 1 000 entités via un seul appel d'API. L'API accepte toutes les requêtes entrantes et les place en file d’attente pour un traitement ultérieur. Les requêtes RTU sont donc traitées de manière asynchrone.
L'API des mises à jour en temps réel fonctionne dans deux environnements: l'environnement de bac à sable et l'environnement de production. L'environnement sandbox est utilisé pour tester les requêtes API et l'environnement de production pour mettre à jour le contenu visible par les utilisateurs finaux des commandes. Noms d'hôte des deux environnements:
- Bac à sable –
partnerdev-mapsbooking.googleapis.com
- Production –
mapsbooking.googleapis.com
Points de terminaison
L'API Realtime Updates expose deux points de terminaison pour gérer les requêtes entrantes. pour les mises à jour de l'inventaire:
- UPSERT –
/v1alpha/inventory/partners/
PARTNER_ID/feeds/owg.v2/record:batchPush
- SUPPRIMER –
/v1alpha/inventory/partners/
PARTNER_ID/feeds/owg.v2/record:batchDelete
Le paramètre PARTNER_ID est disponible dans le Centre Actions. affiché sous la forme ID du partenaire sur la page Compte et utilisateurs, comme indiqué sur la ci-dessous.
Prenons 10000001 comme valeur de PARTNER_ID comme exemple à partir de capture d'écran ci-dessus, les URL complètes pour l'envoi de requêtes API dans le bac à sable et dans les exemples ci-dessous.
# Sandbox UPSERT
https://partnerdev-mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchPush
# Sandbox DELETE
https://partnerdev-mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchDelete
# Production UPSERT
https://mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchPush
# Production DELETE
https://mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchDelete
Mettre à jour des entités
Pour mettre à jour des entités dans votre inventaire, utilisez le point de terminaison UPSERT. et envoyer des requêtes HTTP POST. Chaque requête POST doit inclure le paramètre le paramètre PARTNER_ID ainsi que la charge utile JSON contenant le des données structurées de n'importe quel type d'entité listé dans le schéma d'inventaire.
Charge utile de requête d'insertion
Le corps de la requête est un objet JSON avec une liste d'enregistrements. Chaque enregistrement
correspond à une entité en cours de mise à jour. Il s'agit du champ data_record
.
avec la charge utile de l'entité encodée en base64 et l'en-tête generation_timestamp
indiquant l'heure de la mise à jour de l'entité:
{ "records": [ { "data_record":"BASE_64_ENCODED_ENTITY", "generation_timestamp":"UPDATE_TIMESTAMP" } ] }
Dans la charge utile ci-dessus, remplacez les éléments suivants:
BASE_64_ENCODED_ENTITY: chaîne JSON encodée en base64 de la entité. Le fichier JSON de l'entité décodée doit avoir la même structure que dans Spécifications du flux, par exemple:
{"@type":"MenuSection","name":"My Updated Menu Section","menuId":{"@id":"10824","displayOrder":1},"@id":"853705"}
UPDATE_TIMESTAMP: veillez à inclure le code temporel correspondant au moment où a été générée dans vos systèmes backend. Ce code temporel sert à pour garantir le bon ordre des mises à jour de l'inventaire. Si ce champ n'est pas inclus, il est défini sur l'heure à laquelle Google reçoit la demande. Lors de la mise à jour une entité via une requête
batchPush
, le champgeneration_timestamp
est utilisée pour la gestion des versions d'entités. Affichez les prévisions Format des valeurs temporelles dans l'inventaire relationnel du schéma.
Chaque requête de mise à jour en temps réel doit remplir les conditions 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.
- Une requête
batchPush
peut contenir jusqu'à 1 000 entités.
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": "+16501234570", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 }
Votre mise à jour en temps réel par HTTP POST se présentera comme suit:
JSON
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": { "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501234570", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 } "generation_timestamp": "2022-08-19T17:11:10.750Z" } ] }
Base64
Même exemple avec une charge utile encodée en base64.
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": "eyJAdHlwZSI6IlJlc3RhdXJhbnQiLCJAaWQiOiJyZXN0YXVyYW50MTIzNDUiLCJuYW1lIjoiU29tZSBSZXN0YXVyYW50IiwidXJsIjoiaHR0cHM6Ly93d3cucHJvdmlkZXIuY29tL3NvbWVyZXN0YXVyYW50IiwidGVsZXBob25lIjoiKzE2NTAxMjM0NTcwIiwic3RyZWV0QWRkcmVzcyI6IjM0NSBTcGVhciBTdCIsImFkZHJlc3NMb2NhbGl0eSI6IlNhbiBGcmFuY2lzY28iLCJhZGRyZXNzUmVnaW9uIjoiQ0EiLCJwb3N0YWxDb2RlIjoiOTQxMDUiLCJhZGRyZXNzQ291bnRyeSI6IlVTIiwibGF0aXR1ZGUiOjM3LjQ3Mjg0MiwibG9uZ2l0dWRlIjotMTIyLjIxNzE0NH0=" "generation_timestamp": "2022-08-19T17:11:10.750Z" } ] }
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ésentera comme suit:
JSON
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": { "@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 }, "generation_timestamp": "2022-08-19T17:11:10.850Z" }, { "data_record": { "@type": "Restaurant", "@id": "restaurant123", "name": "Some Other Restaurant", "url": "https://www.provider.com/someotherrestaurant", "telephone": "+16501231235", "streetAddress": "385 Spear St", "addressLocality": "San Mateo", "addressRegion": "CA", "postalCode": "94115", "addressCountry": "US" }, "generation_timestamp": "2022-08-19T17:11:10.850Z" } ] }
Base64
Même exemple avec une charge utile encodée en base64.
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": "eyJAdHlwZSI6IlJlc3RhdXJhbnQiLCJAaWQiOiJyZXN0YXVyYW50MTIzNDUiLCJuYW1lIjoiU29tZSBSZXN0YXVyYW50IiwidXJsIjoiaHR0cHM6Ly93d3cucHJvdmlkZXIuY29tL3NvbWVyZXN0YXVyYW50IiwidGVsZXBob25lIjoiKzE2NTAxMjM1NTU1Iiwic3RyZWV0QWRkcmVzcyI6IjM0NSBTcGVhciBTdCIsImFkZHJlc3NMb2NhbGl0eSI6IlNhbiBGcmFuY2lzY28iLCJhZGRyZXNzUmVnaW9uIjoiQ0EiLCJwb3N0YWxDb2RlIjoiOTQxMDUiLCJhZGRyZXNzQ291bnRyeSI6IlVTIiwibGF0aXR1ZGUiOjM3LjQ3Mjg0MiwibG9uZ2l0dWRlIjotMTIyLjIxNzE0NH0=", "generation_timestamp": "2022-08-19T17:11:10.850Z" }, { "data_record": "eyJAdHlwZSI6IlJlc3RhdXJhbnQiLCJAaWQiOiJyZXN0YXVyYW50MTIzIiwibmFtZSI6IlNvbWUgT3RoZXIgUmVzdGF1cmFudCIsInVybCI6Imh0dHBzOi8vd3d3LnByb3ZpZGVyLmNvbS9zb21lcmVzdGF1cmFudCIsInRlbGVwaG9uZSI6IisxNjUwMTIzMTIzNSIsInN0cmVldEFkZHJlc3MiOiIzODUgU3BlYXIgU3QiLCJhZGRyZXNzTG9jYWxpdHkiOiJTYW4gTWF0ZW8iLCJhZGRyZXNzUmVnaW9uIjoiQ0EiLCJwb3N0YWxDb2RlIjoiOTQxMTUiLCJhZGRyZXNzQ291bnRyeSI6IlVTIn0=", "generation_timestamp": "2022-08-19T17:11:10.850Z" } ] }
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.
Prenons l'exemple d'un flux par lot qui se présente comme suit:
{ "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 2, "priceCurrency": "USD" }
Votre mise à jour en temps réel via la méthode POST se présenterait comme suit:
JSON
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": { "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 2, "priceCurrency": "USD" }, "generation_timestamp": "2022-08-19T17:20:10Z" } ] }
Base64
Même exemple avec une charge utile encodée en base64.
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": "eyJAdHlwZSI6Ik1lbnVJdGVtT2ZmZXIiLCJAaWQiOiJtZW51aXRlbW9mZmVyNjY4MDI2MiIsInNrdSI6Im9mZmVyLWNvbGEiLCJtZW51SXRlbUlkIjoibWVudWl0ZW04OTY1MzIiLCJwcmljZSI6MiwicHJpY2VDdXJyZW5jeSI6IlVTRCJ9", "generation_timestamp": "2022-08-19T17:20:10Z" } ] }
Ajouter des entités
N'utilisez pas les mises à jour en temps réel pour ajouter de nouvelles entités, car cela peut entraîner des incohérences dans les données. Utilisez plutôt les flux par lot tel que décrit pour l'ingestion par lots.
Supprimer des entités
Pour supprimer des entités de votre inventaire, utilisez la fonction DELETE point de terminaison et envoyer des requêtes HTTP POST. Chaque requête POST doit Incluez le paramètre PARTNER_ID avec la charge utile JSON. contenant l'identifiant d'une entité de votre inventaire.
Supprimer la charge utile de la requête
La structure du corps d'une demande de suppression est semblable à celle
demande de mise à jour.
Il contient également une liste d'enregistrements avec les champs data_record
et delete_time
:
{ "records": [ { "data_record":"BASE_64_ENCODED_REFERENCE", "delete_time": "DELETE_TIMESTAMP" } ] }
Dans la charge utile ci-dessus, remplacez les éléments suivants:
BASE_64_ENCODED_REFERENCE: chaîne JSON encodée en base64 de la référence à l'entité en cours de suppression. Une référence ne se compose que à partir du type et de l'identifiant de l'entité, par exemple une représentation JSON d'une MenuSection:
{"@type":"MenuSection","@id":"853705"}
DELETE_TIMESTAMP: veillez à inclure le code temporel correspondant au moment où entité a été supprimée de votre système backend. Cet horodatage est utilisé pour déterminer l'ordre dans lequel les suppressions seront appliquées à l'inventaire.
Une requête batchDelete
peut contenir jusqu'à 1 000 entités.
Exemples
Exemple 1: Supprimer deux entités MenuItem
Pour supprimer deux éléments de menu dans un seul appel d'API, la requête HTTP POST doit ressembler à ceci : ce qui suit:
JSON
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": { "@type": "MenuItem", "@id": "item_1234" }, "delete_time": "2022-08-21T15:23:00.000Z" }, { "data_record": { "@type": "MenuItem", "@id": "item_5678" }, "delete_time": "2022-08-21T15:23:00.000Z" } ] }
Base64
Même exemple avec une charge utile encodée en base64.
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": "eyJAdHlwZSI6Ik1lbnVJdGVtIiwiQGlkIjoiaXRlbV8xMjM0In0=" "delete_time": "2022-08-21T15:23:00.000Z" }, { "data_record": "eyJAdHlwZSI6Ik1lbnVJdGVtIiwiQGlkIjoiaXRlbV81Njc4In0=" "delete_time": "2022-08-21T15:23:00.000Z" }, ] }
Exemple 2: Supprimer une entité Restaurant
Imaginons que vous souhaitiez supprimer un restaurant du flux par lot. Vous ne devez supprimer que l'entité "restaurant". Ne supprimez pas les sous-entités telles que et des menus, car ils seront supprimés automatiquement.
Exemple de requête pour supprimer une entité "restaurant" associée à un ID
https://www.provider.com/restaurant/12345
:
JSON
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": { "@type": "Restaurant", "@id": "https://www.provider.com/restaurant/12345" }, "delete_time": "2022-08-19T17:11:10.750Z" } ] }
Base64
Même exemple avec une charge utile encodée en base64.
POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete Host: mapsbooking.googleapis.com Content-Type: application/json { "records": [ { "data_record": "ewogICJAdHlwZSI6ICJSZXN0YXVyYW50IiwKICAiQGlkIjogImh0dHBzOi8vd3d3LnByb3ZpZGVyLmNvbS9yZXN0YXVyYW50LzEyMzQ1Igp9" "delete_time": "2022-08-19T17:11:10.750Z" } ] }
Validation et Codes de réponse de l'API
Il existe deux types de validations sur les appels d'API de mise à jour en temps réel:
Au niveau de la requête : ces validations vérifient que la charge utile suit la upsert ou delete schéma, et chaque
data_record
contient les champs@id
et@type
. Ces vérifications sont synchrones et les résultats sont renvoyés dans l'API. corps de la réponse. Un code de réponse 200 et un corps JSON vide{}
signifient que ces validations réussies et les entités concernées ont été mises en file d'attente en cours de traitement. Un code de réponse différent de 200 signifie qu'un ou plusieurs de ces et l'intégralité de la demande a été rejetée (y compris toutes entités de la charge utile). Par exemple, s'il manque un élémentdata_record
@type
, la réponse d'erreur suivante serait renvoyée:{ "error": { "code": 400, "message": "Record:{\"@id\":\"2717/86853/DELIVERY\",\"applicableServiceType\":[\"DELIVERY\",\"TAKEOUT\"],\"menuId\":[{\"@id\":\"2717/DELIVERY\",\"displayOrder\":1},{\"@id\":\"2717/TAKEOUT\",\"displayOrder\":2}],\"name\":\"Salad\",\"offeredById\":[\"2717\"]} has following errors: \nThe entity type could not be extracted from the entity value.\n", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.DebugInfo", "detail": "[ORIGINAL ERROR] generic::invalid_argument: Failed to parse one or more rtu records. Record:{\"@id\":\"2717/86853/DELIVERY\",\"applicableServiceType\":[\"DELIVERY\",\"TAKEOUT\"],\"menuId\":[{\"@id\":\"2717/DELIVERY\",\"displayOrder\":1},{\"@id\":\"2717/TAKEOUT\",\"displayOrder\":2}],\"name\":\"Salad\",\"offeredById\":[\"2717\"]} has following errors: \nThe entity type could not be extracted from the entity value.\n [google.rpc.error_details_ext] { message: \"Record:{\\\"@id\\\":\\\"2717/86853/DELIVERY\\\",\\\"applicableServiceType\\\":[\\\"DELIVERY\\\",\\\"TAKEOUT\\\"],\\\"menuId\\\":[{\\\"@id\\\":\\\"2717/DELIVERY\\\",\\\"displayOrder\\\":1},{\\\"@id\\\":\\\"2717/TAKEOUT\\\",\\\"displayOrder\\\":2}],\\\"name\\\":\\\"Salad\\\",\\\"offeredById\\\":[\\\"2717\\\"]} has following errors: \\nThe entity type could not be extracted from the entity value.\\n\" }" } ] } }
Au niveau de l'entité : chaque entité de la charge utile est validée par rapport à la schéma relationnel. Les problèmes rencontrés lors de cette phase de validation ne sont pas signalés dans l'API de réponse. Elles ne sont signalées que dans le Rapports en temps réel tableau de bord.
Quotas d'API
Les mises à jour d'API en temps réel ont un quota de 1 500 requêtes toutes les 60 secondes, soit 25 de requêtes par seconde en moyenne. Lorsqu'un quota est dépassé, Google répond avec le message d'erreur suivant:
{ "error": { "code": 429, "message": "Insufficient tokens for quota ...", "status": "RESOURCE_EXHAUSTED", "details": [...] } }
Pour gérer cela, relancez l'appel à des intervalles exponentiellement plus grands jusqu'à ce qu'il réussisse. Si vous épuisez régulièrement le quota, envisagez d'inclure d'autres entités dans une même requête API. Vous pouvez inclure jusqu'à 1 000 entités dans un appel d'API.
Exemples de code
Vous trouverez ci-dessous des exemples d'utilisation de l'API de mise à jour en temps réel dans différentes langues. Ces exemples utilisent les bibliothèques Google Auth pour l'authentification à l'aide d'un le fichier de clé de compte de service généré Configuration du compte Pour d'autres solutions, reportez-vous à Utiliser OAuth 2.0 pour l'authentification serveur à serveur Pensez à utiliser le schéma disponible sur la page Générer des bibliothèques clientes afin de générer le code source pour les types d'objets d'inventaire et de mise à jour en temps réel.
Mettre à jour des entités
Node.js
Ce code utilise la bibliothèque d'authentification Google pour Node.js.
/* Sample code for Real-time update batchPush implementation. * * Required libraries: * - google-auth-library */ const {JWT} = require('google-auth-library'); // ACTION REQUIRED: Change this to the path of the service account client secret // file downloaded from the Google Cloud Console. const serviceAccountJson = require('./service-account.json'); // ACTION REQUIRED: Change this to your Partner ID received from Google. // The Partner ID is available on the Partner Portal. const PARTNER_ID = 1234; const HOST = { prod: 'https://mapsbooking.googleapis.com', sandbox: 'https://partnerdev-mapsbooking.googleapis.com' }; // ACTION REQUIRED: Change to 'prod' for production const ENV = 'sandbox'; // Feed name for Order with Google including the version. const FEED_NAME = 'owg.v2'; // Endpoint url const url = `${HOST[ENV]}/v1alpha/inventory/partners/${PARTNER_ID}/feeds/${ FEED_NAME}/record:batchPush`; /** * Send a Real-time update request to update/insert entities */ async function batchUpsert(entities) { /** * Sign JWT token using private key from service account secret file * provided. The client can be created without providing a service account * secret file by implementing Application Default Credentials. * https://github.com/googleapis/google-auth-library-nodejs */ const client = new JWT({ email: serviceAccountJson.client_email, key: serviceAccountJson.private_key, scopes: ['https://www.googleapis.com/auth/mapsbooking'], }); const request = {records: toPushRecords(entities)}; const body = JSON.stringify(request); try { const response = await client.request({ method: 'POST', url, data: body, headers: {'Content-Type': 'application/json'} }); console.log('request body:', body); console.log('response status:', response.status); console.log( 'response data:', response.data); // successful response returns '{}' } catch (error) { console.log('error:', error); } } /** * Maps array of entities to records for batch push requests */ const toPushRecords = (entities) => { return entities.map((entity) => { // Using dateModified to set generation_timestamp. Defaulting to the // current timestamp for records that do not have dateModified. const generation_timestamp = entity.dateModified ? entity.dateModified : new Date().toISOString(); return {data_record: btoa(JSON.stringify(entity)), generation_timestamp}; }); }; // Call batchUpsert with example entities. dateModified is optional and is // used to hold the actual timestamp when the entity was updated/created. batchUpsert([ { '@type': 'MenuItemOffer', '@id': '6680261', 'menuItemId': '18931508', 'price': 15.5, 'priceCurrency': 'USD', 'applicableServiceType': ['DELIVERY', 'TAKEOUT'], 'inventoryLevel': 0, 'dateModified': '2022-06-19T15:43:50.970Z' }, { '@type': 'MenuItemOffer', '@id': '6680262', 'menuItemId': '18931509', 'price': 25.5, 'priceCurrency': 'USD', 'applicableServiceType': ['DELIVERY', 'TAKEOUT'], 'inventoryLevel': 0, 'dateModified': '2022-06-19T15:43:50.970Z' } ]);
Python
Ce code utilise la bibliothèque d'authentification Google pour Python.
"""Sample code for the Real-time update batchPush implementation.""" # Required libraries: # - google-auth import base64 import datetime import json from google.auth.transport.requests import AuthorizedSession from google.oauth2 import service_account # ACTION REQUIRED: Change this to the Partner ID received from Google. # Partner ID is available on the Partner Portal. # https://partnerdash.google.com/apps/reservewithgoogle _PARTNER_ID = '1234' # ACTION REQUIRED: Change this to the path of the service account client secret # file downloaded from the Google Cloud Console. _SERVICE_ACCOUNT_KEY_JSON_FILE = 'service-account-creds.json' _HOST_MAP = { 'sandbox': 'https://partnerdev-mapsbooking.googleapis.com', 'prod': 'https://mapsbooking.googleapis.com' } # ACTION REQUIRED: Change to 'prod' for production _ENV = 'sandbox' # Feed name for Order with Google including the version. _FEED_NAME = 'owg.v2' _ENDPOINT = '{}/v1alpha/inventory/partners/{}/feeds/{}/record:batchPush'.format( _HOST_MAP[_ENV], _PARTNER_ID, _FEED_NAME) def batch_upsert(entities): """Makes a batchPush request using the Real-time updates REST service. Args: entities: The list of entity objects to update or add. """ # Creates credentials by providing a json file. Credentials can also be # provided by implementing Application Default Credentials. # https://googleapis.dev/python/google-auth/latest/user-guide.html credentials = service_account.Credentials.from_service_account_file( _SERVICE_ACCOUNT_KEY_JSON_FILE, scopes=['https://www.googleapis.com/auth/mapsbooking']) authorized_session = AuthorizedSession(credentials) # JSON request object batch_request = {'records': [create_push_record(x) for x in entities]} response = authorized_session.post(_ENDPOINT, json=batch_request) print('request body:', json.dumps(batch_request)) print('response status:', response.status_code) print('response data:', response.text) # successful response returns '{}' def create_push_record(entity): """Creates a record from an entity for batchPush requests. Args: entity: The entity object to create the record from. Returns: The constructed record for the batchPush request payload. """ data_bytes = json.dumps(entity).encode('utf-8') base64_bytes = base64.b64encode(data_bytes) # Using dateModified to set generation_timestamp. Defaulting to the # current timestamp for records that do not have dateModified. generation_timestamp = entity.dateModified if 'dateModified' in entity else datetime.datetime.now( ).strftime('%Y-%m-%dT%H:%M:%S.%fZ') return { 'generation_timestamp': generation_timestamp, 'data_record': base64_bytes.decode('utf-8') } # Call batch_upsert with example entities. dateModified is optional and is # used to hold the actual timestamp when the entity was updated/created. batch_upsert([{ '@type': 'MenuItemOffer', '@id': '6680261', 'menuItemId': '18931508', 'price': 15.5, 'priceCurrency': 'USD', 'applicableServiceType': ['DELIVERY', 'TAKEOUT'], 'inventoryLevel': 0, 'dateModified': '2022-06-19T15:43:50.970Z' }, { '@type': 'MenuItemOffer', '@id': '6680262', 'menuItemId': '18931509', 'price': 25.5, 'priceCurrency': 'USD', 'applicableServiceType': ['DELIVERY', 'TAKEOUT'], 'inventoryLevel': 0, 'dateModified': '2022-06-19T15:43:50.970Z' }])
Java
Ce code utilise la bibliothèque d'authentification Google pour Java.
Les modèles de code source client dans les packages rtusamples.inventory
et rtusamples.realtime
ont été créés en suivant la procédure décrite dans Générer des bibliothèques clientes.
/* * Required Libraries: * - JDK >= 11 * - google-auth-library-oauth2-http */ package rtusamples; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; import java.io.FileInputStream; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.nio.charset.Charset; import java.time.Clock; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import rtusamples.inventory.MenuItemOffer; import rtusamples.inventory.MenuItemOfferType; import rtusamples.inventory.ServiceTypeElement; import rtusamples.realtime.BatchPushGenericRecordRequest; import rtusamples.realtime.GenericRecord; /** Sample code for Real-time update batchPush implementation. */ public final class BasicPush { // ACTION REQUIRED: Change this to your Partner ID received from Google. The Partner ID is // available on the Partner Portal. private static final long PARTNER_ID = 12345678; // ACTION REQUIRED: Change this to the path of the service account client secret file downloaded // from the Google Cloud Console. private static final String JSON_KEY_FULL_PATH = "<path to your JSON credentials>/credentials.json"; // ACTION REQUIRED: Change this to the endpoint that is needed. private static final String ENDPOINT = // "https://partnerdev-mapsbooking.googleapis.com"; // for sandbox "https://mapsbooking.googleapis.com"; // for prod // Feed name for Order with Google including the version. private static final String FEED_NAME = "owg.v2"; private static final ObjectMapper objectMapper = new ObjectMapper(); private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'"); private static final Charset UTF_8 = Charset.forName("UTF-8"); public static void main(String[] args) throws Exception { /** * Create credentials from service account secret file. Alternatively, the credentials can be * created by implementing Application Default Credentials. * https://github.com/googleapis/google-auth-library-java */ // GoogleCredentials sourceCredentials = // GoogleCredentials.getApplicationDefault() // .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking")); // ImpersonatedCredentials credentials = // ImpersonatedCredentials.create( // sourceCredentials, // "fo-test@projectname.iam.gserviceaccount.com", // null, // Arrays.asList("https://www.googleapis.com/auth/mapsbooking"), // 300); GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(JSON_KEY_FULL_PATH)) .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking")); // Create example MenuItemOffer entities, dateModified is optional and is used to hold // the actual timestamp when the entity was updated/created. MenuItemOffer menuItemOfferPizza = new MenuItemOffer(); menuItemOfferPizza.setID("6680261"); menuItemOfferPizza.setType(MenuItemOfferType.MENU_ITEM_OFFER); menuItemOfferPizza.setMenuItemID("18931508"); menuItemOfferPizza.setPrice(15.5); menuItemOfferPizza.setPriceCurrency("USD"); menuItemOfferPizza.setApplicableServiceType( new ServiceTypeElement[] {ServiceTypeElement.TAKEOUT, ServiceTypeElement.DELIVERY}); menuItemOfferPizza.setInventoryLevel(0.0); menuItemOfferPizza.setDateModified("2022-10-07T13:00:00.000Z"); MenuItemOffer menuItemOfferSalad = new MenuItemOffer(); menuItemOfferSalad.setID("6680262"); menuItemOfferSalad.setType(MenuItemOfferType.MENU_ITEM_OFFER); menuItemOfferSalad.setMenuItemID("18931509"); menuItemOfferSalad.setPrice(25.5); menuItemOfferSalad.setPriceCurrency("USD"); menuItemOfferSalad.setApplicableServiceType( new ServiceTypeElement[] {ServiceTypeElement.TAKEOUT, ServiceTypeElement.DELIVERY}); menuItemOfferSalad.setInventoryLevel(0.0); menuItemOfferSalad.setDateModified("2022-10-07T13:00:00.000Z"); // Example array of MenuItemOffer entities to update. List<MenuItemOffer> menuItemOffers = Arrays.asList(menuItemOfferPizza, menuItemOfferSalad); // Create list of GenericRecord from menuItemOffers. List<GenericRecord> menuItemOfferGenericRecords = menuItemOffers.stream() .map( (menuItemOffer) -> toBatchPushRecord(menuItemOffer, menuItemOffer.getDateModified())) .collect(Collectors.toList()); // List of records to be updated/created. List<GenericRecord> recordsToBeUpdated = new ArrayList<>(); // Add list of menuItemOffer generic records. recordsToBeUpdated.addAll(menuItemOfferGenericRecords); // Request object that contains all records. BatchPushGenericRecordRequest batchPushRequest = new BatchPushGenericRecordRequest(); batchPushRequest.setRecords(recordsToBeUpdated.toArray(new GenericRecord[0])); // Execute batchPush request. BasicPush basicPush = new BasicPush(); basicPush.batchPush(batchPushRequest, credentials); } public void batchPush( BatchPushGenericRecordRequest batchPushRequest, GoogleCredentials credentials) throws IOException { credentials.refreshIfExpired(); AccessToken token = credentials.getAccessToken(); String requestBody = objectMapper.writeValueAsString(batchPushRequest); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri( URI.create( String.format( "%s/v1alpha/inventory/partners/%s/feeds/%s/record:batchPush", ENDPOINT, PARTNER_ID, FEED_NAME))) .header("Content-Type", "application/json") .header("Authorization", String.format("Bearer %s", token.getTokenValue())) .POST(BodyPublishers.ofString(requestBody)) .build(); HttpResponse<String> response = null; try { response = client.send(request, BodyHandlers.ofString()); System.out.println("Request body:" + requestBody); System.out.println("Response status:" + response.statusCode()); System.out.println("Response body:" + response.body()); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } public static <T> GenericRecord toBatchPushRecord(T entity, String dateModified) { GenericRecord genericRecord = new GenericRecord(); try { String json = objectMapper.writeValueAsString(entity); genericRecord.setDataRecord(Base64.getEncoder().encodeToString(json.getBytes(UTF_8))); // Using dateModified to set generation_timestamp. Defaulting to the // current timestamp for records that do not have dateModified. String generationTimestamp = Optional.ofNullable(dateModified) .orElse(OffsetDateTime.now(Clock.systemUTC()).format(TIMESTAMP_FORMATTER)); genericRecord.setGenerationTimestamp(generationTimestamp); } catch (JsonProcessingException e) { System.out.println(e.getMessage()); } return genericRecord; } }
Supprimer des entités
Node.js
Ce code utilise la bibliothèque d'authentification Google pour Node.js.
/* Sample code for Real-time update batchDelete implementation. * * Required libraries: * - google-auth-library */ const {JWT} = require('google-auth-library'); // ACTION REQUIRED: Change this to the path of the service account client secret // file downloaded from the Google Cloud Console. const serviceAccountJson = require('./service-account.json'); // ACTION REQUIRED: Change this to your Partner ID received from Google. // The Partner ID is available on the Partner Portal. const PARTNER_ID = 1234; const HOST = { prod: 'https://mapsbooking.googleapis.com', sandbox: 'https://partnerdev-mapsbooking.googleapis.com' }; // ACTION REQUIRED: Change to 'prod' for production const ENV = 'sandbox'; // Feed name for Order with Google including the version. const FEED_NAME = 'owg.v2'; // Endpoint url const url = `${HOST[ENV]}/v1alpha/inventory/partners/${PARTNER_ID}/feeds/${ FEED_NAME}/record:batchDelete`; /** * Send a Real-time update request to delete entities */ async function batchDelete(entities) { try { /** * Sign JWT token using private key from service account secret file * provided. The client can be created without providing a service account * secret file by implementing Application Default Credentials. * https://github.com/googleapis/google-auth-library-nodejs */ const client = new JWT({ email: serviceAccountJson.client_email, key: serviceAccountJson.private_key, scopes: ['https://www.googleapis.com/auth/mapsbooking'], }); const request = { records: toDeleteRecords(entities) }; const body = JSON.stringify(request); try { const response = await client.request({ method: 'POST', url, data: body, headers: {'Content-Type': 'application/json'} }); console.log('request body:', body); console.log('response status:', response.status); console.log('response data:', response.data); // successful response returns '{}' } catch (error) { console.log('error:', error); } } /** * Maps array of entities to records for batch delete requests */ const toDeleteRecords = (entities) => { return entities.map((entity) => { // Using dateModified to set delete_time. Defaulting to the current // timestamp for records that do not have dateModified. const delete_time = entity.dateModified ? entity.dateModified : new Date().toISOString(); return {data_record: btoa(JSON.stringify(entity)), delete_time}; }); }; // Call batchDelete with example entities. dateModified is optional and is // used to hold the actual timestamp when the entity was deleted. batchDelete([ { '@type': 'Menu', '@id': '853706', 'dateModified': '2022-06-19T15:43:50.970Z' }, { '@type': 'Menu', '@id': '853705', 'dateModified': '2022-06-19T15:13:00.280Z' } ]);
Python
Ce code utilise la bibliothèque d'authentification Google pour Python.
"""Sample code for the Real-time update batchDelete implementation.""" # Required libraries: # - google-auth import base64 import datetime import json from google.auth.transport.requests import AuthorizedSession from google.oauth2 import service_account # ACTION REQUIRED: Change this to the Partner ID received from Google. # Partner ID is available on the Partner Portal. # https://partnerdash.google.com/apps/reservewithgoogle _PARTNER_ID = '1234' # ACTION REQUIRED: Change this to the path of the service account client secret # file downloaded from the Google Cloud Console. _SERVICE_ACCOUNT_KEY_JSON_FILE = 'service-account-creds.json' _HOST_MAP = { 'sandbox': 'https://partnerdev-mapsbooking.googleapis.com', 'prod': 'https://mapsbooking.googleapis.com' } # ACTION REQUIRED: Change to 'prod' for production _ENV = 'sandbox' # Feed name for Order with Google including the version. _FEED_NAME = 'owg.v2' _ENDPOINT = '{}/v1alpha/inventory/partners/{}/feeds/{}/record:batchDelete'.format( _HOST_MAP[_ENV], _PARTNER_ID, _FEED_NAME) def batch_delete(entities): """Makes a batch delete request using the Real-time updates REST service. Args: entities: The list of entity objects to delete. """ # Creates credentials by providing a json file. Credentials can also be # provided by implementing Application Default Credentials. # https://googleapis.dev/python/google-auth/latest/user-guide.html credentials = service_account.Credentials.from_service_account_file( _SERVICE_ACCOUNT_KEY_JSON_FILE, scopes=['https://www.googleapis.com/auth/mapsbooking']) authorized_session = AuthorizedSession(credentials) # JSON request object batch_request = {'records': [create_delete_record(x) for x in entities]} response = authorized_session.post(_ENDPOINT, json=batch_request) print('request body:', json.dumps(batch_request)) print('response status:', response.status_code) print('response data:', response.text) # successful response returns '{}' def create_delete_record(entity): """Creates a record from an entity for batchDelete requests. Args: entity: The entity object to create the record from. Returns: The constructed record for the batchDelete request payload. """ data_bytes = json.dumps(entity).encode('utf-8') base64_bytes = base64.b64encode(data_bytes) # Using dateModified to set delete_time. Defaulting to the current # timestamp for records that do not have dateModified. delete_time = entity.dateModified if 'dateModified' in entity else datetime.datetime.now( ).strftime('%Y-%m-%dT%H:%M:%S.%fZ') return { 'delete_time': delete_time, 'data_record': base64_bytes.decode('utf-8') } # Call batch_delete with example entities. dateModified is optional and is # used to hold the actual timestamp when the entity was deleted. batch_delete([{ '@type': 'Menu', '@id': '853706', 'dateModified': '2022-06-19T13:10:00.000Z' }, { '@type': 'Menu', '@id': '853705', 'dateModified': '2022-06-19T13:30:10.000Z' }])
Java
Ce code utilise la bibliothèque d'authentification Google pour Java.
Les modèles de code source client dans les packages rtusamples.inventory
et rtusamples.realtime
ont été créés en suivant la procédure décrite dans Générer des bibliothèques clientes.
/* * Required Libraries: * - JDK >= 11 * - google-auth-library-oauth2-http */ package rtusamples; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.auth.oauth2.AccessToken; import com.google.auth.oauth2.GoogleCredentials; import java.io.FileInputStream; import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; import java.nio.charset.Charset; import java.time.Clock; import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import rtusamples.inventory.Menu; import rtusamples.inventory.MenuType; import rtusamples.realtime.BatchDeleteGenericRecordsRequest; import rtusamples.realtime.GenericDeleteRecord; /** Sample code for the Real-time update batchDelete implementation. */ public final class BasicDelete { // ACTION REQUIRED: Change this to your Partner ID received from Google. The Partner ID is // available on the Partner Portal. private static final long PARTNER_ID = 123456789; // ACTION REQUIRED: Change this to the path of the service account client secret file downloaded // from the Google Cloud Console. private static final String JSON_KEY_FULL_PATH = "<path to your JSON credentials>/credentials.json"; // ACTION REQUIRED: Change this to the endpoint that is needed. private static final String ENDPOINT = "https://partnerdev-mapsbooking.googleapis.com"; // for sandbox // "https://mapsbooking.googleapis.com" // for prod // Feed name for Order with Google including the version. private static final String FEED_NAME = "owg.v2"; private static final ObjectMapper objectMapper = new ObjectMapper(); private static final DateTimeFormatter TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'"); private static final Charset UTF_8 = Charset.forName("UTF-8"); public static void main(String[] args) throws Exception { /** * Create credentials from service account secret file. Alternatively, the credentials can be * created by implementing Application Default Credentials. * https://github.com/googleapis/google-auth-library-java */ // GoogleCredentials sourceCredentials = // GoogleCredentials.getApplicationDefault() // .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking")); // ImpersonatedCredentials credentials = // ImpersonatedCredentials.create( // sourceCredentials, // "fo-test@projectname.iam.gserviceaccount.com", // null, // Arrays.asList("https://www.googleapis.com/auth/mapsbooking"), // 300); GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(JSON_KEY_FULL_PATH)) .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking")); // Create example Menu entities, dateModified is optional and is used to hold // the actual timestamp when the entity was deleted. Menu menuLunch = new Menu(); menuLunch.setID("853705"); menuLunch.setType(MenuType.MENU); menuLunch.setDateModified("2022-09-19T13:10:00.000Z"); Menu menuDinner = new Menu(); menuDinner.setID("853706"); menuDinner.setType(MenuType.MENU); menuDinner.setDateModified("2022-09-19T13:13:10.000Z"); // Example array of Menu entities to update. List<Menu> menus = Arrays.asList(menuLunch, menuDinner); // Create list of GenericDeleteRecord from menus. List<GenericDeleteRecord> menuGenericDeleteRecords = menus.stream() .map((menu) -> toBatchDeleteRecord(menu, menu.getDateModified())) .collect(Collectors.toList()); // List of records to be deleted. List<GenericDeleteRecord> recordsToBeDeleted = new ArrayList<>(); // Add list of menu generic records. recordsToBeDeleted.addAll(menuGenericDeleteRecords); // Request object that contains all records. BatchDeleteGenericRecordsRequest batchDeleteRequest = new BatchDeleteGenericRecordsRequest(); batchDeleteRequest.setRecords(recordsToBeDeleted.toArray(new GenericDeleteRecord[0])); // Execute batchDelete request. BasicDelete basicDelete = new BasicDelete(); basicDelete.batchDelete(batchDeleteRequest, credentials); } public void batchDelete( BatchDeleteGenericRecordsRequest batchDeleteRequest, GoogleCredentials credentials) throws IOException { credentials.refreshIfExpired(); AccessToken token = credentials.getAccessToken(); String requestBody = objectMapper.writeValueAsString(batchDeleteRequest); HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri( URI.create( String.format( "%s/v1alpha/inventory/partners/%s/feeds/%s/record:batchDelete", ENDPOINT, PARTNER_ID, FEED_NAME))) .header("Content-Type", "application/json") .header("Authorization", String.format("Bearer %s", token.getTokenValue())) .POST(BodyPublishers.ofString(requestBody)) .build(); HttpResponse<String> response = null; try { response = client.send(request, BodyHandlers.ofString()); System.out.println("Request body:" + requestBody); System.out.println("Response status:" + response.statusCode()); System.out.println("Response body:" + response.body()); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } public static <T> GenericDeleteRecord toBatchDeleteRecord(T entity, String dateModified) { GenericDeleteRecord genericRecord = new GenericDeleteRecord(); try { String json = objectMapper.writeValueAsString(entity); genericRecord.setDataRecord(Base64.getEncoder().encodeToString(json.getBytes(UTF_8))); // Using dateModified to set delete_time. Defaulting to the current // timestamp for records that do not have dateModified. String deleteTime = Optional.ofNullable(dateModified) .orElse(OffsetDateTime.now(Clock.systemUTC()).format(TIMESTAMP_FORMATTER)); genericRecord.setDeleteTime(deleteTime); } catch (JsonProcessingException e) { System.out.println(e.getMessage()); } return genericRecord; } }
Cas d'utilisation
Voici des exemples de mises à jour en temps réel, de mises à jour de flux par lot, 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 en temps réel: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 en temps réel: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 en temps réel: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 en temps réel:envoyez une 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 groupés: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 groupés:envoyez la ServiceHours comme 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 par lot:envoyer la version complète de Fee avec
price mis à jour. |
Modifier les horaires de livraison ou de vente à emporter dans Service |
ServiceHours |
Flux groupés:envoyez la ServiceHours comme 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 par lot:envoyer un Fee complet avec
minPrice
mis à jour |
Supprimer définitivement un(e) MenuItem |
Menu |
Flux groupés:envoyez l'MenuItem de la même manière que dans
flux, mais avec parentMenuSectionId vide.
|
Délais de traitement des jobs par lot et des mises à jour en temps réel
Une entité mise à jour ou supprimée via un flux par lot est traitée dans un délai de 2 alors qu'une entité mise à jour en temps réel est traitée 5 minutes A entité obsolète supprimé dans 14 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 mises à jour en temps réel pour garder votre inventaire à jour