W tej sekcji opisujemy, jak wysyłać pilne aktualizacje zasobów reklamowych podmiotom Google. Interfejs Incremental Update API umożliwia przekazywanie aktualizacji i usuwanie tych zasobach w zasobach piaskownicy lub produkcyjnych 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 w ciągu godziny. Jeśli zmiana nie musi zostać uwzględniona natychmiast, można skorzystać z za pomocą pozyskiwania zbiorczego. Aktualizacje przyrostowe są przetwarzane nie dłużej niż 5 minut.
Wymagania wstępne
Przed wdrożeniem aktualizacji przyrostowych wymagane są następujące elementy:
- Zostanie utworzone konto usługi z przypisaną rolą edytującego projekt Actions. Więcej informacji można znaleźć w sekcji Utwórz i skonfiguruj projekt.
- Pliki danych produkcyjnych lub piaskownicy są hostowane i przetwarzane. Więcej informacji można znaleźć w sekcji Pozyskiwanie zbiorcze.
- (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.
Punkty końcowe
W poniż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: typ elementu (usługa
@type
) obiektu w pliku danych, który chcesz zaktualizować. - ENTITY_ID (usuń tylko punkt końcowy): identyfikator encji do usunięcia. 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
Zaktualizowanie punktu końcowego
Aby zmodyfikować encję, wyślij żądanie HTTP POST do poniższego punktu końcowego i obejmują aktualizacje i dodatki. W jednym wywołaniu interfejsu API możesz zaktualizować maksymalnie 1000 elementów.
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ąć encję 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 np. usunąć sekcję „MenuSection” element o identyfikatorze „menuSection_122” z pola „delivery-provider-id” w projekcie, należy wywołać interfejs HTTP DELETE API, aby:
https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122?entity.vertical=FOODORDERING
Środowisko piaskownicy
Aby korzystać z interfejsu API aktualizacji przyrostowej w zasobach reklamowych piaskownicy, postępuj zgodnie ze wskazówkami w powyższej sekcji Punkty końcowe, ale
wysyłać żą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
Aktualizuję elementy
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.
Zaktualizuj ładunek
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:
{ "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 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ę.
Przykłady
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/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 pojedynczym wywołaniu interfejsu API, żądanie HTTP POST 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. Aktualizowanie ceny pozycji menu
Przyjmijmy, że musisz zmienić cenę pozycji 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/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 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.
Usuwanie elementu najwyższego poziomu
Załóżmy, że chcesz usunąć restaurację z pliku danych. Musisz jej usługi i menu.
Przykładowy punkt końcowy elementu menu o identyfikatorze "provider/restaurant/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 podmiotu restauracji o identyfikatorze "https://www.provider.com/restaurant/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 encji usługi o identyfikatorze "https://www.provider.com/restaurant/service/nr":
DELETE v2/apps/delivery-provider-id/entities/service/provider%2Frestaurant%2Fservice%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com
}
Usuwanie podelementów
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 lub reverseReference.
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 korzystania z interfejsu Incremental Update API 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 = '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 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 = '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 korzysta z biblioteki uwierzytelniania Google dla języka Java.
private static final String PROJECT_ID = "your-project-id"; private static final String ENTITY_ID = "type/your-entity-id"; /** * Get the authorization token using a service account. */ private static String getAuthToken() { InputStream serviceAccountFile = Example.class.getClassLoader().getResourceAsStream("service-account.json"); ServiceAccountCredentials.Builder credentialsSimpleBuilder = ServiceAccountCredentials.fromStream(serviceAccountFile).toBuilder(); credentialsSimpleBuilder.setScopes(ImmutableList.of("https://www.googleapis.com/auth/assistant")); AccessToken accessToken = credentialsSimpleBuilder.build().refreshAccessToken(); return accessToken.getTokenValue(); } /** * Send an incremental update to update or add an entity. * @param entityId The id of the entity to update. * @param entity the json of the entity to be updated. */ public void updateEntity(String entityId, JSONObject data) { String authToken = getAuthToken(); String endpoint = String.format("https://actions.googleapis.com/v2/apps/%s/entities/:batchPush", PROJECT_ID); JSONObject entity = new JSONObject(); entity.put("data", data.toString()); entity.put("name", String.format("apps/%s/entities/%s", PROJECT_ID, URLEncoder.encode(ENTITY_ID, "UTF-8"))); JSONObject request = new JSONObject(); request.put("entity", entity); JSONArray requestArray = new JSONArray(); requestArray.put(request); JSONObject payload = new JSONObject(); payload.put("requests", requestArray); payload.put("vertical", FOODORDERING); // Execute POST request executePostRequest(endpoint, authToken, payload); }
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 do zaktualizowania | Opis i efekty |
---|---|---|
Wyłączanie usługi | Service |
Musisz wyłączyć usługę z nieprzewidzianego powodu. Aktualizacje przyrostowe: aktualizuj element Pełne pliki danych: pamiętaj, aby zaktualizować element z pełnych kanałów.
aby |
Brak produktu w magazynie | MenuItemOffer |
Aktualizacje przyrostowe: wyślij MenuItemOffer dołączający do wiadomości.
encja z wartością inventoryLevel ustawioną na 0 dla danej wartości
MenuItem i wszystkie inne dane bez zmian. |
Zmiana ceny pozycji menu | MenuItemOffer |
Aktualizacje przyrostowe: wyślij MenuItemOffer dołączający do wiadomości.
element z wartością 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. Pełne pliki danych: dodaj element do plików danych i poczekaj na przetworzenie zbiorcze. |
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 |
ServiceArea |
Dodatkowe pliki danych: wyślij element ServiceArea , 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 polygon , geoRadius lub postalCode . |
Zaktualizuj szacowany czas dostawy za Service |
ServiceHours |
Dodatkowe pliki danych: wyślij ServiceHours tak samo jak w
pliki danych z wyjątkiem aktualizacji leadTimeMin
odpowiednio się zmienia. |
Zaktualizuj ceny dostawy w: Service |
Fee |
Dodatkowe pliki danych: wyślij pełne przesłanie Fee z
Zaktualizowano: price . |
Zaktualizuj godziny dostawy lub na wynos w: Service |
ServiceHours |
Dodatkowe pliki danych: wyślij ServiceHours tak samo jak w
pliki danych z wyjątkiem ich właściwości opens i closes zostaną zaktualizowane;
odpowiednio się zmienia. |
Service (zmień minimalną kwotę zamówienia) |
Fee |
Dodatkowe pliki danych: wyślij pełne Fee za pomocą
minPrice
zaktualizowano |
Trwale usuń element MenuItem |
Menu |
Dodatkowe pliki danych: wyślij MenuItem takie same jak w pliku
plików danych, ale parentMenuSectionId jest pusty.
|
Docelowy czas przetwarzania w przypadku zadań wsadowych i aktualizacji przyrostowych
Encja zaktualizowana lub usunięta poprzez wsad zostanie przetworzona w ciągu 2 godzin godzin w trybie najlepszych wyników, 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.