Z tej sekcji dowiesz się, jak wysyłać do Google uaktualnienia zasobów reklamowych, które mają znaczenie czasowe. Interfejs API aktualizacji w czasie rzeczywistym umożliwia przesyłanie aktualizacji i usuwanie elementów w asortymencie w piaskownicy lub w środowisku produkcyjnym w czasie zbliżonym do rzeczywistego.
Ta funkcja jest przeznaczona przede wszystkim do wprowadzania aktualizacji, których nie można przewidzieć, takich jak zamknięcie lokalu z powodu awarii, usunięcie pozycji z menu czy zmiana ceny pozycji w menu, które muszą być szybko odzwierciedlone w interfejsie Google. Jeśli zmiana nie musi być odzwierciedlona natychmiast, możesz użyć przetworzenia zbiorczego. Aktualizacje w czasie rzeczywistym są przetwarzane w ciągu nie więcej niż 5 minut.
Wymagania wstępne
Przed wdrożeniem aktualizacji w czasie rzeczywistym musisz wykonać te czynności:
- Interfejs Maps Booking API jest włączony:
- W konsoli Google Cloud Platform otwórz Interfejsy API i usługi > Biblioteka.
- Wyszukaj „Google Maps Booking API”
- Znajdź instancję piaskownicy („Google Maps Booking API (Dev)”) i kliknij Włącz.
- Znajdź instancję produkcyjną („Google Maps Booking API”) i kliknij Włącz
- Tworzone jest konto usługi z przypisaną rolą edytującego w Twoim projekcie GCP. Więcej informacji znajdziesz w sekcji Konfiguracja konta.
- Pliki danych produkcyjne lub z piaskownicy są hostowane i przetwarzane. Więcej informacji znajdziesz w artykule Przesyłanie zbiorcze.
- W przypadku uwierzytelniania interfejsu API zalecamy zainstalowanie biblioteki klienta Google w wybranym języku. Jako zakres uprawnień OAuth użyj adresu „https://www.googleapis.com/auth/mapsbooking”. Poniżej znajdziesz przykłady kodu, które korzystają z tych bibliotek. W przeciwnym razie musisz ręcznie przeprowadzić wymianę tokenów zgodnie z opisem w artykule Uzyskiwanie dostępu do interfejsów API Google za pomocą protokołu OAuth 2.0.
Omówienie
Interfejs API aktualizacji w czasie rzeczywistym obsługuje 2 typy operacji. Pierwsza operacja to upsert służący do aktualizowania dotychczasowych elementów. Druga operacja to usuwanie elementów z Twojego zasobu reklamowego. Oba te działania są wykonywane na różnych elementach wymienionych w treści żądania. W jednym wywołaniu interfejsu API możesz zaktualizować do 1000 podmiotów. Interfejs API akceptuje wszystkie przychodzące żądania i umieszcza je w kolejce do dalszego przetwarzania. Dlatego żądania RTU są przetwarzane asynchronicznie.
Interfejs API aktualizacji w czasie rzeczywistym działa w 2 środowiskach: piaskownicy i środowisku produkcyjnym. Środowisko piaskownicy służy do testowania żądań interfejsu API, a środowisko produkcyjne do aktualizowania treści widocznych dla użytkowników usługi Zamów wszystko. Nazwy hostów obu środowisk:
- Piaskownica –
partnerdev-mapsbooking.googleapis.com
- Produkcja –
mapsbooking.googleapis.com
Punkty końcowe
Interfejs API aktualizacji w czasie rzeczywistym udostępnia 2 punkty końcowe do obsługi żądań dotyczących aktualizacji zasobów:
- UPSERT -
/v1alpha/inventory/partners/
PARTNER_ID/feeds/owg.v2/record:batchPush
- DELETE -
/v1alpha/inventory/partners/
PARTNER_ID/feeds/owg.v2/record:batchDelete
Parametr PARTNER_ID znajdziesz w Centrum działań, gdzie jest wyświetlany jako identyfikator partnera na stronie Konto i użytkownicy, jak pokazano na poniższym zrzucie ekranu.
Na podstawie przykładowego zrzutu ekranu z wartością PARTNER_ID = 10000001, pełne adresy URL do wysyłania żądań interfejsu API w sandbox i produkcji będą wyglądać jak w przykładach poniżej.
# 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
Aktualizuję elementy
Aby aktualizować elementy w swoim katalogu, użyj punktu końcowego UPSERT i wyślij żądania HTTP POST. Każde żądanie POST musi zawierać parametr PARTNER_ID wraz z ładunkiem JSON zawierającym uporządkowane dane dowolnego typu elementu wymienionego w schemacie asortymentu.
Ładunek żądania upsert
Treść żądania to obiekt JSON z listą rekordów. Każdy rekord odpowiada aktualizowanemu elementowi. Pole to składa się z pola data_record
z zawartością elementu zakodowaną w formacie Base64 oraz pola generation_timestamp
, które wskazuje czas aktualizacji elementu:
{ "records": [ { "data_record":"BASE_64_ENCODED_ENTITY", "generation_timestamp":"UPDATE_TIMESTAMP" } ] }
W powyższym pliku danych zastąp:
BASE_64_ENCODED_ENTITY: zakodowany w formacie Base64 ciąg znaków JSON obiektu. Sformatowany obiekt JSON powinien mieć taką samą strukturę jak w specyfikacji pliku danych, np.:
{"@type":"MenuSection","name":"My Updated Menu Section","menuId":{"@id":"10824","displayOrder":1},"@id":"853705"}
UPDATE_TIMESTAMP: pamiętaj, aby uwzględnić sygnaturę czasową, kiedy w Twoich systemach backendu wygenerowano dany obiekt. Ta sygnatura czasowa służy do zapewnienia prawidłowej kolejności aktualizacji asortymentu. Jeśli to pole nie zostanie uwzględnione, zostanie ustawione na czas, w którym Google otrzyma prośbę. Podczas aktualizowania elementu za pomocą żądania
batchPush
polegeneration_timestamp
służy do tworzenia wersji elementu. Sprawdź oczekiwany format wartości czasu w relacyjnej strukturze pliku danych o zasobach reklamowych.
Każde żądanie aktualizacji w czasie rzeczywistym musi spełniać te warunki:
- Rozmiar ładunku nie powinien przekraczać 5 MB. Podobnie jak w przypadku plików danych zbiorczych, zalecamy usunięcie spacji, aby zmieścić więcej danych.
- W żądaniu
batchPush
może być wymienionych maksymalnie 1000 elementów.
Przykłady
Przykład 1. Aktualizowanie restauracji
Załóżmy, że musisz pilnie zaktualizować numer telefonu restauracji. Aktualizacja zawiera plik JSON całej restauracji.
Weź pod uwagę plik danych zbiorczego, który wygląda tak:
{ "@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 }
Wtedy Twoje żądanie HTTP POST z aktualizacją w czasie rzeczywistym będzie wyglądać tak:
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
Ten sam przykład z ładunkiem zakodowanym w formacie 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" } ] }
Przykład 2. Aktualizowanie wielu restauracji
Aby zaktualizować 2 elementy restauracji w jednym wywołaniu interfejsu API, żądanie HTTP POST będzie wyglądać tak:
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
Ten sam przykład z ładunkiem zakodowanym w formacie 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" } ] }
Przykład 3. Aktualizowanie ceny pozycji menu
Załóżmy, że musisz zmienić cenę pozycji menu.
Weź pod uwagę plik danych zbiorczego, który wygląda tak:
{ "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 2, "priceCurrency": "USD" }
Wtedy aktualizacja w czasie rzeczywistym za pomocą żądania POST będzie wyglądać tak:
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
Ten sam przykład z ładunkiem zakodowanym w formacie 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" } ] }
Dodawanie elementów
Nie używaj aktualizacji w czasie rzeczywistym do dodawania nowych elementów, ponieważ może to spowodować niespójności danych. Zamiast tego użyj procesu przetwarzania plików zbiorczych opisanego w sekcji przetwarzanie zbiorcze.
Usuwanie elementów
Aby usunąć elementy ze swojego zasobu, użyj punktu końcowego DELETE i wyślij żądania HTTP POST. Każde żądanie POST musi zawierać parametr PARTNER_ID wraz z danymi JSON zawierającymi identyfikator dowolnego elementu w Twoim asortymencie.
Payload żądania usunięcia
Treść żądania usunięcia jest sformatowana podobnie do żądania aktualizacji.
Zawiera ona też listę rekordów z polami data_record
i delete_time
:
{ "records": [ { "data_record":"BASE_64_ENCODED_REFERENCE", "delete_time": "DELETE_TIMESTAMP" } ] }
W powyższym pliku danych zastąp:
BASE_64_ENCODED_REFERENCE: zakodowany w formacie Base64 ciąg znaków JSON odwołania do obiektu, który jest usuwany. Odwołania składają się tylko z typu i identyfikatora, np. reprezentacja JSON odwołania do MenuSection:
{"@type":"MenuSection","@id":"853705"}
DELETE_TIMESTAMP: pamiętaj, aby podać sygnaturę czasową usunięcia elementu w systemie backendu. Ten znacznik czasu służy do określenia kolejności, w jakiej usunięcie zostanie zastosowane do zasobów reklamowych.
W żądaniu batchDelete
może być wymienionych maksymalnie 1000 elementów.
Przykłady
Przykład 1. Usuwanie 2 elementów MenuItem
Aby usunąć 2 pozycje menu w jednym wywołaniu interfejsu API, żądanie HTTP POST będzie wyglądać tak:
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
Ten sam przykład z ładunkiem zakodowanym w formacie 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" }, ] }
Przykład 2. Usuwanie encji Restaurant
Wyobraź sobie sytuację, w której chcesz usunąć restaurację z pliku danych zbiorczego. Musisz usunąć tylko element restauracji. Nie usuwaj podelementów, takich jak usługi czy menu, ponieważ zostaną one usunięte automatycznie.
Przykładowa prośba o usunięcie elementu restauracji o identyfikatorzehttps://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
Ten sam przykład z ładunkiem zakodowanym w formacie 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" } ] }
Kody odpowiedzi weryfikacji i interfejsu API
W przypadku wywołań interfejsu API służących do aktualizacji w czasie rzeczywistym przeprowadzane są 2 typy weryfikacji:
Na poziomie żądania – te weryfikacje sprawdzają, czy ładunek jest zgodny ze schematem upsert lub delete, a każdy element
data_record
zawiera pola@id
i@type
. Te weryfikacje są synchroniczne, a ich wyniki są zwracane w ciele odpowiedzi interfejsu API. Kod odpowiedzi 200 i pusta treść JSON{}
oznaczają, że te weryfikacje zostały pomyślnie wykonane, a elementy w tym żądaniu zostały umieszczone w kolejce do przetwarzania. Kod odpowiedzi inny niż 200 oznacza, że co najmniej 1 z tych weryfikacji zakończyła się niepowodzeniem i cała prośba została odrzucona (w tym wszystkie elementy w ładunku). Jeśli na przykład w elementachdata_record
brakuje elementu@type
, zwracana jest taka odpowiedź z błędem:{ "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\" }" } ] } }
Na poziomie elementu – każdy element w pliku danych jest weryfikowany pod kątem zgodności ze schematem relacyjno-obiektowym. Problemy występujące na tym etapie weryfikacji nie są zgłaszane w odpowiedzi interfejsu API. Są one raportowane tylko w panelu Raporty RTU.
Limity interfejsu API
Limit interfejsu API na potrzeby aktualizacji w czasie rzeczywistym wynosi 1500 żądań co 60 sekund, czyli średnio 25 żądań na sekundę. Gdy przekroczysz limit, Google odpowie komunikatem o błędzie:
{ "error": { "code": 429, "message": "Insufficient tokens for quota ...", "status": "RESOURCE_EXHAUSTED", "details": [...] } }
Aby temu zapobiec, usługa próbuje ponownie wykonać wywołanie w coraz dłuższych odstępach czasu, aż się powiedzie. Jeśli regularnie wyczerpujesz limit, rozważ uwzględnienie większej liczby elementów w jednym żądaniu interfejsu API. W jednym wywołaniu interfejsu API możesz uwzględnić maksymalnie 1000 elementów.
Przykładowe fragmenty kodu
Poniżej znajdziesz kilka przykładów użycia interfejsu API do aktualizacji w czasie rzeczywistym w różnych językach. Te przykłady korzystają z bibliotek Google Auth do uwierzytelniania za pomocą pliku klucza konta usługi wygenerowanego podczas konfigurowania konta. Alternatywnych rozwiązań szukaj w artykule Używanie protokołu OAuth 2.0 w aplikacjach międzyserwerowych. Zastanów się nad użyciem schematu dostępnego w sekcji Generowanie bibliotek klienta, aby wygenerować kod źródłowy dla typów zasobów reklamowych i obiektów aktualizacji w czasie rzeczywistym.
Aktualizuję elementy
Node.js
Ten kod używa biblioteki Google do uwierzytelniania w 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
Ten kod korzysta z biblioteki uwierzytelniania Google dla Pythona.
"""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
Ten kod korzysta z biblioteki Google do uwierzytelniania w Javie.
Modele kodu źródłowego klienta w pakietach rtusamples.inventory
i rtusamples.realtime
zostały utworzone zgodnie z instrukcjami podanymi w sekcji Generowanie bibliotek klienta.
/* * 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; } }
Usuwanie elementów
Node.js
Ten kod używa biblioteki Google do uwierzytelniania w 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
Ten kod korzysta z biblioteki uwierzytelniania Google dla Pythona.
"""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
Ten kod korzysta z biblioteki Google do uwierzytelniania w Javie.
Modele kodu źródłowego klienta w pakietach rtusamples.inventory
i rtusamples.realtime
zostały utworzone zgodnie z instrukcjami podanymi w sekcji Generowanie bibliotek klienta.
/* * 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; } }
Przypadki użycia
Poniższe przypadki użycia to przykłady aktualizacji w czasie rzeczywistym, zbiorczych aktualizacji pliku danych oraz treści na wysokim poziomie w wywołaniu interfejsu API:
Scenariusz | Element do zaktualizowania | Opis i efekty |
---|---|---|
Wyłączanie usługi | Service |
musisz wyłączyć usługę z nieprzewidzianego powodu; Aktualizacje w czasie rzeczywistym: zaktualizuj odpowiedni obiekt Pełne pliki danych: przed następnym pobraniem przez Google pamiętaj, aby zaktualizować element z pełnych plików danych, aby wartość |
konkretny produkt jest niedostępny, | MenuItemOffer |
Aktualizacje w czasie rzeczywistym: wyślij opakowujący element MenuItemOffer z wartością inventoryLevel równą 0 dla danego elementu MenuItem , a wszystkie inne dane bez zmian. |
Zmiana ceny pozycji menu | MenuItemOffer |
Aktualizacje w czasie rzeczywistym: prześlij element MenuItemOffer zawierający element price z wartością price ustawioną na zaktualizowaną cenę dla danego MenuItem , a wszystkie inne dane bez zmian. |
Dodawanie nowej jednostki najwyższego poziomu Dotyczy tylko elementów typu |
Menu , Restaurant , Service |
Możesz na przykład dodać nowe menu do restauracji. Pełne pliki danych: dodaj element w plikach danych i poczekaj na przetworzenie zbiorczego. |
Trwałe usuwanie elementu najwyższego poziomu Dotyczy tylko elementów typu |
Menu , Restaurant , Service |
Aktualizacje w czasie rzeczywistym: wyślij wyraźne usunięcie. Pełne pliki danych: przed kolejnym pobraniem przez Google pamiętaj, aby usunąć element z pełnych plików danych. W przeciwnym razie zostanie on ponownie dodany. |
Dodawanie nowej strefy dostawy w określonym Service |
ServiceArea |
Pliki danych zbiorczych: prześlij odpowiednią jednostkę ServiceArea ze wszystkimi
polami, tak jak w pełnych plikach danych, z nową strefą dostawy
określoną w polu polygon , geoRadius lub postalCode . |
Zaktualizuj szacowany czas dostawy w Service |
ServiceHours |
Pliki danych zbiorczych: wyślij ServiceHours w taki sam sposób jak w plikach danych, z tą różnicą, że pole leadTimeMin zostanie odpowiednio zaktualizowane. |
Zaktualizuj ceny dostawy w Service |
Fee |
Pliki danych zbiorczych: wyślij pełny plik danych Fee z
price zaktualizowany. |
Zmień godziny dostawy lub odbioru na wynos w Service |
ServiceHours |
Pliki danych zbiorczych: wyślij ServiceHours w taki sam sposób jak w plikach danych, z tą różnicą, że właściwości opens i closes zostaną odpowiednio zaktualizowane. |
Service (zmiana minimalnej wartości zamówienia) |
Fee |
Pliki danych zbiorczych: wyślij pełny plik Fee z minPrice zaktualizowany |
Trwałe usuwanie MenuItem |
Menu |
Pliki danych zbiorczych: prześlij MenuItem tak samo jak w plikach danych, ale z pustym parentMenuSectionId .
|
Czas przetwarzania zadań zbiorczych i aktualizacji w czasie rzeczywistym
Element zaktualizowany lub usunięty za pomocą pliku danych zbiorczych zostanie przetworzony w ciągu 2 godzin, a element zaktualizowany za pomocą aktualizacji w czasie rzeczywistym – w ciągu 5 minut. Nieaktualny element jest usuwany po 14 dniach.
Możesz wysłać do Google:
- wiele zadań zbiorczych dziennie, aby aktualizować asortyment, lub
- Jedna partia w ciągu dnia i aktualizacje w czasie rzeczywistym, aby Twój asortyment był zawsze aktualny.