W tej sekcji opisujemy, jak przesyłać pilne aktualizacje plików danych do Google. Przy użyciu interfejsu Incremental Updates API możesz aktualizować i usuwać elementy źródeł treści w czasie zbliżonym do rzeczywistego.
Ta funkcja służy przede wszystkim do wprowadzania aktualizacji, których nie można przewidzieć. np. zamknięcia awaryjnego. Zazwyczaj każda zmiana przesłana za pomocą Przyrostowy interfejs API aktualizacji powinien zostać wprowadzony w ciągu maksymalnie tydzień. Jeśli zmiana nie musi zostać uwzględniona natychmiast, można skorzystać z aktualizację zbiorczą. Aktualizacje przyrostowe są przetwarzane w czasie nie dłuższym niż 5 razy min.
Konfiguracja
Aby wdrożyć aktualizacje przyrostowe, wykonaj te czynności:
- Wykonaj czynności opisane w artykule Tworzenie i konfigurowanie projektu, aby: utwórz projekt.
- Wykonaj czynności opisane w artykule Konfigurowanie konta usługi. aby utworzyć konto usługi. Pamiętaj, że musisz być „właścicielem”. z aby dodać „Edytora” rola na koncie usługi
- (Opcjonalne, ale zalecane) Zainstaluj bibliotekę klienta Google. w wybranym języku, aby umożliwić korzystanie z protokołu OAuth 2.0 przy wywoływaniu API. Wymienione poniżej przykładowe fragmenty kodu korzystają z tych bibliotek. W przeciwnym razie muszą ręcznie obsługiwać wymianę tokenów w sposób opisany w artykule Korzystanie z protokołu OAuth 2.0 na potrzeby dostępu do interfejsów API Google.
Punkt końcowy
Aby powiadomić Google o aktualizacji, wyślij żądanie HTTP POST do metody przyrostowej Update API obejmuje ładunek z aktualizacjami i dodatkami; Schemat zasobów reklamowych określa, do którego punktu końcowego ma być wysłane żądanie:
zasoby reklamowe (wersja 2)
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID:push
Zasoby reklamowe w wersji 1
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/ENTITY_ID:push
Aby usunąć encję, wyślij żądanie HTTP DELETE do poniższego punktu końcowego, które odpowiada używanemu schematowi asortymentu:
zasoby reklamowe (wersja 2)
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Zasoby reklamowe w wersji 1
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
W powyższych żądaniach zastąp następujące elementy:
- PROJECT_ID: identyfikator projektu Google Cloud powiązanego z Twoim projektem. utworzona w narzędziu Tworzenie i konfigurowanie projektu.
- TYPE (tylko schemat zasobów reklamowych w wersji 2): typ elementu (usługa
@type
). obiektu w pliku danych, który chcesz zaktualizować. - ENTITY_ID: identyfikator elementu zawartego w ładunku. Upewnij się, że: Zakoduj identyfikator jednostki w adresie URL.
- DELETE_TIME (usuń tylko punkt końcowy): opcjonalne pole do wskazywania
kiedy encja została usunięta z Twoich systemów (domyślnie jest to
odebrane). Wartość czasu nie może przypadać w przyszłości. Podczas wysyłania elementu
za pomocą wywołania przyrostowego obsługa wersji encji
korzysta również z pola
delete_time
w przypadku wywołania usuwania. Sformatuj jakoyyyy-mm-ddTHH:mm:ssZ
Załóżmy, że masz projekt o identyfikatorze „delivery-provider-id”. wykorzystujący funkcję do schematu zasobów reklamowych w wersji 2. Chcesz wprowadzić zmiany w restauracji ze typ elementu restauracji „MenuSection” i identyfikator jednostki „menuSection_122”. Punkt końcowy aktualizacji Twoich danych wyglądałby tak:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122:push
Aby usunąć tę samą encję, użyj wywołania interfejsu HTTP DELETE API:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122?entity.vertical=FOODORDERING
Żądania piaskownicy
W przypadku żądań w trybie piaskownicy postępuj zgodnie ze wskazówkami podanymi powyżej w sekcji Punkt końcowy, ale
wysyłać żądania do /v2/sandbox/apps/
zamiast do /v2/apps/
. Na przykład plik
Żądanie usunięcia w trybie piaskownicy dla schematu zasobów reklamowych w wersji 2 ma taką strukturę:
https://actions.googleapis.com/v2/sandbox/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Aktualizacje i dodatki
Codzienne pliki danych powinny zawierać również zmiany przesłane za pomocą tego API. W przeciwnym razie aktualizacje zbiorcze zastąpią zmiany przyrostowe.
Ładunek
Każde żądanie POST musi zawierać parametry żądania wraz z protokołem JSON ładunek zawierający uporządkowane dane dowolnego typu encji wymienionego w schematu zasobów reklamowych.
Plik JSON powinien wyglądać tak samo, jak w pliku danych wsadowym, z następującym parametrem następujące różnice:
- Rozmiar ładunku nie powinien przekraczać 5 MB. Podobnie jak w przypadku wsadu plików danych, zalecamy usunięcie odstępów, aby zebrać więcej danych.
- Koperta wygląda tak:
{ "entity": { "data":"ENTITY_DATA", "vertical":"FOODORDERING" }, "update_time":"UPDATE_TIMESTAMP" }
W powyższym ładunku zastąp następujące elementy:
- ENTITY_DATA: encja w formacie JSON zserializowany jako ciąg znaków.
Encja JSON-LD musi być przekazywana jako ciąg znaków w polu
data
. - UPDATE_TIMESTAMP (opcjonalnie): sygnatura czasowa aktualizacji elementu
systemów uczących się. Wartość czasu nie może przypadać w przyszłości. Domyślna sygnatura czasowa to czas,
Google otrzymuje żądanie. Wysyłanie elementu za pomocą przyrostowego
obsługa wersji encji używa też funkcji
update_time
w przypadku prośby o dodanie/aktualizację.
Aktualizowanie encji
Przykład 1. Aktualizowanie informacji o restauracji
Załóżmy, że chcesz pilnie zaktualizować numer telefonu do restauracji. Twoje update zawiera kod JSON dla całej restauracji.
Weźmy na przykład wsadowy plik danych, który wygląda tak:
{ "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501234567", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 }
Następnie aktualizacja przyrostowa przeprowadzana za pomocą metody HTTP POST będzie wyglądać tak:
POST v2/apps/provider-project/entities/Restaurant/restaurant12345:push Host: actions.googleapis.com Content-Type: application/ld+json { "entity": { "data": { "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501235555", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 }, "vertical": "FOODORDERING" } }
Przykład 2. Aktualizowanie ceny pozycji menu
Przyjmijmy, że musisz zmienić cenę pozycji w menu. Tak jak w przykładzie 1. update musi zawierać kod JSON dla całego elementu najwyższego poziomu (menu) oraz plik danych używa schematu zasobów reklamowych w wersji 1.
Weźmy na przykład wsadowy plik danych, który wygląda tak:
{ "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 3.00, "priceCurrency": "USD" }
Następnie aktualizacja przyrostowa za pomocą metody POST będzie wyglądać tak:
POST v2/apps/provider-project/entities/MenuItemOffer/menuitemoffer6680262:push Host: actions.googleapis.com Content-Type: application/ld+json { "entity": { "data": { "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 1.00, "priceCurrency": "USD" }, "vertical": "FOODORDERING" } }
Dodawanie encji
Aby dodawać elementy, unikaj aktualizacji zasobów reklamowych. Zamiast tego użyj plików zbiorczych zgodnie ze schematem zasobów reklamowych v2.
Usuwanie elementu
Aby usunąć elementy najwyższego poziomu, użyj nieznacznie zmodyfikowanego punktu końcowego, i użyj w żądaniu HTTP DELETE zamiast HTTP POST.
Nie używaj funkcji HTTP DELETE do usuwania elementu podrzędnego w elemencie najwyższego poziomu, takiego jak pozycji menu. Zamiast tego potraktuj usunięcie podelementów jako na element najwyższego poziomu, w którym element podrzędny jest usunięty z odpowiednią listę lub parametr.
Przykład 1. Usuwanie elementu najwyższego poziomu
Załóżmy, że chcesz usunąć restaurację z pliku danych, w którym użyto do schematu zasobów reklamowych w wersji 1. Musisz też usunąć jego usługi i menu.
Przykładowy punkt końcowy elementu menu o identyfikatorze "https://www.provider.com/restaurant/menu/nr":
DELETE v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fmenu%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Przykładowy punkt końcowy dla podmiotu restauracji o identyfikatorze "https://www.provider.com/restaurant/nr":
DELETE v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Przykładowy punkt końcowy dla encji usługi o identyfikatorze "https://www.provider.com/restaurant/service/nr":
DELETE v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fservice%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
}
Przykład 2: Usuwanie podelementów
Aby usunąć element podrzędny z elementu nadrzędnego, należy wysłać encja z elementem podrzędnym usuniętym z odpowiedniego pola. Poniżej W tym przykładzie zakładamy, że plik danych używa schematu zasobów reklamowych w wersji 1.
Aby na przykład usunąć obsługiwany obszar, podaj w niej obsługiwany obszar
usunięto z listy areaServed
.
POST v2/apps/delivery-provider-id/entities/https%3A%2F%2Fwww.provider.com%2Frestaurant%2Fservice%2Fnr:push
Host: actions.googleapis.com
Content-Type: application/ld+json
{
"entity": {
// Note: "data" is not serialized as a string in our example for readability.
"data": {
"@type": "Service",
"provider": {
"@type": "Restaurant",
"@id": "https://www.provider.com/restaurant/nr"
},
"areaServed": [
{
"@type": "GeoCircle",
"geoMidpoint": {
"@type": "GeoCoordinates",
"latitude": "42.362757",
"longitude": "-71.087109"
},
"geoRadius": "10000"
}
// area2 is removed.
]
...
},
"vertical": "FOODORDERING"
}
}
Kody odpowiedzi interfejsu API
Udane wywołanie nie oznacza, że plik danych jest prawidłowy, a jedynie, że Wykonano wywołanie interfejsu API. Udane wywołania otrzymują kod odpowiedzi HTTP 200 wraz z z pustą treścią odpowiedzi:
{}
W przypadku błędów kod odpowiedzi HTTP nie będzie miał wartości 200, a jej treść wskazuje, co poszło nie tak.
Jeśli na przykład użytkownik wybrał „branżę” w kopercie do
FAKE_VERTICAL
otrzymasz następującą wiadomość:
{
"error": {
"code": 400,
"message": "Invalid value at 'entity.vertical' (TYPE_ENUM), \"FAKE_VERTICAL\"",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "entity.vertical",
"description": "Invalid value at 'entity.vertical' (TYPE_ENUM), \"FAKE_VERTICAL\""
}
]
}
]
}
}
Przykładowy kod
Poniżej znajduje się kilka przykładów użycia interfejsu API aktualizacji przyrostowych w różnych języki. Te przykłady korzystają z bibliotek uwierzytelniania Google i zakładają, że plik danych używa parametru do schematu zasobów reklamowych w wersji 1. Rozwiązania alternatywne znajdziesz tutaj: Używanie protokołu OAuth 2.0 w aplikacjach międzyserwerowych.
Aktualizuję elementy
Node.js
Ten kod korzysta z biblioteki uwierzytelniania Google dla Node.js.
const {auth} = require('google-auth-library') const request = require('request'); // The service account client secret file downloaded from the Google Cloud Console const serviceAccountJson = require('./service-account.json') // entity.json is a file that contains the entity data in json format const entity = require('./entity.json') const ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' const PROJECT_ID = 'your-project-id' /** * Get the authorization token using a service account. */ async function getAuthToken() { let client = auth.fromJSON(serviceAccountJson) client.scopes = ['https://www.googleapis.com/auth/assistant'] const tokens = await client.authorize() return tokens.access_token; } /** * Send an incremental update to update or add an entity */ async function updateEntity(entityId, entity) { const token = await getAuthToken() request.post({ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, url: `https://actions.googleapis.com/v2/apps/${PROJECT_ID}/entities/${encodeURIComponent(entityId)}:push`, body: { entity: { data: JSON.stringify(entity), vertical: 'FOODORDERING', } }, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) } updateEntity(ENTITY_ID, entity)
Python
Ten kod korzysta z biblioteki uwierzytelniania Google dla Pythona.
from google.oauth2 import service_account from google.auth.transport.requests import AuthorizedSession import json import urllib PROJECT_ID = 'your-project-id' ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' ENDPOINT = 'https://actions.googleapis.com/v2/apps/%s/entities/%s:push' % ( PROJECT_ID, urllib.quote(ENTITY_ID, '')) # service-account.json is the service account client secret file downloaded from the # Google Cloud Console credentials = service_account.Credentials.from_service_account_file( 'service-account.json') scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/assistant']) authed_session = AuthorizedSession(scoped_credentials) # Retrieving the entity update_file = open("entity.json") #JSON file containing entity data in json format. data = update_file.read() # Populating the entity with wrapper entity = {} entity['data'] = data #entity JSON-LD serialized as string entity['vertical'] = 'FOODORDERING' request = {} request['entity'] = entity response = authed_session.post(ENDPOINT, json=request) print(response.text) #if successful, will be '{}'
Java
Ten kod korzysta z biblioteki uwierzytelniania Google dla języka Java.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "http://www.provider.com/somerestaurant"; /** * Get the authorization token using a service account. */ private static String getAuthToken() { InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json"); ServiceAccountCredentials.Builder credentialsSimpleBuilder = ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder(); credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/assistant")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an incremental update to update or add an entity. * @param entityId The id of the entity to update. * @param entity the json of the entity to be updated. */ public void updateEntity(String entityId, JSONObject entity) { String authToken = getAuthToken(); String endpoint = String.format( "https://actions.googleapis.com/v2/apps/%s/entities/%s:push", PROJECT_ID, URLEncoder.encode(entityId, "UTF-8")); JSONObject data = new JSONObject(); data.put("data", entity.toString()); data.put("vertical", "FOODORDERING"); JSONObject jsonBody = new JSONObject(); jsonBody.put("entity", data); // Execute POST request executePostRequest(endpoint, authToken, jsonBody); }
Usuwam elementy
Node.js
Ten kod korzysta z biblioteki uwierzytelniania Google dla Node.js.
const {auth} = require('google-auth-library') const request = require('request'); // The service account client secret file downloaded from the Google Cloud Console const serviceAccountJson = require('./service-account.json') // entity.json is a file that contains the entity data in json format const entity = require('./entity.json') const ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' const PROJECT_ID = 'your-project-id' /** * Get the authorization token using a service account. */ async function getAuthToken() { let client = auth.fromJSON(serviceAccountJson) client.scopes = ['https://www.googleapis.com/auth/assistant'] const tokens = await client.authorize() return tokens.access_token; } /** * Send an incremental update to delete an entity */ async function deleteEntity(entityId) { const token = await getAuthToken() request.delete({ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, url: `https://actions.googleapis.com/v2/apps/${PROJECT_ID}/entities/${encodeURIComponent(entityId)}?entity.vertical=FOODORDERING`, body: {}, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) } deleteEntity(ENTITY_ID)
Python
Ten kod korzysta z biblioteki uwierzytelniania Google dla Pythona.
from google.oauth2 import service_account from google.auth.transport.requests import AuthorizedSession import json import urllib # Service config PROJECT_ID = 'your-project-id' ENTITY_ID = 'restaurant/http://www.provider.com/somerestaurant' DELETE_TIME = '2018-04-07T14:30:00-07:00' ENDPOINT = 'https://actions.googleapis.com/v2/apps/%s/entities/%s?entity.vertical=FOODORDERING&delete_time=%s' % ( PROJECT_ID, urllib.quote(ENTITY_ID, ''), urllib.quote(DELETE_TIME, '')) # service-account.json is the service account client secret file downloaded from the # Google Cloud Console credentials = service_account.Credentials.from_service_account_file( 'service-account.json') scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/assistant']) authed_session = AuthorizedSession(scoped_credentials) response = authed_session.delete(ENDPOINT) print(response.text) #if successful, will be '{}'
Java
Ten kod korzysta z biblioteki uwierzytelniania Google dla języka Java.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "restaurant/http://www.provider.com/somerestaurant"; /** * Get the authorization token using a service account. */ private static String getAuthToken() { InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json"); ServiceAccountCredentials.Builder credentialsSimpleBuilder = ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder(); credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/assistant")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an incremental update to delete an entity. * @param entityId The id of the entity to delete. */ public void deleteEntity(String entityId) { String authToken = getAuthToken(); String endpoint = String.format( "https://actions.googleapis.com/v2/apps/%s/entities/%s?entity.vertical=FOODORDERING", PROJECT_ID, URLEncoder.encode(entityId, "UTF-8")); // Execute DELETE request System.out.println(executeDeleteRequest(endpoint, authToken)); }
Przypadki użycia
Poniższe przypadki użycia to przykłady aktualizacji przyrostowych, pełnych aktualizacji plików danych a treścią ogólną w wywołaniu interfejsu API:
Scenariusz | Element najwyższego poziomu | Opis i efekty |
---|---|---|
Wyłączanie usługi | DisabledService |
Musisz wyłączyć usługę z nieprzewidzianego powodu. Aktualizacje przyrostowe: wyślij element Pełne pliki danych: pamiętaj, aby zaktualizować element z pełnych kanałów.
aby |
Brak produktu w magazynie | Menu |
Aktualizacje przyrostowe: wyślij Menu dołączający do wiadomości.
encja z wartością offer.inventoryLevel ustawioną na 0 dla danej wartości
MenuItem i wszystkie inne dane bez zmian. |
Zmiana ceny pozycji menu | Menu |
Aktualizacje przyrostowe: wyślij Menu dołączający do wiadomości.
element z wartością offer.price ustawioną na zaktualizowaną cenę danego
MenuItem i wszystkie inne dane bez zmian. |
Dodaj nowy element najwyższego poziomu Dotyczy tylko elementu typu |
Menu , Restaurant , Service |
Możesz na przykład dodać nowe menu do restauracji. Aktualizacje przyrostowe: wyślij nową pozycję menu wraz z restauracją.
element z polem |
Trwale usuń element najwyższego poziomu Dotyczy tylko elementu typu |
Menu , Restaurant , Service |
Aktualizacje przyrostowe: wyślij wiadomość usuwać. Pełne pliki danych: pamiętaj, aby usunąć element z pełnych kanałów przed podczas następnego pobierania przez Google. W przeciwnym razie element zostanie ponownie dodany. |
Dodaj nowy obszar dostawy w określonym regionie Service |
Service |
Dodatkowe pliki danych: wyślij element Service , którego dotyczy problem, wraz ze wszystkimi jego
tak jak zwykle w pełnych plikach danych, a także nowy obszar dostawy.
określona w areaServed w argumencie Service . |
Zaktualizuj szacowany czas dostawy za Service |
Service |
Dodatkowe pliki danych: wyślij Service tak samo jak w
pliki danych z wyjątkiem aktualizacji hoursAvailable.deliveryHours
odpowiednio się zmienia. |
Zaktualizuj ceny dostawy w: Service |
Service |
Dodatkowe pliki danych: wyślij pełne Service za pomocą
Zaktualizowano: offers.priceSpecification.price . |
Zaktualizuj godziny dostawy lub na wynos w: Service |
Service |
Dodatkowe pliki danych: wyślij Service tak samo jak w
pliki danych z wyjątkiem aktualizacji hoursAvailable
odpowiednio się zmienia. |
Service (zmień minimalną kwotę zamówienia) |
Service |
Dodatkowe pliki danych: wyślij pełne Service za pomocą
Service.offers.priceSpecification.eligibleTransactionVolume
zaktualizowano |
Usuń trwale MenuItem |
Menu |
Dodatkowe pliki danych: wyślij Menu takie same jak w pliku
, ale po usunięciu tego pliku MenuItem z
Lista hasMenuItems . |
Docelowy czas przetwarzania w przypadku zadań wsadowych i aktualizacji przyrostowych
Encja dodana za pomocą aktualizacji zbiorczej lub przyrostowej zostanie przetworzona w 1–2 dni. Encja zaktualizowana lub usunięta poprzez wsad zostanie przetworzona w 2 sekundach. godzin, podczas gdy jednostka zaktualizowana za pomocą przyrostowej aktualizacji jest przetwarzana w 5 minut. Nieaktualny element jest usuwany po 7 dniach.
Możesz wysłać do Google:
- Kilka zadań zbiorczych dziennie, aby aktualizować asortyment, LUB
- Jedno zadanie wsadowe dziennie i przyrostowe interfejsy API zapewniają aktualność zasobów reklamowych.