עדכוני מלאי מצטבר גרסה 1

בקטע הזה נסביר איך לשלוח ל-Google עדכונים תלויי-זמן של הפידים שלכם. ה-Inremental Updates API מאפשר לעדכן ולמחוק ישויות בפידים כמעט בזמן אמת.

הפונקציונליות הזו מיועדת בעיקר לעדכונים שאי אפשר לחזות מראש, כמו חסימות חירום. ככלל, כל שינוי שנשלח דרך Incremental Updates API צריך להיות שינוי שיחול בתוך שבוע לכל היותר. אם אין צורך לתקף את השינוי באופן מיידי, אפשר להשתמש בעדכון בכמות גדולה במקום זאת. העדכונים המצטברים מעובדים בתוך חמש דקות לכל היותר.

Setup (הגדרה)

כדי להטמיע עדכונים מצטברים:

  1. כדי ליצור פרויקט, פועלים לפי ההוראות במאמר יצירה והגדרה של פרויקט.
  2. במאמר הגדרה של חשבון שירות מוסבר איך ליצור חשבון שירות. שימו לב: כדי שתוכלו להוסיף תפקיד 'עריכה' לחשבון השירות, עליכם להיות עם התפקיד 'בעלים' בפרויקט.
  3. (אופציונלי, אבל מומלץ) מתקינים את ספריית הלקוח של Google בשפה הרצויה כדי לאפשר שימוש ב-OAuth 2.0 בקריאה ל-API. דוגמאות הקוד המפורטות בהמשך משתמשות בספריות אלו. אחרת, תצטרכו לטפל בהמרות של אסימונים באופן ידני, כפי שמתואר במאמר שימוש ב-OAuth 2.0 לגישה ל-Google APIs.

נקודת קצה

כדי להודיע ל-Google על עדכון, שולחים בקשת HTTP POST ל-Inremental Updates API וכוללים מטען ייעודי (payload) של עדכונים ותוספות. סכימת המלאי שבה משתמשים קובעת לאיזו נקודת קצה לשלוח את הבקשה:

מלאי גרסה 2

https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/TYPE/ENTITY_ID:push

מלאי שטחי פרסום בגרסה 1

https://actions.googleapis.com/v2/apps/PROJECT_ID/entities/ENTITY_ID:push

כדי להסיר ישות, צריך לשלוח בקשת HTTP DELETE לנקודת הקצה הבאה שתואמת לסכימת המלאי שבה אתם משתמשים:

מלאי גרסה 2

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

מלאי שטחי פרסום בגרסה 1

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

בבקשות שלמעלה, צריך להחליף את הפרטים הבאים:

  • PROJECT_ID: מזהה הפרויקט ב-Google Cloud שמשויך לפרויקט שיצרתם בקטע Create and set up a project (יצירה והגדרה של פרויקט).
  • TYPE (סכימת מלאי v2 בלבד): סוג הישות (נכס @type) של האובייקט בפיד הנתונים שרוצים לעדכן.
  • ENTITY_ID: מזהה של הישות שכלולה במטען הייעודי (payload). חשוב לוודא ש-URL מקודד את מזהה הישות.
  • DELETE_TIME (מחיקה של נקודת הקצה בלבד): שדה אופציונלי לציון הזמן שבו הישות נמחקה במערכות שלכם (ברירת המחדל היא מועד קבלת הבקשה). ערך הזמן אינו יכול להיות בעתיד. כששולחים ישות באמצעות קריאה מצטברת, ניהול גרסאות של ישויות משתמש גם בשדה delete_time במקרה של מחיקת קריאה. הפורמט של הערך הזה צריך להיות yyyy-mm-ddTHH:mm:ssZ

לדוגמה, אם יש לכם פרויקט שהמזהה שלו הוא 'delivery-provider-id' שמשתמש בסכימת המלאי v2. אתם רוצים לבצע שינויים במסעדה עם סוג הישות של מסעדה "MenuSection" ומזהה ישות "menuSection_122". נקודת הקצה לעדכון הנתונים תהיה:

https://actions.googleapis.com/v2/apps/delivery-provider-id/entities/MenuSection/menuSection_122:push

כדי להסיר את אותה ישות, צריך לבצע את הקריאה הבאה ל-HTTP DELETE API:

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

בקשות ב-Sandbox

בבקשות ל-Sandbox, פועלים לפי ההנחיות המפורטות בקטע Endpoint שלמעלה, אבל יש לשלוח בקשות אל /v2/sandbox/apps/ במקום אל /v2/apps/. לדוגמה, בקשת מחיקה של Sandbox לסכימת מלאי v2 בנויה כך:

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

עדכונים ותוספות

גם הפידים היומיים באצווה צריכים לכלול את כל השינויים שנשלחו דרך ה-API הזה. אחרת, העדכונים בכמות גדולה יחליפו את השינויים המצטברים.

מטען ייעודי (payload)

כל בקשת POST צריכה לכלול את הפרמטרים של הבקשה יחד עם המטען הייעודי (payload) של JSON שמכיל נתונים מובְנים של כל סוג ישות שרשום בסכימת המלאי.

קובץ ה-JSON אמור להיראות כמו בפיד האצווה, עם ההבדלים הבאים:

  • גוף המטען הייעודי לא יכול להיות גדול מ-5MB. בדומה לפידים באצווה, מומלץ להסיר רווחים לבנים כדי להתאים יותר נתונים.
  • המעטפה הבאה:
{
  "entity": {
    "data":"ENTITY_DATA",
    "vertical":"FOODORDERING"
  },
  "update_time":"UPDATE_TIMESTAMP"
}

במטען הייעודי (payload) שלמעלה, מחליפים את הפריטים הבאים:

  • ENTITY_DATA: ישות בפורמט JSON מסודרת כמחרוזת. צריך להעביר את הישות JSON-LD כמחרוזת בשדה data.
  • UPDATE_TIMESTAMP (אופציונלי): חותמת זמן של מועד העדכון של הישות במערכות שלכם. ערך הזמן אינו יכול להיות בעתיד. חותמת הזמן של ברירת המחדל היא התאריך שבו Google מקבלת את הבקשה. כששולחים ישות באמצעות בקשה מצטברת, ניהול הגרסאות של הישות משתמש גם בשדה update_time במקרה של בקשת הוספה/עדכון.

עדכון ישות

דוגמה 1: עדכון מסעדה

נניח שאתם צריכים לעדכן בדחיפות מספר טלפון של מסעדה. העדכון מכיל קובץ JSON לכל המסעדה.

נניח שיש לכם פיד אצווה שנראה כך:

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

כך העדכון המצטבר באמצעות HTTP POST:

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

דוגמה 2: עדכון מחיר של פריט בתפריט

נניח שצריך לשנות את המחיר של פריט בתפריט. כמו בדוגמה 1, העדכון חייב להכיל את ה-JSON של כל הישות ברמה העליונה (התפריט), ובפיד נעשה שימוש בסכימת המלאי v1.

נניח שיש לכם פיד אצווה שנראה כך:

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

לאחר מכן, העדכון המצטבר דרך POST יהיה:

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

הוספת ישות

כדי להוסיף ישויות, אין להשתמש בעדכוני מלאי. במקום זאת, צריך להשתמש בתהליך של פידים באצווה, כפי שמתואר בסכימת המלאי לגרסה 2.

הסרת ישות

כדי להסיר ישויות ברמה העליונה, צריך להשתמש בנקודת קצה שעברה שינוי קל ולהשתמש ב-HTTP DELETE במקום ב-HTTP POST בבקשה.

אסור להשתמש ב-HTTP DELETE כדי להסיר ישות משנה בתוך ישות ברמה העליונה, כמו למשל פריט בתפריט בתוך תפריט. במקום זאת, יש להתייחס להסרה של ישויות משנה כעדכון לישות ברמה העליונה שבה ישות המשנה הוסרה מהרשימה או מהפרמטר הרלוונטיים.

דוגמה 1: מחיקת ישות ברמה העליונה

כדאי להביא בחשבון מצב שבו רוצים למחוק מסעדה בפיד שמשתמשת בסכימת המלאי v1. עליך למחוק גם את השירותים והתפריטים שלו.

דוגמה של נקודת קצה לישות תפריט עם המזהה "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

נקודת קצה לדוגמה לישות של מסעדה עם המזהה "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

דוגמה של נקודת קצה לישות שירות עם המזהה "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
}

דוגמה 2: הסרת ישויות משנה

כדי להסיר ישות משנה מתוך ישות ברמה העליונה, שולחים את הישות ברמה העליונה לאחר שישות המשנה הוסרה מהשדה המתאים. בדוגמה הבאה ההנחה היא שהפיד משתמש בסכימת מלאי v1.

לדוגמה, כדי להסיר אזור שירות, מעדכנים את השירות כך שאזור השירות הוסר מהרשימה 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"
  }
}

קודי תגובה של API

קריאה מוצלחת לא מעידה על כך שהפיד תקין או נכון, אלא רק על כך שבוצעה הקריאה ל-API. קריאות מוצלחות מקבלות קוד תגובת HTTP 200, עם גוף תגובה ריק:

{}

במקרה של כשלים, קוד התגובה של ה-HTTP לא יהיה 200, וגוף התגובה מציין מה השתבש.

לדוגמה, אם המשתמש הגדיר את הערך 'vertical' במעטפה כ-FAKE_VERTICAL, תתקבל ההודעה הבאה:

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

דוגמת קוד

בהמשך מפורטות כמה דוגמאות לשימוש ב-Incrmental Updates API בשפות שונות. בדוגמאות האלה נעשה שימוש בספריות האימות של Google, ומתבססים על פיד באמצעות סכימת המלאי v1. לפתרונות חלופיים, קראו את המאמר שימוש ב-OAuth 2.0 לאפליקציות שרת-אל-שרת.

מתבצע עדכון ישויות

Node.js

הקוד הזה משתמש בספריית האימות של Google עבור 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

הקוד הזה משתמש בספריית Google auth ל-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 = '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

הקוד הזה משתמש בספריית האימות של Google עבור 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);
}

הסרת ישויות

Node.js

הקוד הזה משתמש בספריית האימות של Google עבור 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

הקוד הזה משתמש בספריית Google auth ל-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

הקוד הזה משתמש בספריית האימות של Google עבור 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));
}

תרחישים לדוגמה

התרחישים הבאים הם דוגמאות לעדכונים מצטברים, לעדכוני פיד מלאים ולתוכן ברמה גבוהה בקריאה ל-API:

תרחיש ישות ברמה העליונה תיאור ואפקטים
השבתה של שירות DisabledService

צריך להשבית שירות מסיבה בלתי צפויה.

עדכונים מצטברים: שליחת הישות Service המדוברת עם הערך @type שמשתנה באופן הבא: DisabledService, אבל משאירים את שאר הנכסים ללא שינוי.

פידים מלאים: לפני האחזור הבא של Google, חשוב לעדכן את הישות מהפידים המלאים כך שהערך של @type יוגדר ל-DisabledService. אחרת, הישות תופעל מחדש.

פריט מסוים חסר במלאי Menu עדכונים מצטברים: צריך לשלוח את הישות Menu של האנקפסולציה עם offer.inventoryLevel שמוגדר ל-0 עבור MenuItem הנתון, וכל שאר הנתונים ללא שינוי.
שינוי במחיר של פריט בתפריט Menu עדכונים מצטברים: יש לשלוח את הישות המסכמת Menu כאשר offer.price מוגדר למחיר המעודכן עבור MenuItem הנתון, וכל שאר הנתונים ללא שינוי.

הוספת ישות חדשה ברמה העליונה

רלוונטי רק לישויות מהסוגים Menu, Restaurant ו-Service.

Menu,‏ Restaurant,‏ Service

למשל, אם צריך להוסיף תפריט חדש למסעדה.

עדכונים מצטברים: כדי לעדכן את הישות החדשה של התפריט, צריך לעדכן בהתאם את ישות המסעדה עם השדה hasMenu.

מחיקת ישות ברמה העליונה באופן סופי

רלוונטי רק לישויות מהסוגים Menu, Restaurant ו-Service.

Menu,‏ Restaurant,‏ Service

עדכונים מצטברים: שליחת מחיקה בוטה.

פידים מלאים: חשוב להסיר את הישות מהפידים המלאים לפני האחזור הבא של Google, אחרת הישות תתווסף מחדש.

הוספת אזור משלוחים חדש בשביל Service ספציפי Service פידים מצטברים: צריך לשלוח את הישות Service הרלוונטית כשכל השדות שלה שלמים, כמו שהייתם עושים בדרך כלל בפידים המלאים, ולציין אזור משלוח חדש בתוך areaServed מתוך Service.
עדכון זמן ההגעה המשוער בService Service פידים מצטברים: שולחים את הערך Service כמו בפידים, אלא שהhoursAvailable.deliveryHours שלו מתעדכן בהתאם.
עדכון מחירי משלוחים בService Service פידים מצטברים: שליחת Service מלאים עם עדכון של offers.priceSpecification.price.
עדכון שעות האספקה או האיסוף בService Service פידים מצטברים: שולחים את הערך Service כמו בפידים, אלא שהhoursAvailable שלו מתעדכן בהתאם.
Service (שינוי סכום ההזמנה המינימלי) Service פידים מצטברים: שליחת Service מלאים עם Service.offers.priceSpecification.eligibleTransactionVolume מעודכנים
מחיקה סופית של MenuItem Menu פידים מצטברים: יש לשלוח את אותם Menu כמו בפידים, אבל כשה-MenuItem הזה הוסר מהרשימה hasMenuItems.

יעד למדידת רמת השירות (SLO) בזמן העיבוד של משימות באצווה ועדכונים מצטברים

ישות שנוספה באמצעות עדכון באצווה או עדכון מצטבר תעובד בתוך יום עד יומיים. ישות שעודכנו או נמחקה באמצעות אצווה תעובד בתוך שעתיים, ואילו ישות שעודכנה באמצעות עדכון מצטבר תעובד בתוך 5 דקות. ישות לא עדכנית תימחק תוך 7 ימים.

אפשר לשלוח ל-Google אחת מהאפשרויות הבאות:

  • כמה משימות באצווה ביום כדי לשמור על מלאי עדכני, או
  • משימה אחת באצווה אחת ליום וממשקי API מצטברים לעדכון המלאי שלך.