Aggiornamenti incrementali sull'inventario v2

di Gemini Advanced.

Questa sezione descrive come inviare aggiornamenti dell'inventario urgenti a Google. L'API Incremental Update consente di eseguire il push degli aggiornamenti e nel tuo inventario sandbox o di produzione quasi in tempo reale.

Questa funzionalità è pensata principalmente per aggiornamenti che non puoi prevedere, come chiusure di emergenza. Di norma, qualsiasi modifica inviata tramite L'API Incremental Update deve essere una modifica che deve essere pubblicata entro all'ora. Se non è necessario che la modifica sia riportata immediatamente, puoi utilizzare l'importazione in batch. Gli aggiornamenti incrementali vengono elaborati in non più di cinque minuti.

Prerequisiti

Per implementare gli aggiornamenti incrementali, sono necessari i seguenti elementi:

  1. Viene creato un account di servizio con il ruolo di editor per il progetto Actions. Per ulteriori dettagli, vedi Crea e configura un progetto.
  2. I feed di dati di produzione o sandbox vengono ospitati e importati. Per ulteriori dettagli, vedi Importazione in batch:
  3. (Facoltativo, ma consigliato) Installa la libreria client di Google. nella lingua scelta per facilitare l'utilizzo di OAuth 2.0 durante le chiamate tramite Google Cloud CLI o tramite l'API Compute Engine. Gli esempi di codice inclusi di seguito utilizzano queste librerie. In caso contrario, Occorre gestire manualmente lo scambio di token, come descritto in Utilizzo di OAuth 2.0 per accedere alle API di Google.

Endpoint

Nelle richieste riportate di seguito, sostituisci quanto segue:

  • PROJECT_ID: ID progetto Google Cloud associato al progetto creato in Creare e configurare un progetto.
  • TYPE: il tipo di entità (proprietà @type) dell'oggetto nel feed di dati che vuoi aggiornare.
  • ENTITY_ID (solo eliminazione endpoint): ID dell'entità da eliminare. Assicurati di Codifica l'ID entità nell'URL.
  • DELETE_TIME (solo eliminazione endpoint): campo facoltativo per indicare la l'ora in cui l'entità è stata eliminata sui tuoi sistemi (per impostazione predefinita si intende quando la richiesta ricevute). Il valore dell'ora non deve essere nel futuro. Quando invii un'entità tramite una chiamata incrementale, il controllo delle versioni delle entità utilizza il campo delete_time anche in caso di chiamata di eliminazione. Formatta valore come yyyy-mm-ddTHH:mm:ssZ

Aggiorna endpoint

Per modificare un'entità, effettua una richiesta POST HTTP al seguente endpoint e includere un payload di aggiornamenti e aggiunte. Puoi aggiornare fino a 1000 entità in una singola chiamata API.

https://actions.googleapis.com/v2/apps/PROJECT_ID/entities:batchPush

Ad esempio, se vuoi aggiornare le entità in un progetto con un ID "delivery-provider-id" l'endpoint sarà il seguente:

https://actions.googleapis.com/v2/apps/delivery-provider-id/entities:batchpush

Elimina endpoint

Per eliminare un'entità dall'inventario, effettua una richiesta DELETE HTTP al seguente endpoint.

https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID?entity.vertical=FOODORDERING&delete_time=DELETE_TIME

Ad esempio, per eliminare una "MenuSezione" entità con ID "menuSezione_122" dal tuo "delivery-provider-id" devi effettuare una chiamata all'API DELETE HTTP per:

https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122?entity.vertical=FOODORDERING

Ambiente sandbox

Per utilizzare l'API Incremental Update nell'inventario sandbox, segui le indicazioni fornite nella sezione precedente Endpoint, ma invia richieste a /v2/sandbox/apps/ anziché a /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

Aggiornamento delle entità

Ogni richiesta POST deve includere i parametri della richiesta e il codice JSON payload contenente i dati strutturati di qualsiasi tipo di entità elencato nel schema dell'inventario.

Aggiorna payload

Il codice JSON dovrebbe avere lo stesso aspetto del feed batch, con le seguenti differenze:

  • Le dimensioni del corpo del payload non devono superare i 5 MB. Analogamente alla modalità batch ti consigliamo di eliminare gli spazi vuoti per inserire più dati.
  • La busta è la seguente:
{
  "requests": [
    {
      "entity": {
        "data":"ENTITY_DATA",
        "name": "apps/project_id>/entities/type/entity_id"
      },
      "update_time":"UPDATE_TIMESTAMP"
    },
  ],
  "vertical": "FOODORDERING"
}

Nel payload riportato sopra, sostituisci quanto segue:

  • ENTITY_DATA: entità in formato JSON serializzata come stringa. La L'entità JSON-LD deve essere passata come stringa nel campo data.
  • (Facoltativo) UPDATE_TIMESTAMP: timestamp del momento dell'aggiornamento dell'entità in nei tuoi sistemi. Il valore dell'ora non deve essere nel futuro. Il timestamp predefinito è Google riceve la richiesta. Quando si invia un'entità tramite un modello richiesta, il controllo delle versioni dell'entità utilizza anche update_time nel caso di una richiesta di aggiunta/aggiornamento.

Esempi

Esempio 1: aggiornare un ristorante

Supponiamo che tu debba aggiornare urgentemente il numero di telefono di un ristorante. Il tuo contiene il codice JSON dell'intero ristorante.

Prendi in considerazione un feed batch simile al seguente:

{
  "@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
}

In questo caso, l'aggiornamento incrementale tramite HTTP POST sarebbe il seguente:

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"
}

Esempio 2: aggiornare più ristoranti

Per aggiornare due entità ristorante in una singola chiamata API, la richiesta HTTP POST sarebbe la seguente:

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"
}

Esempio 3: aggiornare il prezzo di una voce di menu

Supponiamo di dover modificare il prezzo di una voce del menu. Come nell'esempio 1, deve contenere il codice JSON per l'intera entità di primo livello (il menu) e utilizza lo schema dell'inventario v1.

Prendi in considerazione un feed batch simile al seguente:

{
  "@type": "MenuItemOffer",
  "@id": "menuitemoffer6680262",
  "sku": "offer-cola",
  "menuItemId": "menuitem896532",
  "price": 3.00,
  "priceCurrency": "USD"
}

In questo caso, l'aggiornamento incrementale tramite POST sarebbe il seguente:

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"
}

Aggiunta di un'entità

Per aggiungere entità, evita di utilizzare aggiornamenti dell'inventario. Utilizza invece i feed in batch come descritto per lo schema dell'inventario v2.

Rimozione di un'entità

Per rimuovere le entità di primo livello, utilizza un endpoint leggermente modificato, e utilizzare HTTP DELETE anziché HTTP POST nella richiesta.

Eliminazione di un'entità di primo livello

Considera una situazione in cui vuoi eliminare un ristorante in un feed. Devi e i relativi servizi e menu.

Un endpoint di esempio per un'entità menu con ID "provider/restaurant/menu/nr":

DELETE v2/apps/delivery-provider-id/entities/menu/provider%2Frestaurant%2Fmenu%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com

Un endpoint di esempio per un'entità ristorante con ID "https://www.provider.com/restaurant/nr":

DELETE v2/apps/delivery-provider-id/entities/restaurant/provider%2Frestaurant%2Fnr?entity.vertical=FOODORDERING
Host: actions.googleapis.com

Un endpoint di esempio per un'entità di servizio con ID "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
}

Rimozione di entità secondarie

Non utilizzare HTTP DELETE per rimuovere un'entità secondaria all'interno di un'entità di primo livello, ad esempio un elemento all'interno di un menu. Considera invece la rimozione di entità secondarie aggiornamento a un'entità di primo livello in cui l'entità secondaria viene rimossa pertinente o reverseReference.

Codici di risposta delle API

Una chiamata riuscita non significa che il feed sia valido o corretto, ma solo che il valore Chiamata API effettuata. Le chiamate riuscite ricevono un codice di risposta HTTP 200, insieme con un corpo della risposta vuoto:

{}

Per gli errori, il codice di risposta HTTP non sarà 200 e il corpo della risposta indica il problema.

Ad esempio, se l'utente ha impostato il "verticale" valore nella busta FAKE_VERTICAL, riceverai il messaggio seguente:

{
  "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\""
          }
        ]
      }
    ]
  }
}

Esempio di codice

Di seguito sono riportati alcuni esempi di utilizzo dell'API Incremental Update in diverse lingue diverse. Questi esempi utilizzano le librerie di Google Auth e presuppongono che un feed utilizzi lo schema dell'inventario v1. Per soluzioni alternative, consulta Utilizzo di OAuth 2.0 per applicazioni server-server.

Aggiornamento delle entità

Node.js

Questo codice utilizza la libreria di autenticazione di Google per 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

Questo codice utilizza la libreria di autenticazione di Google per Python.

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

Questo codice utilizza la libreria di autenticazione di Google per 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);
}

Rimozione delle entità

Node.js

Questo codice utilizza la libreria di autenticazione di Google per 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

Questo codice utilizza la libreria di autenticazione di Google per Python.

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

Questo codice utilizza la libreria di autenticazione di Google per 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));
}

Casi d'uso

I seguenti casi d'uso sono esempi di aggiornamenti incrementali, aggiornamenti completi dei feed e i contenuti ad alto livello nella chiamata API:

Scenario Entità da aggiornare Descrizione ed effetti
Disattivazione di un servizio Service

Devi disattivare un servizio per un motivo imprevisto.

Aggiornamenti incrementali: aggiorna l'entità Service in impostando la relativa proprietà isDisabled su true, ma mantengono invariate le altre proprietà.

Feed completi: assicurati di aggiornare l'entità dai feed completi. per avere isDisabled impostato su true prima del al recupero successivo da parte di Google, altrimenti l'entità viene riattivata.

Un articolo specifico non è disponibile MenuItemOffer Aggiornamenti incrementali: invia il MenuItemOffer di incapsulamento entità con inventoryLevel impostato su 0 per la data specificata MenuItem e tutti gli altri dati invariati.
Variazione di prezzo della voce di menu MenuItemOffer Aggiornamenti incrementali: invia il MenuItemOffer di incapsulamento entità con price impostato sul prezzo aggiornato per il MenuItem e tutti gli altri dati invariati.

Aggiungi nuova entità di primo livello

Applicabile solo per entità di tipo Menu, Restaurant e Service.

Menu, Restaurant e Service

Ad esempio, devi aggiungere un nuovo menu a un ristorante.

Feed completi:aggiungi l'entità ai feed di dati e attendi l'importazione in batch.

Elimina definitivamente entità di primo livello

Applicabile solo per entità di tipo Menu, Restaurant e Service.

Menu, Restaurant e Service

Aggiornamenti incrementali: invia un eliminazione esplicita.

Feed completi: assicurati di rimuovere l'entità dai feed completi prima del giorno al recupero successivo da parte di Google, altrimenti l'entità verrà aggiunta di nuovo.

Aggiungi una nuova zona di consegna in un intervallo specifico: Service ServiceArea Feed incrementali: invia l'entità ServiceArea in questione con tutti i relativi campi intatti, come faresti normalmente nei feed completi, con una nuova area di consegna specificato in polygon, geoRadius o postalCode.
Aggiorna l'orario di arrivo previsto per la consegna nel mese di Service ServiceHours Feed incrementali: invia il ServiceHours come in i feed, ad eccezione del fatto che il valore leadTimeMin è aggiornato di conseguenza.
Aggiorna i prezzi per la consegna nel seguente paese: Service Fee Feed incrementali: invia la pubblicazione completa Fee con price aggiornato.
Aggiorna gli orari di consegna o ritiro in Service ServiceHours Feed incrementali: invia il ServiceHours come in i feed, ad eccezione delle proprietà opens e closes aggiornate di conseguenza.
Service (modifica l'importo minimo dell'ordine) Fee Feed incrementali: invia Fee completi con minPrice aggiornato
Elimina definitivamente MenuItem Menu Feed incrementali: invia il MenuItem come nell'attributo feed, ma con parentMenuSectionId vuoto.

SLO sul tempo di elaborazione per job batch e aggiornamenti incrementali

Un'entità aggiornata o eliminata tramite un batch verrà elaborata entro 2 ore in modalità di massimo impegno, mentre un'entità aggiornata tramite un aggiornamento incrementale viene elaborata in 5 minuti. Un'entità inattiva viene eliminata dopo 7 giorni.

Puoi inviare a Google:

  • Più job batch al giorno per mantenere l'inventario aggiornato OPPURE
  • Un job batch al giorno e API incrementali per mantenere l'inventario aggiornato.