Z tej sekcji dowiesz się, jak wysyłać do Google aktualne informacje o zasobach reklamowych. Interfejs przyrostowy interfejsu API umożliwia aktualizowanie zasobów i usuwanie ich z zasobów piaskownicy lub środowiska produkcyjnego w czasie rzeczywistym.
Ta funkcja jest przeznaczona głównie do aktualizacji, których nie można przewidzieć, takich jak zamknięcie awaryjne. Każda zmiana przesłana za pomocą interfejsu przyrostowego interfejsu API powinna zostać wprowadzona w ciągu godziny. Jeśli zmiana nie musi zostać od razu odzwierciedlona, możesz skorzystać z przetwarzania zbiorczego. Aktualizacje przyrostowe są przetwarzane w ciągu maksymalnie 5 minut.
Wymagania wstępne
Zanim wdrożysz aktualizacje przyrostowe, wymagane są te elementy:
- Zostanie utworzone konto usługi z rolą edytora do projektu Actions. Więcej informacji znajdziesz w artykule Tworzenie i konfigurowanie projektu.
- Pliki danych środowiska produkcyjnego i piaskownicy są przechowywane i przetwarzane. Więcej informacji znajdziesz w artykule Przetwarzanie zbiorcze.
- (Opcjonalnie, ale zalecane) Zainstaluj bibliotekę klienta Google w wybranym języku, aby ułatwić korzystanie z protokołu OAuth 2.0 podczas wywoływania interfejsu API. W podanych niżej przykładach kodu wykorzystywane są te biblioteki. W przeciwnym razie musisz ręcznie obsługiwać wymiany tokenów zgodnie z opisem w artykule Korzystanie z OAuth 2.0 do dostępu do interfejsów API Google.
Punkty końcowe
Zastąp te żądania:
- PROJECT_ID: identyfikator projektu Google Cloud powiązanego z projektem utworzonym w artykule Tworzenie i konfigurowanie projektu.
- TYPE: typ encji (właściwość
@type
) obiektu w pliku danych, który chcesz zaktualizować. - ENTITY_ID (tylko usunięcie punktu końcowego): identyfikator elementu do usunięcia. Pamiętaj, aby zakodować identyfikator jednostki w adresie URL.
- DELETE_TIME (tylko usunięcie punktu końcowego): pole opcjonalne wskazujące, kiedy element został usunięty w systemach (domyślnie jest to miejsce, w którym zostało odebrane żądanie). Wartość czasu nie może być w przyszłości. Gdy wysyłasz encję za pomocą wywołania przyrostowego, obsługi wersji elementu używa też pola
delete_time
w przypadku wywołania usunięcia. Sformatuj tę wartość jakoyyyy-mm-ddTHH:mm:ssZ
Zaktualizowanie punktu końcowego
Aby zmodyfikować jednostkę, wyślij żądanie HTTP POST do poniższego punktu końcowego i dodaj ładunek aktualizacji i dodatków. W jednym wywołaniu interfejsu API możesz zaktualizować maksymalnie 1000 jednostek.
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities:batchPush
Jeśli na przykład chcesz zaktualizować encje w projekcie o identyfikatorze "delivery-provider-id" punkt końcowy będzie wyglądać tak:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities:batchpush
Usuń punkt końcowy
Aby usunąć element z zasobów reklamowych, wyślij żądanie HTTP DELETE do poniższego punktu końcowego.
https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Aby na przykład usunąć element "MenuSection" z identyfikatorem "menuSection_122" z projektu "delivery-provider-id", należy utworzyć wywołanie API HTTP DELETE:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122?entity.vertical=FOODORDERING
Środowisko piaskownicy
Aby używać przyrostowego interfejsu API aktualizacji w zasobach reklamowych w piaskownicy, postępuj zgodnie ze wskazówkami w sekcji Punkty końcowe powyżej, ale wysyłaj żądania do /v2/sandbox/apps/
zamiast do /v2/apps/
.
https://actions.googleapis.com/v2/sandbox/apps/PROJECT_ID/entities:batchPush
https://actions.googleapis.com/v2/sandbox/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME
Aktualizowanie encji
Każde żądanie POST musi zawierać parametry żądania w ładunku JSON zawierającym uporządkowane dane dowolnego typu encji wymienionego w schemacie asortymentu.
Zaktualizuj ładunek
Plik JSON powinien wyglądać tak samo jak w pliku danych zbiorczych, z tymi różnicami:
- Rozmiar ładunku nie powinien przekraczać 5 MB. Podobnie jak w przypadku kanałów wsadowych, zalecamy usunięcie spacji, aby dopasować więcej danych.
- Koperta jest taka:
{ "requests": [ { "entity": { "data":"ENTITY_DATA", "name": "apps/project_id>/entities/type/entity_id" }, "update_time":"UPDATE_TIMESTAMP" }, ], "vertical": "FOODORDERING" }
W powyższym ładunku zastąp te elementy:
- ENTITY_DATA: element 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 w Twoich systemach. Wartość czasu nie może być w przyszłości. Domyślna sygnatura czasowa oznacza moment, w którym Google otrzymuje żądanie. Gdy wysyłasz encję za pomocą żądania przyrostowego, obsługa wersji obejmuje też pole
update_time
w przypadku żądania dodania/aktualizacji.
Przykłady
Przykład 1. Aktualizowanie restauracji
Załóżmy, że musisz pilnie zaktualizować numer telefonu restauracji. Aktualizacja zawiera kod JSON całej restauracji.
Rozważ użycie zbiorczego pliku danych podobnego do tego:
{ "@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 przyrostowa aktualizacja POST w protokole HTTP będzie wyglądać tak:
POST v2/sandbox/apps/provider-project/entities:batchPush Host: actions.googleapis.com Content-Type: application/ld+json { "requests": [ { "entity": { "name": "apps/provider-project/entities/restaurant/restaurant12345", "data": { "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501235555", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 } } } "vertical": "FOODORDERING" }
Przykład 2. Aktualizowanie wielu restauracji
Aby zaktualizować 2 elementy restauracji w 1 wywołaniu interfejsu API, żądanie HTTP POST będzie wyglądać tak:
POST v2/sandbox/apps/provider-project/entities:batchPush Host: actions.googleapis.com Content-Type: application/ld+json { "requests": [ { "entity": { "name": "apps/provider-project/entities/restaurant/restaurant12345", "data": { "@type": "Restaurant", "@id": "restaurant12345", "name": "Some Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501235555", "streetAddress": "345 Spear St", "addressLocality": "San Francisco", "addressRegion": "CA", "postalCode": "94105", "addressCountry": "US", "latitude": 37.472842, "longitude": -122.217144 } } }, { "entity": { "name": "apps/provider-project/entities/restaurant/restaurant123", "data": { "@type": "Restaurant", "@id": "restaurant123", "name": "Some Other Restaurant", "url": "https://www.provider.com/somerestaurant", "telephone": "+16501231235", "streetAddress": "385 Spear St", "addressLocality": "San Mateo", "addressRegion": "CA", "postalCode": "94115", "addressCountry": "US" } } } ] "vertical": "FOODORDERING" }
Przykład 3. Aktualizacja ceny elementu menu
Załóżmy, że chcesz zmienić cenę pozycji menu. Tak jak w przykładzie 1, aktualizacja musi zawierać kod JSON dla całego elementu najwyższego poziomu (menu), a plik danych używa schematu zasobów reklamowych w wersji 1.
Rozważ użycie zbiorczego pliku danych podobnego do tego:
{ "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 3.00, "priceCurrency": "USD" }
Wtedy przyrostowa aktualizacja za pomocą metody POST będzie wyglądać tak:
POST v2/sandbox/apps/provider-project/entities:batchPush Host: actions.googleapis.com Content-Type: application/ld+json { "requests": [ { "entity": { "name": "apps/provider-project/entities/menuitemoffer/menuitemoffer6680262", "data": { "@type": "MenuItemOffer", "@id": "menuitemoffer6680262", "sku": "offer-cola", "menuItemId": "menuitem896532", "price": 1.00, "priceCurrency": "USD" }, "vertical": "FOODORDERING" } } ] "vertical": "FOODORDERING" }
Dodawanie encji
Aby dodać elementy, nie używaj aktualizacji zasobów. Zamiast tego użyj procesu zbiorczego pliku danych w sposób opisany w schemacie zasobów reklamowych v2.
Usuwanie encji
Aby usunąć encje najwyższego poziomu, użyj lekko zmodyfikowanego punktu końcowego i użyj w żądaniu żądania HTTP DELETE zamiast HTTP POST.
Usuwanie elementu najwyższego poziomu
Weź pod uwagę sytuację, w której chcesz usunąć restaurację. Musisz też usunąć związane z nim usługi i menu.
Przykładowy punkt końcowy elementu menu o identyfikatorze "provider/restauracja/menu/nr":
DELETE v2/apps/delivery-provider-id/entities/menu/provider%2Frestaurant%2Fmenu%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Przykładowy punkt końcowy dla elementu restauracji o identyfikatorze&https://www.provider.com/restauracja/nr":
DELETE v2/apps/delivery-provider-id/entities/restaurant/provider%2Frestaurant%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
Przykładowy punkt końcowy dla usługi o identyfikatorze ID:
DELETE v2/apps/delivery-provider-id/entities/service/provider%2Frestaurant%2Fservice%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
}
Usuwanie podmiotów
Nie używaj protokołu HTTP DELETE do usunięcia elementu podrzędnego w jednostce najwyższego poziomu, np. do elementu menu. Zamiast tego potraktuj usunięcie encji jako aktualizację encji najwyższego poziomu, z której została ona usunięta z odpowiedniej listy lub odwołania.
Kody odpowiedzi interfejsu API
Udane wywołanie nie oznacza, że plik danych jest prawidłowy lub prawidłowy, tylko że zostało wykonane wywołanie interfejsu API. Udane połączenia otrzymują kod odpowiedzi HTTP 200 oraz pusty tekst odpowiedzi:
{}
W przypadku awarii kod odpowiedzi HTTP nie będzie wynosił 200, a treść odpowiedzi będzie wskazywać błąd.
Jeśli na przykład użytkownik ustawił wartość "vertical" w danych koperty na FAKE_VERTICAL
, otrzymasz ten komunikat:
{
"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 znajdziesz kilka przykładów użycia interfejsu Incremental Update API w różnych językach. W tych przykładach używane są biblioteki uwierzytelniania Google i przyjmowane są pliki danych za pomocą schematu zasobów reklamowych v1. Informacje o alternatywnych rozwiązaniach znajdziesz w artykule Korzystanie z OAuth 2.0 dla aplikacji serwer-serwer.
Aktualizowanie encji
Node.js
Ten kod używa biblioteki uwierzytelniania Google na potrzeby środowiska Node.js.
const {auth} = require('google-auth-library') const request = require('request'); // The service account client secret file downloaded from the Google Cloud Console const serviceAccountJson = require('./service-account.json') // entity.json is a file that contains the entity data in json format const entity = require('./entity.json') const ENTITY_ID = 'your/entity/id' const PROJECT_ID = 'type/your-project-id' /** * Get the authorization token using a service account. */ async function getAuthToken() { let client = auth.fromJSON(serviceAccountJson) client.scopes = ['https://www.googleapis.com/auth/assistant'] const tokens = await client.authorize() return tokens.access_token; } /** * Send an incremental update to update or add an entity */ async function updateEntity(entity) { const token = await getAuthToken() request.post({ headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, url: `https://actions.googleapis.com/v2/apps/${PROJECT_ID}/entities:batchPush`, body: { requests: [ { entity: { data: JSON.stringify(entity) name: `apps/${PROJECT_ID}/entities/${ENTITY_ID}` } } ], vertical: 'FOODORDERING' }, json: true }, (err, res, body) => { if (err) { return console.log(err); } console.log(`Response: ${JSON.stringify(res)}`) }) } updateEntity(entity)
Python
Ten kod używa biblioteki uwierzytelniania Google na potrzeby 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 = 'type/your/entity/id' ENDPOINT = 'https://actions.googleapis.com/v2/apps/%s/entities:batchPush' % ( PROJECT_ID) # service-account.json is the service account client secret file downloaded from the # Google Cloud Console credentials = service_account.Credentials.from_service_account_file( 'service-account.json') scoped_credentials = credentials.with_scopes( ['https://www.googleapis.com/auth/assistant']) authed_session = AuthorizedSession(scoped_credentials) # Retrieving the entity update_file = open("entity.json") #JSON file containing entity data in json format. data = update_file.read() entity = {} entity['data'] = data #entity JSON-LD serialized as string entity['name'] = 'apps/%s/entities/%s' % (PROJECT_ID, urllib.quote(ENTITY_ID, '') ) # Populating the request request = {} request['entity'] = entity requestArray = [request] # Populating the payload payload = {} payload['requests'] = requestArray payload['vertical'] = 'FOODORDERING' response = authed_session.post(ENDPOINT, json=payload) print(response.text) #if successful, will be '{}'
Java
Ten kod używa biblioteki uwierzytelniania Google na potrzeby Javy.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "type/your-entity-id"; /** * Get the authorization token using a service account. */ private static String getAuthToken() { InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json"); ServiceAccountCredentials.Builder credentialsSimpleBuilder = ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder(); credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/assistant")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an incremental update to update or add an entity. * @param entityId The id of the entity to update. * @param entity the json of the entity to be updated. */ public void updateEntity(String entityId, JSONObject data) { String authToken = getAuthToken(); String endpoint = String.format("https://actions.googleapis.com/v2/apps/%s/entities/:batchPush", PROJECT_ID); JSONObject entity = new JSONObject(); entity.put("data", data.toString()); entity.put("name", String.format("apps/%s/entities/%s", PROJECT_ID, URLEncoder.encode(ENTITY_ID, "UTF-8"))); JSONObject request = new JSONObject(); request.put("entity", entity); JSONArray requestArray = new JSONArray(); requestArray.put(request); JSONObject payload = new JSONObject(); payload.put("requests", requestArray); payload.put("vertical", FOODORDERING); // Execute POST request executePostRequest(endpoint, authToken, payload); }
Usuwanie encji
Node.js
Ten kod używa biblioteki uwierzytelniania Google na potrzeby środowiska 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 używa biblioteki uwierzytelniania Google na potrzeby 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 używa biblioteki uwierzytelniania Google na potrzeby Javy.
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
Wybrane przykłady zastosowania aktualizacji przyrostowych, pełnych aktualizacji pliku danych i wysokiej zawartości treści w wywołaniu interfejsu API:
Scenariusz | Element do zaktualizowania | Opis i efekty |
---|---|---|
Wyłączanie usługi | Service |
Usługę należy wyłączyć z nieprzewidzianych powodów. Aktualizacje przyrostowe: zaktualizuj odpowiedni element Pełne kanały: pamiętaj, aby zaktualizować element z pełnych kanałów, tak aby |
Ten produkt jest niedostępny | MenuItemOffer |
Aktualizacje przyrostowe: w przypadku danego elementu MenuItem ustaw o wartości inventoryLevel wartość , a pozostałe dane bez zmian. |
Zmiana ceny elementu menu | MenuItemOffer |
Aktualizacje przyrostowe: w przypadku elementu MenuItem z price ustaw nową cenę dla danego elementu MenuItem i wszystkie pozostałe dane bez zmian. |
Dodaj nowy element najwyższego poziomu Dotyczy tylko typów |
Menu , Restaurant , Service |
Możesz na przykład dodać nowe menu do restauracji. Pełne kanały: dodaj encję w plikach danych i poczekaj na przetworzenie zbiorcze. |
Trwale usuń element najwyższego poziomu Dotyczy tylko typów |
Menu , Restaurant , Service |
Aktualizacje dodatkowe: wyślij wyraźne usunięcie. Pełne kanały: usuń element z pełnych kanałów przed następnym pobraniem przez Google elementu. W przeciwnym razie element zostanie ponownie dodany. |
Dodaj nowy obszar dostawy w określonym Service |
ServiceArea |
przyrostowe pliki danych: prześlij dany element ServiceArea ze wszystkimi polami w oryginalnej formie, tak jak w przypadku pełnych plików danych, z nowym obszarem wyświetlania określonym w tagach polygon , geoRadius lub postalCode ; |
Zaktualizuj szacowany czas dostawy w: Service |
ServiceHours |
Dodatkowe pliki danych: wyślij ServiceHours tak samo jak w plikach danych, chyba że jego leadTimeMin jest odpowiednio zaktualizowany. |
Zaktualizuj ceny dostawy w: Service |
Fee |
Dodatkowe pliki danych: wyślij pełną dostawę Fee z zaktualizowanym price . |
Zaktualizuj godziny dostawy lub na wynos w: Service |
ServiceHours |
Dodatkowe kanały: wyślij wartość ServiceHours tak samo jak w plikach danych, ale właściwości opens i closes są odpowiednio zaktualizowane. |
Service (zmień minimalną kwotę zamówienia) |
Fee |
przyrostowe pliki danych: wyślij pełne dane typu Fee z aktualizacją minPrice . |
Trwałe usunięcie elementu MenuItem |
Menu |
Dodatkowe pliki danych: wyślij MenuItem tak samo jak w plikach danych, ale z pustym polem parentMenuSectionId .
|
Docelowy poziom czasu przetwarzania zadań wsadowych i przyrostowych aktualizacji
Encja zaktualizowana lub usunięta wsadem zostanie przetworzona w ciągu 2 godzin w trybie „najlepszym wysiłkiem”, a encja zaktualizowana za pomocą aktualizacji przyrostowej rozpocznie się w ciągu 5 minut. Nieaktualny element jest usuwany za 7 dni.
Możesz wysłać Google:
- Mieć wiele zadań wsadowych dziennie, aby zasoby były aktualne LUB
- Jedno zadanie wsadowe dziennie i przyrostowe interfejsy API, aby aktualizować zasoby reklamowe.