نقل البيانات من Content API for Shopping إلى Merchant API

يشرح هذا الدليل عملية نقل البيانات من Content API for Shopping إلى Merchant API لإدارة بيانات النشاط الإعلاني.

يمكنك استخدام هذا الدليل لنقل بياناتك من Content API for Shopping إلى Merchant API. لمزيد من المعلومات حول تفاصيل Merchant API وواجهات برمجة التطبيقات الفرعية، يُرجى الاطّلاع على تصميم Merchant API.

البدء

لبدء استخدام Merchant API، غيِّر عناوين URL لطلباتك إلى التنسيق التالي:

https://merchantapi.googleapis.com/{SUB_API}/{VERSION}/{RESOURCE_NAME}:{METHOD}…

لاستخدام Merchant API، يجب ربط حسابك على Merchant Center بمشروعك على Google Cloud باستخدام طريقة "تسجيل المطوّر"، وذلك على النحو التالي:

POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/developerRegistration:registerGcp

{
  developer_email:"example-email@example.com"
}

لمزيد من المعلومات، يُرجى الاطّلاع على دليل البدء السريع ومرجع Merchant API.

التحسينات مقارنةً بـ Content API for Shopping

تتيح لك Merchant API أتمتة وتبسيط سير العمل في Merchant Center، كما توفّر إمكانات محسّنة مقارنةً بـ Content API for Shopping.

أبرز حالات الاستخدام:

  • إدارة الحسابات المبرمَجة
  • إدارة المنتجات المبرمَجة
  • نظام إدارة المخزون المبرمَج
  • إعداد التقارير المخصّصة

مجالات التحسين الرئيسية:

التغييرات التي أُجريت

  • تمت زيادة الحد الأقصى لـ pageSize من 250 إلى 1000 صف لكل طلب بيانات من واجهة برمجة التطبيقات.
  • تم إصلاح مشكلة التأخير في إدراج المنتجات والعروض الترويجية ومراجعات المنتجات ومراجعات التجّار بعد إنشاء DataSources.
  • إطلاق تعريف معدَّل لـ clickPotentialRank في جدول productView ضمن واجهة Reporting sub-API:
    • يتم ترتيب المنتجات استنادًا إلى clickPotential بقيم تتراوح بين 1 و1000.
  • يتيح لك الحقل AccountIdAlias في المورد AccountRelationship إدارة هياكل الحسابات المعقّدة بشكل أفضل. على سبيل المثال، تستخدم الأسواق اسمًا مستعارًا يحدّده المستخدم بدلاً من رقم التعريف الداخلي للتاجر، مثل رقم تعريف الحساب.

دعم gRPC

تتوافق Merchant API مع gRPC وREST. يمكنك استخدام gRPC في Merchant API وREST في Content API for Shopping في الوقت نفسه.

تتطلّب مكتبات العملاء في Merchant API استخدام gRPC.

لمزيد من المعلومات، يُرجى الاطّلاع على نظرة عامة على gRPC.

التوافق

يصف هذا الدليل التغييرات العامة التي تنطبق على Merchant API بالكامل.

تم تصميم Merchant API للعمل مع ميزات Content API for Shopping الحالية.

على سبيل المثال، يمكنك استخدام Merchant Inventories API إلى جانب عملية تنفيذ الإصدار 2.1 من Content API for Shopping products الحالية. يمكنك استخدام Content API for Shopping من أجل تحميل منتج محلي جديد (تبيعه في متجر محلي)، ثم استخدام Merchant Inventories API LocalInventory لإدارة معلومات ذلك المنتج في المتجر.

تحسينات هيكلية مقارنةً بـ Content API

تتفوّق Merchant API على Content API في المجالات التالية:

لنتعرّف على هذه التغييرات بمزيد من التفصيل.

الإصدارات وواجهات برمجة التطبيقات الفرعية

توفّر Merchant API مفاهيم تحديد الإصدارات وواجهات برمجة التطبيقات الفرعية. ويعمل تصميمها المعياري على تحسين سهولة الاستخدام، من خلال السماح لك بالتركيز على واجهات برمجة التطبيقات الفرعية التي تحتاجها وتمكين عمليات نقل أسهل في المستقبل إلى الإصدارات الأحدث. سيتم تطبيق الإصدارات مع عناوين URL للطلبات. وتتشابه الاستراتيجية مع تجربة Google Ads API.

طلبات أكثر فعالية

تتطلّب طلبات عناوين URL في Merchant API المزيد من المَعلمات لاستدعاء Merchant API. ويشمل ذلك المورد والإصدار والاسم (المعرّفات) والطريقة (الطرق غير العادية). لمزيد من المعلومات حول هذا الموضوع، يُرجى الاطّلاع على معرّفات الحسابات والمنتجات والأمثلة.

مبادئ AIP للمعرّفات

تستخدم Content API for Shopping أرقام تعريف لتحديد الموارد (على سبيل المثال، merchantId وproductId)، بينما تستخدم Merchant API معرّف name للتوافق مع AIP (يُرجى الاطّلاع على مبادئ تحسين واجهة برمجة التطبيقات).

يتضمّن المعرّف {name} معرّف المورد وحسابه الرئيسي (أو حساباته الرئيسية المتعددة المحتملة)، بحيث يساوي {name} accounts/{account}/products/{product}

تعرض جميع طلبات القراءة والكتابة الحقل name كمعرّف المورد.

يتضمّن {name} أيضًا معرّفَي المجموعة accounts/ وproducts/.

تستخدم Merchant API السمة {account} للإشارة إلى معرّف Merchant Center و{product} للإشارة إلى معرّفات المنتجات.

على سبيل المثال، يمكنك تنفيذ طريقة getName() لاسترداد name من مورد، وتخزين الناتج كمتغيّر بدلاً من إنشاء name من معرّفات التاجر والموارد بنفسك.

في ما يلي مثال على كيفية استخدام حقل name في طلباتك:

   POST https://merchantapi.googleapis.com/inventories/v1/{PARENT}/regionalInventories:insert

يعرض الجدول كيفية تغيُّر طلب products.get في Content API for Shopping:

واجهة برمجة تطبيقات المحتوى في Shopping Merchant API
GET https://shoppingcontent.googleapis.com/content/v2.1/{merchantId}/products/{productId} GET https://merchantapi.googleapis.com/products/v1/{name}

لمزيد من التفاصيل، يُرجى مراجعة التغييرات في المعرّفات.

على سبيل المثال، لاسترداد منتج يحمل المعرّف en~US~1234 من معرّف Merchant Center‏ 4321 باستخدام Merchant API، يكون الطلب على النحو التالي:

    GET
    https://merchantapi.googleapis.com/products/v1/accounts/4321/products/en~US~1234

حيث يساوي {name} accounts/4321/products/en~US~1234. يتم عرض حقل الاسم الجديد هذا كمعرّف المورد لجميع طلبات القراءة والكتابة في Merchant API.

في Content API for Shopping، تشير النقطتان الرأسيتان (:) إلى محدّد في اسم المنتج، بينما في Merchant API، تؤدي علامة التلدة (~) هذه الوظيفة. لا يحتوي معرّف Merchant API على الجزء channel.

على سبيل المثال، معرّف المنتج في Content API for Shopping:

channel:contentLanguage:feedLabel:offerId.

في Merchant API على النحو التالي:

contentLanguage~feedLabel~offerId.

حقول الموارد الرئيسية للموارد الفرعية

في Merchant API، تحتوي جميع الموارد الفرعية على الحقل parent. يمكنك استخدام الحقل parent لتحديد {name} المرجع الذي تريد إدراج العنصر الفرعي فيه، بدلاً من تمرير المرجع الرئيسي بالكامل. يمكنك أيضًا استخدام الحقل parent مع list

على سبيل المثال، لإدراج المستودعات المحلية لمنتج معيّن، حدِّد name المنتج في حقل parent لطريقة list. في هذه الحالة، يكون product المحدّد هو parent لموارد LocalInventory التي تم عرضها.

    GET
    https://merchantapi.googleapis.com/inventories/v1/{parent}/localInventories

لاسترداد جميع المستودعات المحلية للمنتج en~US~1234 والحساب 4321، سيبدو الطلب على النحو التالي:

    GET
    https://merchantapi.googleapis.com/inventories/v1/accounts/4321/products/en~US~1234/localInventories

العنصر الرئيسي هو accounts/{account}/products/{product}. يُرجى العِلم أنّه في هذه الحالة، يتضمّن مورد localInventories عنصرَين رئيسيَين في معرّف الاسم (accounts/ وproducts/)، لأنّ الحساب هو العنصر الرئيسي لمورد المنتج.

التعدادات الشائعة

يوفّر استخدام التعدادات الشائعة المزيد من الاتساق.

يحدّد الحقل Destination.DestinationEnum مساحات العرض التي ستظهر فيها مواردك. تدرج السمة DestinationEnum جميع القيم المتاحة لاستهداف الوجهات، وهي موحّدة في جميع واجهات برمجة التطبيقات الفرعية، مثل سمات العروض الترويجية.

يمثّل الحقل ReportingContext.ReportingContextEnum السياق الذي تنطبق عليه مشاكل حسابك ومنتجاتك. يُستخدَم هذا الحقل في جميع طرق إعداد التقارير (على سبيل المثال، في IssueSeverityPerReportingContext).

التوافق مع الأنظمة القديمة

عند بدء استخدام Merchant API، سيستمر تكامل Content API for Shopping الحالي في العمل بدون انقطاع. لمزيد من المعلومات، يُرجى الاطّلاع على التوافق.

بعد نقل واجهات برمجة التطبيقات الفرعية إلى Merchant API، ننصحك باستخدام Merchant API فقط لواجهات برمجة التطبيقات الفرعية التي تم نقلها.

توفُّر استدعاء إجراء عن بُعد (gRPC)

‫gRPC هي الطريقة الجديدة المقترَحة للربط بواجهة Merchant API.

تشمل مزاياه ما يلي:

تحويل المعالجة المجمّعة المخصّصة إلى معالجة مجمّعة مدمجة

تكون المعالجة المجمّعة أكثر كفاءة عند استخدام طلبات غير متزامنة. يمكنك الاطّلاع على مزيد من المعلومات حول استخدام الطلبات الموازية لإجراء تجميع في Merchant API وكيفية إعادة هيكلة الرمز البرمجي للطلبات المتزامنة.

للمساعدة في تسريع عملية نقل البيانات، ننصحك باستخدام مكتبات العملاء.

لا تتيح Merchant API استخدام طريقة customBatch المتوفّرة في Content API for Shopping. بدلاً من ذلك، يمكنك الاطّلاع على إرسال طلبات متعددة في آنٍ واحد أو تنفيذ طلباتك بشكل غير متزامن.

يوضّح نموذج 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);
  }
}

إذا كنت تستخدم customBatch في Content API، وتحتاج إلى هذه الميزة في Merchant API، يُرجى إعلامنا بالسبب في ملاحظاتك.

الميزات الحصرية

ستظهر الميزات المستقبلية في Merchant API فقط. (ستكون هناك بعض الاستثناءات، مثل مواصفات الخلاصة السنوية لعام 2025).

تشمل الميزات الحصرية في Merchant API ما يلي:

  • Reviews API استخدِم "المراجعات" لتطبيق وإدارة تقييمات منتجاتك ومتجرك. لمزيد من المعلومات، يُرجى الاطّلاع على مراجعات البائعين ومراجعات المنتجات.
  • الإشعارات: يمكنك الاشتراك لتلقّي إشعارات فورية بشأن التغييرات في بيانات الحساب والمنتجات.

السعر

في ما يلي التغييرات التي تم إجراؤها على Price في حزمة Merchant Common:

واجهة برمجة تطبيقات المحتوى في Shopping Merchant API
حقل المبلغ value:string amountMicros:int64
حقل العملة currency:string currencyCode:string

يتم الآن تسجيل مبلغ Price بوحدات ميكرو، حيث يساوي مليون وحدة ميكرو الوحدة العادية لعملتك.

في Content API for Shopping، كانت السمة Price عبارة عن رقم عشري على شكل سلسلة.

تم تغيير اسم حقل المبلغ من value إلى amountMicros

تم تغيير اسم حقل العملة من currency إلى currencyCode. يجب أن يكون التنسيق متوافقًا مع معايير ISO 4217.

آخر الأخبار والإشعارات

للحصول على تحديثات أكثر دقة، يُرجى الاطّلاع على ملاحظات الإصدار الخاصة بكل واجهة برمجة تطبيقات فرعية. للاطّلاع على المزيد من التعديلات المجمّعة المنتظمة على Merchant API، يُرجى مراجعة آخر التعديلات.

لمزيد من التفاصيل المحدّدة والتعرّف على Merchant API بشكل أفضل، يمكنك الاطّلاع على النظرة العامة على موقع المطوّرين ودليل نقل البيانات العام.

يُرجى الاطّلاع على تصميم Merchant API للحصول على تفاصيل حول Merchant API وواجهات برمجة التطبيقات الفرعية.