Dodawanie produktów i zarządzanie nimi

Sub-API Products umożliwia zarządzanie całym cyklem życia produktów w Merchant Center. Możesz go używać do przesyłania nowych produktów, aktualizowania istniejących, pobierania informacji o produktach i usuwania produktów, których już nie sprzedajesz.

Specjalne uwagi

  • Produkty można wstawiać, aktualizować lub usuwać tylko wtedy, gdy należą do źródeł danych typu API. Nie możesz wstawiać ani aktualizować produktów w źródłach danych, które korzystają z przesyłania plików.
  • Aby produkty były aktualne i nie wygasały , należy je regularnie aktualizować lub odświeżać (co najmniej raz na 30 dni).
  • Segment ProductInput.name to unikalny identyfikator produktu. Produkty są identyfikowane przez kombinację języka, etykiety pliku danych i identyfikatora oferty w formacie contentLanguage~feedLabel~offerId, np. en~US~sku12345. Interfejs Merchant API używa tego identyfikatora do tworzenia nazw zasobów product i productInput, na przykład accounts/12345/products/en~US~SKU12345.
  • Jeśli jakakolwiek część identyfikatora produktu, np. offerId, zawiera znaki zarezerwowane dla adresu URL lub znaki używane przez Merchant API, takie jak /, % lub ~, musisz zakodować część identyfikatora en~US~SKU12345. Więcej informacji znajdziesz w opisie pola ProductInput.name. Część identyfikatora en~US~SKU12345 musi być zakodowana na potrzeby adresu URL, gdy jest uwzględniona w adresie URL żądania.

Wymagania wstępne

Zanim zaczniesz dodawać produkty lub nimi zarządzać za pomocą interfejsu API, musisz mieć skonfigurowane co najmniej jedno źródło danych na koncie Merchant Center.

Aby utworzyć źródło danych, użyj metody dataSources.create z podrzędnego interfejsu API źródeł danych. Aby ułatwić sobie podjęcie decyzji o typie źródła danych, które chcesz utworzyć, zapoznaj się z artykułami Wybieranie strategii dotyczącej źródła danych i Zarządzanie źródłami danych API do przesyłania produktów. Po utworzeniu źródła danych zanotuj jego name (np. accounts/12345/dataSources/67890), ponieważ będzie on potrzebny do tworzenia, aktualizowania i usuwania żądań związanych z produktami.

Nowo utworzone źródła danych są domyślnie włączone dla wszystkich miejsc docelowych (nazywanych też metodami marketingowymi) dostępnych na koncie. Więcej informacji o możliwych miejscach docelowych znajdziesz w artykule Czym są metody marketingowe?.

Więcej informacji o źródłach danych znajdziesz w przewodniku Zarządzanie źródłami danych interfejsu API na potrzeby przesyłania produktów.

Dodaj produkt

Aby dodać nowy produkt do konta Merchant Center, musisz wstawić zasób ProductInput do podstawowego źródła danych. To działanie spowoduje utworzenie produktu i rozpoczęcie przetwarzania. Pola w obiekcie productAttributes muszą być zgodne ze specyfikacją danych produktów.

Użyj metody productInputs.insert i podaj name podstawowego źródła danych jako parametr dataSource.

Poniższy przykład pokazuje, jak wstawić nowy produkt do sklepu internetowego w podstawowym źródle danych. Produkt ma pewne atrybuty, takie jak:

Więcej informacji o atrybutach produktu znajdziesz w artykule ProductAttributes.

POST https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs:insert?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}
{
  "offerId": "SKU12345",
  "contentLanguage": "en",
  "feedLabel": "US",
  "productAttributes": {
    "title": "Classic Cotton T-Shirt",
    "description": "A comfortable, durable, and stylish t-shirt made from 100% cotton.",
    "link": "https://www.example.com/p/SKU12345",
    "imageLink": "https://www.example.com/img/SKU12345.jpg",
    "videoLinks": [
      "https://www.example.com/videos/SKU12345_1.mp4",
      "https://www.example.com/videos/SKU12345_2.mp4"
    ],
    "availability": "IN_STOCK",
    "price": {
      "amountMicros": "15990000", // 15.99 USD
      "currencyCode": "USD"
    },
    "condition": "NEW",
    "gtins": ["9780007350896", "93433295494587"],
    "size": "XL",
    "sizeSystem": "US",
    "sizeTypes": [
      "BIG",
      "TALL"
    ]
  }
}

Udane wywołanie zwraca nowo utworzony zasób ProductInput. Pole name zawiera unikalny identyfikator tych danych wejściowych produktu, a pole product zawiera nazwę ostatecznego, przetworzonego produktu, którego możesz później użyć do jego pobrania.

Pola zwracane w odpowiedzi productInputs.insert odzwierciedlają wartości wejściowe. Przetworzone wartości, które zostaną zachowane w wynikowym productAttributes, mogą się różnić.

{
 "name": "accounts/{ACCOUNT_ID}/productInputs/{en~US~SKU12345}",
 "product": "accounts/{ACCOUNT_ID}/products/{en~US~SKU12345}",
 "offerId": "SKU12345",
 "contentLanguage": "en",
 "feedLabel": "US",
 "productAttributes": {
   "title": "Classic Cotton T-Shirt",
   "description": "A comfortable, durable, and stylish t-shirt made from 100% cotton.",
   "link": "https://www.example.com/p/SKU12345",
   "imageLink": "https://www.example.com/img/SKU12345.jpg",
    "videoLinks": [
      "https://www.example.com/videos/SKU12345_1.mp4",
      "https://www.example.com/videos/SKU12345_2.mp4"
    ],
   "availability": "IN_STOCK",
   "price": {
     "amountMicros": "15990000",
     "currencyCode": "USD"
   },
   "condition": "NEW",
   "gtins": [
     "9780007350896"
   ]
 }
}

Poniższe przykłady kodu pokazują, jak dodać produkt.

Java

import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.shopping.merchant.products.v1.Availability;
import com.google.shopping.merchant.products.v1.Condition;
import com.google.shopping.merchant.products.v1.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1.ProductAttributes;
import com.google.shopping.merchant.products.v1.ProductInput;
import com.google.shopping.merchant.products.v1.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1.Shipping;
import com.google.shopping.type.Price;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/** This class demonstrates how to insert a product input */
public class InsertProductInputSample {

  private static String getParent(String accountId) {
    return String.format("accounts/%s", accountId);
  }

  public static ProductInput insertProductInput(Config config, String dataSource) throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Creates service settings using the credentials retrieved above.
    ProductInputsServiceSettings productInputsServiceSettings =
        ProductInputsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .build();

    // Creates parent to identify where to insert the product.
    String parent = getParent(config.getAccountId().toString());

    try (ProductInputsServiceClient productInputsServiceClient =
        ProductInputsServiceClient.create(productInputsServiceSettings)) {

      // Price to be used for shipping ($33.45).
      Price price = Price.newBuilder().setAmountMicros(33_450_000).setCurrencyCode("USD").build();

      Shipping shipping =
          Shipping.newBuilder()
              .setPrice(price)
              .setCountry("GB")
              .setService("1st class post")
              .build();

      Shipping shipping2 =
          Shipping.newBuilder()
              .setPrice(price)
              .setCountry("FR")
              .setService("1st class post")
              .build();

      ProductAttributes attributes =
          ProductAttributes.newBuilder()
              .setTitle("A Tale of Two Cities")
              .setDescription("A classic novel about the French Revolution")
              .setLink("https://exampleWebsite.com/tale-of-two-cities.html")
              .setImageLink("https://exampleWebsite.com/tale-of-two-cities.jpg")
              .setAvailability(Availability.IN_STOCK)
              .setCondition(Condition.NEW)
              .setGoogleProductCategory("Media > Books")
              .addGtins("9780007350896")
              .addShipping(shipping)
              .addShipping(shipping2)
              .build();

      // The datasource can be either a primary or supplemental datasource.
      InsertProductInputRequest request =
          InsertProductInputRequest.newBuilder()
              .setParent(parent)
              // You can only insert products into datasource types of Input "API" and "FILE", and
              // of Type "Primary" or "Supplemental."
              // This field takes the `name` field of the datasource.
              .setDataSource(dataSource)
              // If this product is already owned by another datasource, when re-inserting, the
              // new datasource will take ownership of the product.
              .setProductInput(
                  ProductInput.newBuilder()
                      .setContentLanguage("en")
                      .setFeedLabel("GB")
                      .setOfferId("sku123")
                      .setProductAttributes(attributes)
                      .build())
              .build();

      System.out.println("Sending insert ProductInput request");
      ProductInput response = productInputsServiceClient.insertProductInput(request);
      System.out.println("Inserted ProductInput Name below");
      // The last part of the product name will be the product ID assigned to a product by Google.
      // Product ID has the format `contentLanguage~feedLabel~offerId`
      System.out.println(response.getName());
      System.out.println("Inserted Product Name below");
      System.out.println(response.getProduct());
      return response;
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    // Identifies the data source that will own the product input.
    String dataSource = "accounts/" + config.getAccountId() + "/dataSources/{INSERT_DATASOURCE_ID}";

    insertProductInput(config, dataSource);
  }
}

PHP

use Google\ApiCore\ApiException;
use Google\Shopping\Merchant\Products\V1\Availability;
use Google\Shopping\Merchant\Products\V1\Condition;
use Google\Shopping\Merchant\Products\V1\ProductAttributes;
use Google\Shopping\Merchant\Products\V1\InsertProductInputRequest;
use Google\Shopping\Merchant\Products\V1\ProductInput;
use Google\Shopping\Merchant\Products\V1\Client\ProductInputsServiceClient;
use Google\Shopping\Merchant\Products\V1\Shipping;
use Google\Shopping\Type\Price;

/**
 * Uploads a product input to your Merchant Center account.
 */
class InsertProductInput
{

    // ENSURE you fill in the datasource ID for the sample to work.
    private const DATASOURCE = 'INSERT_DATASOURCE_ID';

    /**
     * A helper function to create the parent string.
     *
     * @param array $accountId
     *      The account that owns the product.
     *
     * @return string The parent has the format: `accounts/{account_id}`
     */
    private static function getParent($accountId)
    {
        return sprintf("accounts/%s", $accountId);
    }

    /**
     * Uploads a product input to your Merchant Center account. If an input
     * with the same feedLabel, contentLanguage, offerId, and dataSource
     * already exists, this method replaces that entry.
     *
     * After inserting, updating, or deleting a product input, it may take several
     * minutes before the processed product can be retrieved.
     *
     * @param array $config
     *      The configuration data used for authentication and getting the acccount
     *      ID.
     * @param string $dataSource
     *      The primary or supplemental product data source name. If the
     *      product already exists and data source provided is different, then the
     *      product will be moved to a new data source.
     *      Format: `accounts/{account}/dataSources/{datasource}`.
     *
     * @return void
     */
    public static function insertProductInputSample($config, $dataSource): void
    {

        // Gets the OAuth credentials to make the request.
        $credentials = Authentication::useServiceAccountOrTokenFile();

        // Creates options config containing credentials for the client to use.
        $options = ['credentials' => $credentials];

        // Creates a client.
        $productInputsServiceClient = new ProductInputsServiceClient($options);


        // Creates parent to identify where to insert the product.
        $parent = self::getParent($config['accountId']);

        // Calls the API and catches and prints any network failures/errors.
        try {

            // Price to be used for shipping ($33.45).
            $price = new Price(
                [
                    'amount_micros' => 33450000,
                    'currency_code' => 'USD'
                ]
            );

            $shipping = new Shipping(
                [
                    'price' => $price,
                    'country' => 'GB',
                    'service' => '1st class post'
                ]
            );

            $shipping2 = new Shipping(
                [
                    'price' => $price,
                    'country' => 'FR',
                    'service' => '1st class post'
                ]
            );

            // Creates the attributes of the product.
            $attributes = new ProductAttributes(
                [
                    'title' => 'A Tale of Two Cities',
                    'description' => 'A classic novel about the French Revolution',
                    'link' => 'https://exampleWebsite.com/tale-of-two-cities.html',
                    'image_link' =>
                        'https://exampleWebsite.com/tale-of-two-cities.jpg',
                    'availability' => Availability::IN_STOCK,
                    'condition' => Condition::PBNEW,
                    'google_product_category' => 'Media > Books',
                    'gtins' => ['9780007350896'],
                    'shipping' => [$shipping, $shipping2]
                ]
            );

            // Creates the productInput with the fundamental identifiers.
            $productInput = new ProductInput(
                [
                    'content_language' => 'en',
                    'feed_label' => 'label',
                    'offer_id' => 'sku123ABCD',
                    'product_attributes' => $attributes
                ]
            );

            // Prepares the request message.
            $request = new InsertProductInputRequest(
                [
                    'parent' => $parent,
                    'data_source' => $dataSource,
                    'product_input' => $productInput
                ]
            );

            print "Sending insert ProductInput request\n";
            $response = $productInputsServiceClient->insertProductInput($request);
            print "Inserted ProductInput Name below\n";
            print $response->getName() . "\n";
            print "Inserted Product Name below\n";
            print $response->getProduct() . "\n";
        } catch (ApiException $e) {
            print $e->getMessage();
        }
    }

    /**
     * Helper to execute the sample.
     *
     * @return void
     */
    public function callSample(): void
    {
        $config = Config::generateConfig();
        // Identifies the data source that will own the product input.
        $dataSource = sprintf(
            "accounts/%s/dataSources/%s",
            $config['accountId'],
            self::DATASOURCE
        );

        // Makes the call to insert a product to the MC account.
        self::insertProductInputSample($config, $dataSource);
    }
}


// Run the script
$sample = new InsertProductInput();
$sample->callSample();

Python

from examples.authentication import configuration
from examples.authentication import generate_user_credentials
from google.shopping import merchant_products_v1
from google.shopping.merchant_products_v1 import Availability
from google.shopping.merchant_products_v1 import Condition
from google.shopping.type import Price


def create_product_input():
  """Creates a `ProductInput` resource."""

  # Creates a shipping setting
  price = Price()
  price.amount_micros = 33_450_000
  price.currency_code = "GBP"

  shipping_option_1 = merchant_products_v1.Shipping()
  shipping_option_1.price = price
  shipping_option_1.country = "GB"
  shipping_option_1.service = "1st class post"

  price2 = Price()
  price2.amount_micros = 33_450_000
  price2.currency_code = "EUR"

  shipping_option_2 = merchant_products_v1.Shipping()
  shipping_option_2.price = price2
  shipping_option_2.country = "FR"
  shipping_option_2.service = "2nd class post"

  # Sets product attributes. Make sure to replace these values with your own.
  attributes = merchant_products_v1.ProductAttributes()
  attributes.title = "A Tale of Two Cities"
  attributes.description = "A classic novel about the French Revolution"
  attributes.link = "https://exampleWebsite.com/tale-of-two-cities.html"
  attributes.image_link = "https://exampleWebsite.com/tale-of-two-cities.jpg"
  attributes.price = price
  attributes.availability = Availability.IN_STOCK
  attributes.condition = Condition.NEW
  attributes.google_product_category = "Media > Books"
  attributes.gtins = ["9780007350896"]
  attributes.shipping = [shipping_option_1, shipping_option_2]

  return merchant_products_v1.ProductInput(
      content_language="en",
      feed_label="GB",
      offer_id="sku123",
      product_attributes=attributes,
  )


def insert_product_input(account_id: str, data_source: str):
  """Inserts the specified `ProductInput` resource.

  Args:
    account_id: The Merchant Center account ID.
    data_source: The resource name of the data source that will own the product
      input.

  Returns:
    The inserted `ProductInput` resource.
  """

  # Gets OAuth Credentials.
  credentials = generate_user_credentials.main()

  # Creates a client.
  client = merchant_products_v1.ProductInputsServiceClient(
      credentials=credentials
  )

  parent = f"accounts/{account_id}"

  # Creates the request.
  request = merchant_products_v1.InsertProductInputRequest(
      parent=parent,
      # If this product is already owned by another datasource, when
      # re-inserting, the new datasource will take ownership of the product.
      product_input=create_product_input(),
      data_source=data_source,
  )

  # Makes the request and catches and prints any error messages.
  try:
    response = client.insert_product_input(request=request)
    # The last part of the product name will be the product ID assigned to a
    # product by Google. Product ID has the format
    # `contentLanguage~feedLabel~offerId`
    print(f"Input successful: {response}")
    return response
  except RuntimeError as e:
    print("Input failed")
    print(e)
    # After the product is inserted, the product ID will be returned in the
    # response. We recommend that you check the Merchant Center to ensure that
    # the product is approved and visible to users before using the product ID
    # in any downstream processes.
    raise


if __name__ == "__main__":
  # Retrieves the Merchant Center account ID from the configuration file.
  merchant_account_id = configuration.Configuration().read_merchant_info()
  # Identifies the data source that will own the product input.
  # You can only insert products into datasource types of Input "API" and
  # "FILE", and of Type "Primary" or "Supplemental."
  target_data_source = (
      f"accounts/{merchant_account_id}/dataSources/[INSERT_DATA_SOURCE_HERE]"
  )

  insert_product_input(merchant_account_id, target_data_source)

Apps_Script


/**
 * Inserts a product into the products list. Logs the API response.
 */
function productInsert() {
  // IMPORTANT:
  // Enable the Merchant API Products sub-API Advanced Service and call it
  // "MerchantApiProducts"

  // Replace this with your Merchant Center ID.
  const accountId = 'INSERT_MERCHANT_ID';

  // Replace this with the Data Source ID you want to use.
  const dataSourceId = 'INSERT_DATASOURCE_ID';

  // Construct the parent name
  const parent = 'accounts/' + accountId;

  // Construct the Data Source name
  const dataSource = parent + '/dataSources/' + dataSourceId;

  // Create a product resource and insert it
  const productResource = {
    'offerId': 'fromAppsScript',
    'contentLanguage': 'en',
    'feedLabel': 'US',
    'productAttributes': {
      'title': 'A Tale of Two Cities',
      'description': 'A classic novel about the French Revolution',
      'link': 'http://my-book-shop.com/tale-of-two-cities.html',
      'imageLink': 'http://my-book-shop.com/tale-of-two-cities.jpg',
      'availability': 'IN_STOCK',
      'condition': 'new',
      'googleProductCategory': 'Media > Books',
      'gtins': '[9780007350896]',
      'price': {'amountMicros': '2500000', 'currencyCode': 'USD'},
    },
  };

  try {
    console.log('Sending insert ProductInput request');
    // Call the ProductInputs.insert API method.
    const response = MerchantApiProducts.Accounts.ProductInputs.insert(
        productResource, parent, {dataSource});
    // RESTful insert returns the JSON object as a response.
    console.log('Inserted ProductInput below');
    console.log(response);
  } catch (e) {
    console.log('ERROR!');
    console.log(e);
  }
}

cURL

curl -X POST \
"https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs:insert?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}" \
-H "Authorization: Bearer <API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
 "offerId": "SKU12345",
 "contentLanguage": "en",
 "feedLabel": "US",
 "productAttributes": {
   "title": "Classic Cotton T-Shirt",
   "description": "A comfortable, durable, and stylish t-shirt made from 100% cotton.",
   "link": "https://www.example.com/p/SKU12345",
   "imageLink": "https://www.example.com/img/SKU12345.jpg",
    "videoLinks": [
      "https://www.example.com/videos/SKU12345_1.mp4",
      "https://www.example.com/videos/SKU12345_2.mp4"
    ],
   "availability": "IN_STOCK",
   "price": {
     "amountMicros": "15990000",
     "currencyCode": "USD"
   },
   "condition": "NEW",
   "gtins": ["9780007350896"]
 }
}'

Dodawanie i aktualizowanie informacji o produktach za pomocą dodatkowego źródła danych

Użyj dodatkowego źródła danych, aby podać dodatkowe lub zastępujące dane produktów, które znajdują się już w podstawowym źródle danych. Jest to przydatne, gdy chcesz dodać informacje, takie jak promocje, etykiety własne, lub zastąpić określone dane produktów bez modyfikowania oryginalnych danych wejściowych produktu.

Aby to zrobić, użyj metody productInput.insert, ale w parametrze dataSource podaj name dodatkowego źródła danych. Sprawdź, czy offerId, contentLanguage i feedLabel pasują do istniejącego produktu.

W tym przykładzie dodajemy etykietę własną do dotychczasowego produktu za pomocą dodatkowego źródła danych.

POST https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs:insert?dataSource=accounts/{ACCOUNT_ID}/dataSources/{SUPPLEMENTAL_DATASOURCE_ID}
{
 "offerId": "SKU12345",
 "contentLanguage": "en",
 "feedLabel": "US",
 "productAttributes": {
   "customLabel0": "clearance-sale"
 }
}

Po tym wywołaniu ostateczny obiekt Product będzie miał właściwość customLabel0 ustawioną na clearance-sale, zakładając, że dodatkowe źródło danych ma wyższy priorytet niż podstawowe źródło danych w regułach pliku danych zdefiniowanych przez default_rule.

Dodawanie produktów asynchronicznie

Aby skutecznie przesłać dużą liczbę produktów, możesz wysłać wiele żądań wstawienia jednocześnie. Zamiast czekać na odpowiedź na każde żądanie przed wysłaniem kolejnego, możesz wysyłać je asynchronicznie i obsługiwać odpowiedzi w miarę ich napływania. Takie podejście może znacznie zwiększyć przepustowość przesyłania danych.

Poniższe przykłady kodu pokazują, jak asynchronicznie wstawiać produkty. Aby dowiedzieć się, jak wysyłać wiele żądań jednocześnie za pomocą curl, przeczytaj artykuł Wysyłanie wielu żądań jednocześnie.

.

Java

import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutureCallback;
import com.google.api.core.ApiFutures;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.api.gax.grpc.ChannelPoolSettings;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.shopping.merchant.products.v1.Availability;
import com.google.shopping.merchant.products.v1.Condition;
import com.google.shopping.merchant.products.v1.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1.ProductAttributes;
import com.google.shopping.merchant.products.v1.ProductInput;
import com.google.shopping.merchant.products.v1.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1.Shipping;
import com.google.shopping.type.Price;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/** This class demonstrates how to insert a product input */
public class InsertProductInputAsyncSample {

  private static String getParent(String accountId) {
    return String.format("accounts/%s", accountId);
  }

  private static String generateRandomString() {
    String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    Random random = new Random();
    StringBuilder sb = new StringBuilder(8);
    for (int i = 0; i < 8; i++) {
      sb.append(characters.charAt(random.nextInt(characters.length())));
    }
    return sb.toString();
  }

  private static ProductInput createRandomProduct() {
    Price price = Price.newBuilder().setAmountMicros(33_450_000).setCurrencyCode("USD").build();

    Shipping shipping =
        Shipping.newBuilder().setPrice(price).setCountry("GB").setService("1st class post").build();

    Shipping shipping2 =
        Shipping.newBuilder().setPrice(price).setCountry("FR").setService("1st class post").build();

    ProductAttributes attributes =
        ProductAttributes.newBuilder()
            .setTitle("A Tale of Two Cities")
            .setDescription("A classic novel about the French Revolution")
            .setLink("https://exampleWebsite.com/tale-of-two-cities.html")
            .setImageLink("https://exampleWebsite.com/tale-of-two-cities.jpg")
            .setAvailability(Availability.IN_STOCK)
            .setCondition(Condition.NEW)
            .setGoogleProductCategory("Media > Books")
            .addGtins("9780007350896")
            .addShipping(shipping)
            .addShipping(shipping2)
            .build();

    return ProductInput.newBuilder()
        .setContentLanguage("en")
        .setFeedLabel("CH")
        .setOfferId(generateRandomString())
        .setProductAttributes(attributes)
        .build();
  }

  public static void asyncInsertProductInput(Config config, String dataSource) throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Creates a channel provider. This provider manages a pool of gRPC channels
    // to enhance throughput for bulk operations. Each individual channel in the pool
    // can handle up to approximately 100 concurrent requests.
    //
    // Channel: A single connection pathway to the service.
    // Pool: A collection of multiple channels managed by this provider.
    //   Requests are distributed across the channels in the pool.
    //
    // We recommend estimating the number of concurrent requests you'll make, divide by 50 (50%
    // utilization of channel capacity), and set the pool size to that number.
    InstantiatingGrpcChannelProvider channelProvider =
        InstantiatingGrpcChannelProvider.newBuilder()
            .setChannelPoolSettings(ChannelPoolSettings.staticallySized(30))
            .build();

    // Creates service settings using the credentials retrieved above.
    ProductInputsServiceSettings productInputsServiceSettings =
        ProductInputsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .setTransportChannelProvider(channelProvider)
            .build();

    // Creates parent to identify where to insert the product.
    String parent = getParent(config.getAccountId().toString());

    // Calls the API and catches and prints any network failures/errors.
    try (ProductInputsServiceClient productInputsServiceClient =
        ProductInputsServiceClient.create(productInputsServiceSettings)) {

      // Creates five insert product input requests with random product IDs.
      List<InsertProductInputRequest> requests = new ArrayList<>(5);
      for (int i = 0; i < 5; i++) {
        InsertProductInputRequest request =
            InsertProductInputRequest.newBuilder()
                .setParent(parent)
                // You can only insert products into datasource types of Input "API", and of Type
                // "Primary" or "Supplemental."
                // This field takes the `name` field of the datasource.
                .setDataSource(dataSource)
                // If this product is already owned by another datasource, when re-inserting, the
                // new datasource will take ownership of the product.
                .setProductInput(createRandomProduct())
                .build();

        requests.add(request);
      }

      System.out.println("Sending insert product input requests");
      List<ApiFuture<ProductInput>> futures =
          requests.stream()
              .map(
                  request ->
                      productInputsServiceClient.insertProductInputCallable().futureCall(request))
              .collect(Collectors.toList());

      // Creates callback to handle the responses when all are ready.
      ApiFuture<List<ProductInput>> responses = ApiFutures.allAsList(futures);
      ApiFutures.addCallback(
          responses,
          new ApiFutureCallback<List<ProductInput>>() {
            @Override
            public void onSuccess(List<ProductInput> results) {
              System.out.println("Inserted products below");
              System.out.println(results);
            }

            @Override
            public void onFailure(Throwable throwable) {
              System.out.println(throwable);
            }
          },
          MoreExecutors.directExecutor());

    } catch (Exception e) {
      System.out.println(e);
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    // Identifies the data source that will own the product input.
    String dataSource = "accounts/" + config.getAccountId() + "/dataSources/{datasourceId}";

    asyncInsertProductInput(config, dataSource);
  }
}

Python

import asyncio
import os
import random
import string

from examples.authentication import configuration
from examples.authentication import generate_user_credentials
from google.shopping.merchant_products_v1 import Availability
from google.shopping.merchant_products_v1 import Condition
from google.shopping.merchant_products_v1 import InsertProductInputRequest
from google.shopping.merchant_products_v1 import ProductAttributes
from google.shopping.merchant_products_v1 import ProductInput
from google.shopping.merchant_products_v1 import ProductInputsServiceAsyncClient
from google.shopping.merchant_products_v1 import Shipping
from google.shopping.type import Price

# Enable gRPC connection scaling.
os.environ["GRPC_EXPERIMENTAL_MAX_CONCURRENT_STREAMS_CONNECTION_SCALING"] = (
    "true"
)
os.environ["GRPC_EXPERIMENTS"] = "subchannel_connection_scaling"

# Read merchant account information from the configuration file.
_ACCOUNT_ID = configuration.Configuration().read_merchant_info()
# The parent account for the product input.
# Format: accounts/{account}
_PARENT = f"accounts/{_ACCOUNT_ID}"


def _generate_random_string(length: int = 8) -> str:
  """Generates a random string of a given length."""
  characters = string.ascii_letters + string.digits
  return "".join(random.choice(characters) for _ in range(length))


def _create_random_product() -> ProductInput:
  """Creates a ProductInput with random elements and predefined attributes."""
  price = Price(amount_micros=33450000, currency_code="USD")

  shipping1 = Shipping(price=price, country="GB", service="1st class post")
  shipping2 = Shipping(price=price, country="FR", service="1st class post")

  attributes = ProductAttributes(
      title="A Tale of Two Cities",
      description="A classic novel about the French Revolution",
      link="https://exampleWebsite.com/tale-of-two-cities.html",
      image_link="https://exampleWebsite.com/tale-of-two-cities.jpg",
      availability=Availability.IN_STOCK,
      condition=Condition.NEW,
      google_product_category="Media > Books",
      gtins=["9780007350896"],
      shipping=[shipping1, shipping2],
  )

  return ProductInput(
      content_language="en",
      feed_label="CH",
      offer_id=_generate_random_string(),
      product_attributes=attributes,
  )


class ClientPool:
  """A simple client pool to distribute requests across multiple clients.

  This implements the Client Pool pattern to enhance throughput for bulk
  operations, mimicking channel pooling.
  """

  def __init__(self, size: int, credentials):
    self._pool = [
        ProductInputsServiceAsyncClient(credentials=credentials)
        for _ in range(size)
    ]
    self._size = size
    self._index = 0

  def get_client(self) -> ProductInputsServiceAsyncClient:
    """Returns the next client in the pool using round-robin."""
    client = self._pool[self._index]
    self._index = (self._index + 1) % self._size
    return client


async def async_insert_product_input(
    client: ProductInputsServiceAsyncClient, request: InsertProductInputRequest
):
  """Inserts product inputs.

  Args:
    client: The ProductInputsServiceAsyncClient to use.
    request: The InsertProductInputRequest to send.

  Returns:
    The response from the insert_product_input request.
  """
  return await client.insert_product_input(request=request)


async def main():
  # The ID of the data source that will own the product input.
  # This is a placeholder and should be replaced with an actual data source ID.
  datasource_id = "<INSERT_DATA_SOURCE_ID_HERE>"
  data_source_name = f"accounts/{_ACCOUNT_ID}/dataSources/{datasource_id}"

  # Gets OAuth Credentials.
  credentials = generate_user_credentials.main()

  # Creates a client pool with 30 clients to handle concurrent requests.
  # We recommend estimating the number of concurrent requests you'll make,
  # divide by 50 (50% utilization of channel capacity), and set the pool size to
  # that number.
  client_pool = ClientPool(size=30, credentials=credentials)

  tasks = []
  for _ in range(5):
    product_input = _create_random_product()
    request = InsertProductInputRequest(
        parent=_PARENT,
        data_source=data_source_name,
        product_input=product_input,
    )

    # Get a client from the pool and create the async task
    client = client_pool.get_client()
    insert_product_task = asyncio.create_task(
        async_insert_product_input(client, request)
    )
    tasks.append(insert_product_task)

  print("Sending insert product input requests")

  try:
    # Await all tasks to complete concurrently and gather their results
    results = await asyncio.gather(*tasks)
    print("Inserted products below")
    print(results)
  except RuntimeError as e:
    # Catch and print any exceptions that occur during the API calls.
    print(e)


if __name__ == "__main__":
  asyncio.run(main())

Dodawanie produktów kierowanych na konkretne kraje

Możesz ustawić kierowanie na kraj dla poszczególnych produktów, aby zastąpić ustawienia ze źródła danych lub kierować produkty, gdy w źródle danych nie ma zdefiniowanych krajów.

Kraje docelowe z atrybutem shipping

Jeśli w źródle danych nie masz zdefiniowanych konkretnych krajów, możesz kierować produkty na kraje, podając pole shipping w productAttributes. To pole umożliwia określenie kosztów dostawy i reguł dla różnych krajów, co oznacza, że reklamy będą wyświetlane w tych krajach.

W tym przykładzie produkt jest kierowany na Stany Zjednoczone i Kanadę przez podanie 2 osobnych wpisów shipping.

POST https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs:insert?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}
{
 "offerId": "SKU_SHIP_TARGET",
 "contentLanguage": "en",
 "feedLabel": "GLOBAL",
 "productAttributes": {
   "title": "Global T-Shirt",
   "link": "https://www.example.com/p/SKU_SHIP_TARGET",
   "imageLink": "https://www.example.com/img/SKU_SHIP_TARGET.jpg",
   "availability": "IN_STOCK",
   "price": {
     "amountMicros": "25990000",
     "currencyCode": "USD"
   },
   "shipping": [
     {
       "country": "US",
       "price": {
         "amountMicros": "5990000",
         "currencyCode": "USD"
       }
     },
     {
       "country": "CA",
       "price": {
         "amountMicros": "10990000",
         "currencyCode": "CAD"
       }
     }
   ]
 }
}

Wykluczanie krajów i miejsc docelowych

Jeśli źródło danych jest już kierowane na wiele krajów, możesz wykluczyć wyświetlanie produktu w niektórych z tych krajów lub w określonych miejscach docelowych.

  • Użyj atrybutu shoppingAdsExcludedCountries, aby zapobiec wyświetlaniu produktu w reklamach produktowych w określonych krajach.
  • Użyj atrybutu excludedDestinations, aby zapobiec wyświetlaniu produktu w ramach określonych metod marketingowych, takich jak FreeListings.

W tym przykładzie zakładamy, że źródło danych jest kierowane na Stany Zjednoczone, Kanadę i Meksyk. Żądanie wyklucza produkt z reklam produktowych w Meksyku i całkowicie z bezpłatnych informacji.

POST https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs:insert?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}
{
  "offerId": "SKU_EXCLUDE_TARGET",
  "contentLanguage": "en",
  "feedLabel": "NA",
  "productAttributes": {
    "title": "North America T-Shirt",
    "link": "https://www.example.com/p/SKU_EXCLUDE_TARGET",
    "imageLink": "https://www.example.com/img/SKU_EXCLUDE_TARGET.jpg",
    "availability": "IN_STOCK",
    "price": {
      "amountMicros": "19990000",
      "currencyCode": "USD"
    },
    "shoppingAdsExcludedCountries": ["MX"],
    "excludedDestinations": ["FREE_LISTINGS"]
  }
}

Produkty kierowane na konkretne miejsca docelowe

Możesz użyć jednego produktu, aby kierować reklamy zarówno na typy miejsc docelowych online, jak i lokalne. Ta funkcja pozwala wykorzystać strategię wielokanałową w zakupach.

Kierowanie produktu możesz kontrolować za pomocą:

  • konfigurację źródła danych,
  • konfiguracja na poziomie poszczególnych produktów,

Wszystkie miejsca docelowe

Domyślne kierowanie produktów obsługuje wszystkie miejsca docelowe, podobnie jak domyślne kierowanie źródeł danych, w zależności od udziału w programie.

Tylko online lub lokalnie

Jeśli chcesz, aby produkt był dostępny wyłącznie w kanałach online lub tylko w sklepach stacjonarnych:

  • Poziom źródła danych: ustaw miejsca docelowe (znane też jako metody marketingowe) źródła danych na tylko online lub tylko lokalne. Na przykład reklamy lokalnego asortymentu produktów i bezpłatne lokalne informacje to lokalne miejsca docelowe. Więcej informacji o tym, jak i gdzie Twoje produkty są wyświetlane potencjalnym klientom w Google, znajdziesz w artykułach Czym są metody marketingowe? i Reklamy lokalnego asortymentu produktów i bezpłatne lokalne informacje.
  • Na poziomie produktu: niezależnie od konfiguracji źródła danych możesz kierować reklamy na określone miejsca docelowe na poziomie produktu. Ustaw includedDestinations na miejsca docelowe online lub lokalne. Możesz też użyć właściwości excludedDestinations, aby określić, na które miejsca docelowe nie chcesz kierować reklam. Możesz na przykład użyć atrybutu excludedDestinations, aby zapobiec wyświetlaniu produktu online w miejscach docelowych lokalnie.
  • Informacje o produktach dostępnych lokalnie w sklepie: jeśli kierujesz niektóre produkty na lokalne typy miejsc docelowych, musisz podać informacje o tych produktach w sklepie. Więcej informacji o dodawaniu informacji o sklepie do produktów dostępnych lokalnie znajdziesz w artykule Wstawianie informacji o sklepie.

Uzyskiwanie informacji o produkcie

Aby pobrać ostateczny stan przetworzonego produktu, użyj metody products.get. Ta metoda zwraca zasób Product, który zawiera wszystkie productAttributes po zastosowaniu reguł pliku danych i dodatkowych źródeł danych, wraz z bieżącym stanem weryfikacji.

Od momentu wstawienia lub zaktualizowania elementu ProductInput do momentu, gdy ostateczny element Product będzie dostępny do pobrania, może minąć kilka minut.

GET https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/products/{PRODUCT_ID}

Pomyślne żądanie zwraca zasób Product.

{
 "name": "accounts/{ACCOUNT_ID}/products/{PRODUCT_ID}}",
 "offerId": "SKU12345",
 "contentLanguage": "en",
 "feedLabel": "US",
 "dataSource": "accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}",
 "productAttributes": {
   "title": "Classic Cotton T-Shirt",
   "description": "A comfortable, durable, and stylish t-shirt made from 100% cotton.",
   "link": "https://www.example.com/p/SKU12345",
   "imageLink": "https://www.example.com/img/SKU12345.jpg",
   "availability": "IN_STOCK",
   "price": {
     "amountMicros": "15990000",
     "currencyCode": "USD"
   },
   "condition": "NEW",
   "gtins": [
     "9780007350896"
   ]
 },
 "productStatus": {
   "destinationStatuses": [
     {
       "reportingContext": "SHOPPING_ADS",
       "approvedCountries": [
         "US"
       ]
     }
   ],
   "creationDate": "2024-05-20T10:00:00Z",
   "lastUpdateDate": "2024-05-20T10:05:00Z",
   "googleExpirationDate": "2024-06-19T10:05:00Z"
 }
}

Poniższe przykłady kodu pokazują, jak pobrać produkt.

Java


import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.io.BaseEncoding;
import com.google.shopping.merchant.products.v1.GetProductRequest;
import com.google.shopping.merchant.products.v1.Product;
import com.google.shopping.merchant.products.v1.ProductsServiceClient;
import com.google.shopping.merchant.products.v1.ProductsServiceSettings;
import java.nio.charset.StandardCharsets;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/** This class demonstrates how to get a single product for a given Merchant Center account */
public class GetProductSample {

  // Base64Url encoder/decoder without padding
  private static final BaseEncoding BASE64URL_NOPADDING = BaseEncoding.base64Url().omitPadding();

  // Encodes a string to base64url without padding
  public static String encodeProductId(String productId) {
    return BASE64URL_NOPADDING.encode(productId.getBytes(StandardCharsets.UTF_8));
  }

  public static Product getProduct(Config config, String accountId, String productId)
      throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Creates service settings using the credentials retrieved above.
    ProductsServiceSettings productsServiceSettings =
        ProductsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .build();

    try (ProductsServiceClient productsServiceClient =
        ProductsServiceClient.create(productsServiceSettings)) {

      // The name has the format: accounts/{account}/products/{productId}
      String name = "accounts/" + accountId + "/products/" + productId;

      // The name has the format: accounts/{account}/products/{productId}
      GetProductRequest request = GetProductRequest.newBuilder().setName(name).build();

      System.out.println("Sending get product request:");
      Product response = productsServiceClient.getProduct(request);

      System.out.println("Retrieved Product below");
      System.out.println(response);
      return response;
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    String accountId = config.getAccountId().toString();

    // The name of the `product`, returned after a `Product.insert` request. We recommend
    // having stored this value in your database to use for all future requests.
    String productId = "en~GB~sku123"; // Replace with your actual product ID

    // Uncomment the following line if the product name contains special characters (such as forward
    // slashes) and needs base64url encoding.
    // productId = encodeProductId(productId);

    getProduct(config, accountId, productId);
  }
}

PHP

require_once __DIR__ . '/../../../vendor/autoload.php';
require_once __DIR__ . '/../../Authentication/Authentication.php';
require_once __DIR__ . '/../../Authentication/Config.php';

use Google\ApiCore\ApiException;
use Google\Shopping\Merchant\Products\V1\Client\ProductsServiceClient;
use Google\Shopping\Merchant\Products\V1\GetProductRequest;

/**
 * This class demonstrates how to get a single product for a given Merchant
 * Center account.
 */
class GetProductSample
{
    /**
     * A helper function to create the product name string.
     *
     * @param string $accountId
     *      The account that owns the product.
     * @param string $productId
     *      The ID of the product.
     *
     * @return string The name has the format: `accounts/{account}/products/{product}`
     */
    private static function getName(string $accountId, string $productId): string
    {
        return sprintf("accounts/%s/products/%s", $accountId, $productId);
    }

    /**
     * Encodes a string to base64url without padding. This is needed if the
     * product ID contains special characters (such as forward slashes) and
     * needs base64url encoding.
     *
     * @param string $productId
     *      The ID of the product.
     *
     * @return string The encoded product ID.
     */
    public static function encodeProductId(string $productId): string
    {
        return rtrim(strtr(base64_encode($productId), '+/', '-_'), '=');
    }

    /**
     * Retrieves a product from your Merchant Center account.
     *
     * @param array $config
     *      The configuration data used for authentication and getting the
     *      account ID.
     * @param string $productId
     *      The ID of the product, in the form of
     *      `contentLanguage~feedLabel~offerId`.
     *
     * @return void
     */
    public static function getProduct(array $config, string $productId): void
    {
        // Gets the OAuth credentials to make the request.
        $credentials = Authentication::useServiceAccountOrTokenFile();

        // Creates options config containing credentials for the client to use.
        $options = ['credentials' => $credentials];

        // Creates a client.
        $productsServiceClient = new ProductsServiceClient($options);

        // The name has the format: accounts/{account}/products/{productId}
        $name = self::getName($config['accountId'], $productId);

        // Creates the request.
        $request = new GetProductRequest([
            'name' => $name
        ]);

        // Calls the API and catches and prints any network failures/errors.
        try {
            print "Sending get product request:\n";
            $response = $productsServiceClient->getProduct($request);
            print "Retrieved Product below\n";
            // Pretty-prints the JSON representation of the response.
            print $response->serializeToJsonString(true) . "\n";
        } catch (ApiException $e) {
            printf("Call failed with message: %s\n", $e->getMessage());
        }
    }

    /**
     * Helper to execute the sample.
     *
     * @return void
     */
    public function callSample(): void
    {
        $config = Config::generateConfig();

        // The name of the `product`, returned after a `Product.insert` request.
        // We recommend having stored this value in your database to use for all
        // future requests.
        $productId = 'en~US~sku123'; // Replace with your actual product ID

        // Uncomment the following line if the product name contains special
        // characters (such as forward slashes) and needs base64url encoding.
        // $productId = self::encodeProductId($productId);

        self::getProduct($config, $productId);
    }
}

// Runs the sample.
$sample = new GetProductSample();
$sample->callSample();

Python

import base64

from examples.authentication import configuration
from examples.authentication import generate_user_credentials
from google.shopping.merchant_products_v1 import GetProductRequest
from google.shopping.merchant_products_v1 import Product
from google.shopping.merchant_products_v1 import ProductsServiceClient


# This is needed for base64url encoding if product IDs contain special
# characters such as forward slashes.
def encode_product_id(product_id_to_encode: str) -> str:
  """Base64url encodes a string without padding.

  Args:
    product_id_to_encode: The product ID string to encode.

  Returns:
    The encoded product ID string.
  """
  encoded_bytes = base64.urlsafe_b64encode(product_id_to_encode.encode("utf-8"))
  return encoded_bytes.rstrip(b"=").decode("utf-8")


def get_product(account_id_arg: str, product_id_arg: str) -> Product:
  """Retrieves a single product from a Merchant Center account.

  Args:
    account_id_arg: The ID of the Merchant Center account.
    product_id_arg: The ID of the product to retrieve.

  Returns:
    The retrieved `Product` resource.
  """
  # Gets OAuth Credentials.
  credentials = generate_user_credentials.main()

  # Creates a client.
  client = ProductsServiceClient(credentials=credentials)

  # The name has the format: accounts/{account}/products/{product}
  name = f"accounts/{account_id_arg}/products/{product_id_arg}"

  # Creates the request.
  request = GetProductRequest(name=name)

  print("Sending get product request:")

  # Makes the request and catches and prints any error messages.
  try:
    response = client.get_product(request=request)
    print("Retrieved Product below")
    print(response)
    return response
  except RuntimeError as e:
    print(e)
    raise


if __name__ == "__main__":
  # Retrieves the configured account ID from the config file.
  account_id = configuration.Configuration().read_merchant_info()

  # The ID of the product, which is the final component of the product's
  # resource name. The product ID is the same as the offer ID.
  # For example, `en~US~sku123`.
  product_id = "en~US~sku123"  # Replace with your actual product ID.

  # Uncomment the following line if the product ID contains special characters
  # (such as forward slashes) and needs base64url encoding.
  # product_id = encode_product_id(product_id)

  get_product(account_id, product_id)


Apps_Script

/**
 * Get a specific product for a given Merchant Center account.
 */
function getProduct() {
  // IMPORTANT:
  // Enable the Merchant API Products sub-API Advanced Service and call it
  // "MerchantApiProducts"

  // Replace this with your Merchant Center ID.
  const accountId = '<MERCHANT_CENTER_ID>';

  // The ID of the product to retrieve.
  // This ID is assigned by Google and typically follows the format:
  // contentLanguage~feedLabel~offerId
  // Replace with an actual product ID from your Merchant Center account.
  const productId = '<PRODUCT_ID>';

  // Construct the parent name
  const parent = 'accounts/' + accountId;

  // Construct the product resource name
  const name = parent + '/products/' + productId;

  try {
    console.log('Sending get Product request');
    // Call the Products.get API method.
    const product = MerchantApiProducts.Accounts.Products.get(name);
    console.log(product);
  } catch (e) {
    console.log('ERROR!');
    console.log(e);
  }
}

cURL

curl -X GET \
"https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/products/{PRODUCT_ID}" \
-H "Authorization: Bearer <API_TOKEN>"

Usuwanie produktu ze źródła danych

Aby usunąć dane wejściowe produktu z konkretnego źródła danych, użyj metody productInputs.delete.

  • Jeśli usuniesz produkt z podstawowego źródła danych, cały produkt wraz z dodatkowym productInputs zostanie usunięty z Merchant Center.
  • Jeśli usuniesz produkt z dodatkowego źródła danych, usunięte zostaną tylko atrybuty z tego źródła danych. Sam produkt pozostanie, a jego dane będą pochodzić z podstawowego i innych dodatkowych źródeł danych.

Musisz podać dataSource, z którego usuwasz dane wejściowe produktu.

DELETE https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs/{PRODUCT_ID}?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}

Udane wywołanie zwraca pustą odpowiedź.

Poniższe przykłady kodu pokazują, jak usunąć produkt.

Java

import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.shopping.merchant.products.v1.DeleteProductInputRequest;
import com.google.shopping.merchant.products.v1.ProductInputName;
import com.google.shopping.merchant.products.v1.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1.ProductInputsServiceSettings;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/** This class demonstrates how to delete a product for a given Merchant Center account */
public class DeleteProductInputSample {

  public static void deleteProductInput(Config config, String productId, String dataSource)
      throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Creates service settings using the credentials retrieved above.
    ProductInputsServiceSettings productInputsServiceSettings =
        ProductInputsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .build();

    // Creates product name to identify product.
    String name =
        ProductInputName.newBuilder()
            .setAccount(config.getAccountId().toString())
            .setProductinput(productId)
            .build()
            .toString();

    // Calls the API and catches and prints any network failures/errors.
    try (ProductInputsServiceClient productInputsServiceClient =
        ProductInputsServiceClient.create(productInputsServiceSettings)) {
      DeleteProductInputRequest request =
          DeleteProductInputRequest.newBuilder().setName(name).setDataSource(dataSource).build();

      System.out.println("Sending deleteProductInput request");
      productInputsServiceClient.deleteProductInput(request); // no response returned on success
      System.out.println(
          "Delete successful, note that it may take a few minutes for the delete to update in"
              + " the system. If you make a products.get or products.list request before a few"
              + " minutes have passed, the old product data may be returned.");
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    // An ID assigned to a product input by Google. In the format
    // contentLanguage~feedLabel~offerId
    String productId = "en~GB~sku123";

    // The name of the dataSource from which to delete the product. If it is a primary feed, this
    // will delete the product completely. If it's a supplemental feed, it will only delete the
    // product information from that feed, but the product will still be available from the primary
    // feed.
    String dataSource = "accounts/{account}/dataSources/{dataSource}";

    deleteProductInput(config, productId, dataSource);
  }
}

PHP

use Google\ApiCore\ApiException;
use Google\Auth\CredentialsLoader;
use Google\Shopping\Merchant\Products\V1\Client\ProductInputsServiceClient;
use Google\Shopping\Merchant\Products\V1\DeleteProductInputRequest;
use Google\Shopping\Merchant\Products\V1\ProductInputName;

/**
 * This class demonstrates how to delete a productinput for a given Merchant Center
 * account.
 */

class DeleteProductInput
{

    // ENSURE you fill in the product and datasource ID for the sample to work.
    // An ID assigned to a product by Google:
    // In the format `contentLanguage~feedLabel~offerId`
    private const PRODUCT = 'INSERT_PRODUCT_ID_HERE';
    private const DATASOURCE = 'INSERT_DATASOURCE_ID_HERE';

    /**
     * Deletes a product input to your Merchant Center account.
     *
     * @param array  $config
     *      The configuration data used for authentication and getting the
     *      acccount ID.
     * @param string $product
     *      The product ID to delete.
     *      Format: `accounts/{account}/products/{productId}`.
     * @param string $dataSource
     *      The primary or supplemental product data source name that owns the
     *      product.
     *      Format: `accounts/{account}/dataSources/{datasource}`.
     *
     * @return void
     */
    public static function deleteProductInputSample(
        $config, $product, $dataSource
    ): void {
        // Obtains OAuth token based on the user's configuration.
        $credentials = Authentication::useServiceAccountOrTokenFile();

        // Creates service settings using the credentials retrieved above.
        $options = ['credentials' => $credentials];

        $productInputsServiceClient = new ProductInputsServiceClient($options);

        // Calls the API and catches and prints any network failures/errors.
        try {

            $request = new DeleteProductInputRequest(
                [
                    'name' => $product,
                    'data_source' => $dataSource
                ]
            );

            echo "Sending deleteProductInput request\n";
            $productInputsServiceClient->deleteProductInput($request);
            echo "Delete successful, note that it may take a few minutes for the "
            . "delete to update in the system. If you make a products.get or "
            . "products.list request before a few  minutes have passed, the old "
            . "product data may be returned.\n";
        } catch (ApiException $e) {
            echo "An error has occurred: \n";
            echo $e->getMessage() . "\n";
        }
    }

    /**
     * Helper to execute the sample.
     *
     * @return void
     */
    public function callSample(): void
    {
        $config = Config::generateConfig();

        // The productID variable is defined at the top of the file.
        $product = ProductInputsServiceClient::productInputName(
            $config['accountId'],
            self::PRODUCT
        );

        // The name of the dataSource from which to delete the product.
        $dataSource = sprintf(
            'accounts/%s/dataSources/%s',
            $config['accountId'],
            self::DATASOURCE
        );
        self::deleteProductInputSample($config, $product, $dataSource);
    }
}


// Run the script.
$sample = new DeleteProductInput();
$sample->callSample();

Python

from examples.authentication import configuration
from examples.authentication import generate_user_credentials
from google.shopping import merchant_products_v1


def delete_product_input(account_id: str, product_id: str, data_source: str):
  """Deletes the specified `ProductInput` resource.

  Args:
    account_id: The Merchant Center account ID.
    product_id: The ID of the product input to delete, in the format
      `contentLanguage~feedLabel~offerId`.
    data_source: The resource name of the data source from which to delete the
      product.
  """

  # Gets OAuth Credentials.
  credentials = generate_user_credentials.main()

  # Creates a client.
  client = merchant_products_v1.ProductInputsServiceClient(
      credentials=credentials
  )

  name = f"accounts/{account_id}/productInputs/{product_id}"

  # Creates the request.
  request = merchant_products_v1.DeleteProductInputRequest(
      name=name, data_source=data_source
  )

  # Makes the request and catch and print any error messages.
  try:
    client.delete_product_input(request=request)
    print("Deletion successful")
  except RuntimeError as e:
    print("Deletion failed")
    print(e)
    raise


if __name__ == "__main__":
  # Retrieves the Merchant Center account ID from the configuration file.
  merchant_account_id = configuration.Configuration().read_merchant_info()

  # ENSURE you fill in the product ID and data source for the
  # sample to work.
  # In the format of `contentLanguage~feedLabel~offerId`
  target_product = "[INSERT_PRODUCT_HERE]"
  target_data_source = (
      f"accounts/{merchant_account_id}/dataSources/[INSERT_DATA_SOURCE_HERE]"
  )

  delete_product_input(
      merchant_account_id, target_product, target_data_source
  )

cURL

curl -X DELETE \
"https://merchantapi.googleapis.com/products/v1/accounts/{ACCOUNT_ID}/productInputs/{PRODUCT_ID}?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}" \
-H "Authorization: Bearer <API_TOKEN>"