রিয়েল-টাইম আপডেট

এই বিভাগটি বর্ণনা করে কিভাবে আপনি Google-এ আপনার ইনভেন্টরি সত্তার সময়-সংবেদনশীল আপডেট পাঠাতে পারেন। রিয়েল-টাইম আপডেট API আপনাকে প্রায় রিয়েল টাইমে আপনার স্যান্ডবক্স বা প্রোডাকশন ইনভেন্টরিতে আপডেটগুলি পুশ করতে এবং সত্তাগুলিকে মুছতে দেয়৷

এই কার্যকারিতাটি প্রাথমিকভাবে এমন আপডেটগুলির জন্য উদ্দিষ্ট যেগুলি আপনি পূর্বাভাস দিতে পারেন না, যেমন জরুরী বন্ধ, মেনু থেকে আইটেমগুলি সরানো বা মেনু আইটেমের দাম আপডেট করা, যা Google UI-তে দ্রুত প্রতিফলিত হওয়া আবশ্যক৷ আপনার পরিবর্তন অবিলম্বে প্রতিফলিত করার প্রয়োজন না হলে, আপনি পরিবর্তে ব্যাচ ইনজেশন ব্যবহার করতে পারেন। রিয়েল-টাইম আপডেটগুলি পাঁচ মিনিটের বেশি নয় প্রক্রিয়া করা হয়।

পূর্বশর্ত

আপনি রিয়েল-টাইম আপডেটগুলি বাস্তবায়ন করার আগে নিম্নলিখিত আইটেমগুলি প্রয়োজন:

  1. মানচিত্র বুকিং API সক্ষম করা হয়েছে:
    • GCP-এ APIs & Services > Library- এ যান
    • "গুগল ম্যাপ বুকিং API" অনুসন্ধান করুন
      Google মানচিত্র বুকিং APIs সনাক্ত করুন
    • স্যান্ডবক্স ইন্সট্যান্স খুঁজুন ("Google Maps বুকিং API (Dev)") এবং Enable এ ক্লিক করুন
    • প্রোডাকশন ইনস্ট্যান্স খুঁজুন ("Google Maps বুকিং API") এবং Enable এ ক্লিক করুন
      Google Maps বুকিং API সক্ষম করুন৷
  2. আপনার GCP প্রকল্পে সম্পাদকের ভূমিকা সহ একটি পরিষেবা অ্যাকাউন্ট তৈরি করা হয়েছে। আরও বিশদ বিবরণের জন্য, অ্যাকাউন্ট সেটআপ দেখুন।
  3. প্রোডাকশন বা স্যান্ডবক্স ডেটা ফিডগুলি হোস্ট করা এবং ইনজেস্ট করা হয়৷ আরো বিস্তারিত জানার জন্য, ব্যাচ ইনজেশন দেখুন।
  4. API প্রমাণীকরণের জন্য আপনার পছন্দের ভাষায় Google ক্লায়েন্ট লাইব্রেরি ইনস্টল করার পরামর্শ দেওয়া হয়। OAuth সুযোগ হিসেবে "https://www.googleapis.com/auth/mapsbooking" ব্যবহার করুন। নীচে অন্তর্ভুক্ত কোড নমুনা এই লাইব্রেরি ব্যবহার করে. অন্যথায়, Google API অ্যাক্সেস করতে OAuth 2.0 ব্যবহারে বর্ণিত হিসাবে আপনাকে টোকেন এক্সচেঞ্জ ম্যানুয়ালি পরিচালনা করতে হবে।

ওভারভিউ

রিয়েল-টাইম আপডেট API দুই ধরনের অপারেশন সমর্থন করে। বিদ্যমান সত্তা আপডেট করার জন্য প্রথম অপারেশনটি আপসার্ট। দ্বিতীয় অপারেশন হল আপনার ইনভেন্টরি থেকে সত্তা অপসারণের জন্য মুছে ফেলা। উভয় ক্রিয়াকলাপ অনুরোধের অংশে তালিকাভুক্ত বিভিন্ন সত্তার উপর সঞ্চালিত হয়। আপনি একটি একক API কলে 1,000টি পর্যন্ত সত্তার আপডেট করতে পারেন৷ API সমস্ত আগত অনুরোধ গ্রহণ করে এবং পরবর্তী প্রক্রিয়াকরণের জন্য একটি সারিতে রাখে। তাই RTU অনুরোধগুলি অ্যাসিঙ্ক্রোনাসভাবে প্রক্রিয়া করা হয়।

রিয়েল-টাইম আপডেট API দুটি পরিবেশে কাজ করে: স্যান্ডবক্স এবং উত্পাদন। স্যান্ডবক্স এনভায়রনমেন্ট এন্ড-টু-এন্ড ব্যবহারকারীদের কাছে দৃশ্যমান বিষয়বস্তু আপডেট করার জন্য API অনুরোধ এবং উৎপাদন পরিবেশ পরীক্ষা করার জন্য ব্যবহার করা হয়। উভয় পরিবেশের হোস্টনাম:

  • স্যান্ডবক্স - partnerdev-mapsbooking.googleapis.com
  • উৎপাদন - mapsbooking.googleapis.com

শেষবিন্দু

রিয়েল-টাইম আপডেট API ইনভেন্টরি আপডেটের জন্য আগত অনুরোধগুলি পরিচালনা করার জন্য দুটি শেষ পয়েন্ট প্রকাশ করে:

  • UPSERT - /v1alpha/inventory/partners/ PARTNER_ID /feeds/owg.v2/record:batchPush
  • মুছুন - /v1alpha/inventory/partners/ PARTNER_ID /feeds/owg.v2/record:batchDelete

প্যারামিটার PARTNER_ID নীচের স্ক্রিনশটে দেখানো হিসাবে অ্যাকাউন্ট এবং ব্যবহারকারীদের পৃষ্ঠায় অংশীদার ID হিসাবে প্রদর্শিত অ্যাকশন সেন্টারে পাওয়া যাবে।

পার্টনার পোর্টালে পার্টনার আইডি

উপরের স্ক্রিনশট থেকে উদাহরণ হিসাবে PARTNER_ID এর মান হিসাবে 10000001 নিলে, স্যান্ডবক্স এবং উত্পাদনে API অনুরোধ পাঠানোর সম্পূর্ণ URLগুলি নীচের উদাহরণগুলির মতো দেখাবে৷

# Sandbox UPSERT
https://partnerdev-mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchPush
# Sandbox DELETE
https://partnerdev-mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchDelete
# Production UPSERT
https://mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchPush
# Production DELETE
https://mapsbooking.googleapis.com/v1alpha/inventory/partners/10000001/feeds/owg.v2/record:batchDelete

সত্তা আপডেট করা হচ্ছে

আপনার ইনভেন্টরিতে সত্তা আপডেট করতে, UPSERT এন্ডপয়েন্ট ব্যবহার করুন এবং HTTP POST অনুরোধ পাঠান। প্রতিটি POST অনুরোধে অবশ্যই JSON পেলোডের সাথে PARTNER_ID প্যারামিটার অন্তর্ভুক্ত করতে হবে যাতে ইনভেনটরি স্কিমা তালিকাভুক্ত যেকোনও এন্টিটির স্ট্রাকচার্ড ডেটা থাকে।

আপসার্ট রিকোয়েস্ট পেলোড

অনুরোধের মূল অংশটি রেকর্ডের একটি তালিকা সহ একটি JSON অবজেক্ট। প্রতিটি রেকর্ড আপডেট করা একটি সত্তার সাথে মিলে যায়। এটি Base64 এ এনকোড করা সত্তা পেলোড সহ data_record ক্ষেত্র এবং generation_timestamp রয়েছে যা সত্তা আপডেটের সময় নির্দেশ করে:

  {
    "records": [
      {
        "data_record":"BASE_64_ENCODED_ENTITY",
        "generation_timestamp":"UPDATE_TIMESTAMP"
      }
    ]
  }

উপরের পেলোডে, নিম্নলিখিতগুলি প্রতিস্থাপন করুন:

  • BASE_64_ENCODED_ENTITY : বেস64 সত্তার এনকোড করা JSON স্ট্রিং। ডিকোড করা সত্তা JSON-এর ফিড স্পেকের মতো একই কাঠামো থাকা উচিত, উদাহরণস্বরূপ:

    {"@type":"MenuSection","name":"My Updated Menu Section","menuId":{"@id":"10824","displayOrder":1},"@id":"853705"}
  • UPDATE_TIMESTAMP : আপনার ব্যাকএন্ড সিস্টেমে সত্তাটি কখন তৈরি হয়েছিল তার টাইমস্ট্যাম্প অন্তর্ভুক্ত করা নিশ্চিত করুন৷ এই টাইমস্ট্যাম্পটি ইনভেন্টরি আপডেটের সঠিক ক্রম নিশ্চিত করতে ব্যবহার করা হয়। যদি এই ক্ষেত্রটি অন্তর্ভুক্ত না করা হয়, Google অনুরোধটি গ্রহণ করার সময় এটি সেট করা হবে৷ batchPush অনুরোধের মাধ্যমে একটি সত্তা আপডেট করার সময়, generation_timestamp ক্ষেত্রটি সত্তা সংস্করণের জন্য ব্যবহার করা হয়। রিলেশনাল ইনভেন্টরি স্কিমায় সময়ের মানের প্রত্যাশিত বিন্যাস দেখুন।

প্রতিটি রিয়েল-টাইম আপডেট অনুরোধ এই শর্ত পূরণ করতে হবে:

  • পেলোড বডি আকারে 5 এমবি এর বেশি হওয়া উচিত নয়। একইভাবে ব্যাচ ফিডের ক্ষেত্রে, আমরা আপনাকে আরও ডেটা ফিট করার স্বার্থে হোয়াইটস্পেসগুলি ফালা করার পরামর্শ দিই।
  • একটি batchPush অনুরোধে 1,000টি পর্যন্ত সত্তা থাকতে পারে৷

উদাহরণ

উদাহরণ 1: একটি রেস্টুরেন্ট আপডেট করা

ধরুন আপনাকে জরুরীভাবে একটি রেস্টুরেন্টের ফোন নম্বর আপডেট করতে হবে। আপনার আপডেটে পুরো রেস্টুরেন্টের জন্য JSON রয়েছে।

নিচের মত দেখতে একটি ব্যাচ ফিড বিবেচনা করুন:

{
  "@type": "Restaurant",
  "@id": "restaurant12345",
  "name": "Some Restaurant",
  "url": "https://www.provider.com/somerestaurant",
  "telephone": "+16501234570",
  "streetAddress": "345 Spear St",
  "addressLocality": "San Francisco",
  "addressRegion": "CA",
  "postalCode": "94105",
  "addressCountry": "US",
  "latitude": 37.472842,
  "longitude": -122.217144
}
  

তারপর HTTP POST দ্বারা আপনার রিয়েল-টাইম আপডেটটি নিম্নরূপ হবে:

JSON

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": {
        "@type": "Restaurant",
        "@id": "restaurant12345",
        "name": "Some Restaurant",
        "url": "https://www.provider.com/somerestaurant",
        "telephone": "+16501234570",
        "streetAddress": "345 Spear St",
        "addressLocality": "San Francisco",
        "addressRegion": "CA",
        "postalCode": "94105",
        "addressCountry": "US",
        "latitude": 37.472842,
        "longitude": -122.217144
      }
      "generation_timestamp": "2022-08-19T17:11:10.750Z"
    }
  ]
}
    

বেস64

একটি বেস64 এনকোডেড পেলোডের সাথে একই উদাহরণ।

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": "eyJAdHlwZSI6IlJlc3RhdXJhbnQiLCJAaWQiOiJyZXN0YXVyYW50MTIzNDUiLCJuYW1lIjoiU29tZSBSZXN0YXVyYW50IiwidXJsIjoiaHR0cHM6Ly93d3cucHJvdmlkZXIuY29tL3NvbWVyZXN0YXVyYW50IiwidGVsZXBob25lIjoiKzE2NTAxMjM0NTcwIiwic3RyZWV0QWRkcmVzcyI6IjM0NSBTcGVhciBTdCIsImFkZHJlc3NMb2NhbGl0eSI6IlNhbiBGcmFuY2lzY28iLCJhZGRyZXNzUmVnaW9uIjoiQ0EiLCJwb3N0YWxDb2RlIjoiOTQxMDUiLCJhZGRyZXNzQ291bnRyeSI6IlVTIiwibGF0aXR1ZGUiOjM3LjQ3Mjg0MiwibG9uZ2l0dWRlIjotMTIyLjIxNzE0NH0="
      "generation_timestamp": "2022-08-19T17:11:10.750Z"
    }
  ]
}
    

উদাহরণ 2: একাধিক রেস্টুরেন্ট আপডেট করা

একটি একক API কলে দুটি রেস্টুরেন্ট সত্তা আপডেট করতে, HTTP POST অনুরোধটি নিম্নরূপ হবে:

JSON

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": {
        "@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
      },
      "generation_timestamp": "2022-08-19T17:11:10.850Z"
    },
    {
      "data_record": {
        "@type": "Restaurant",
        "@id": "restaurant123",
        "name": "Some Other Restaurant",
        "url": "https://www.provider.com/someotherrestaurant",
        "telephone": "+16501231235",
        "streetAddress": "385 Spear St",
        "addressLocality": "San Mateo",
        "addressRegion": "CA",
        "postalCode": "94115",
        "addressCountry": "US"
      },
      "generation_timestamp": "2022-08-19T17:11:10.850Z"
    }
  ]
}
    

বেস64

একটি বেস64 এনকোডেড পেলোডের সাথে একই উদাহরণ।

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": "eyJAdHlwZSI6IlJlc3RhdXJhbnQiLCJAaWQiOiJyZXN0YXVyYW50MTIzNDUiLCJuYW1lIjoiU29tZSBSZXN0YXVyYW50IiwidXJsIjoiaHR0cHM6Ly93d3cucHJvdmlkZXIuY29tL3NvbWVyZXN0YXVyYW50IiwidGVsZXBob25lIjoiKzE2NTAxMjM1NTU1Iiwic3RyZWV0QWRkcmVzcyI6IjM0NSBTcGVhciBTdCIsImFkZHJlc3NMb2NhbGl0eSI6IlNhbiBGcmFuY2lzY28iLCJhZGRyZXNzUmVnaW9uIjoiQ0EiLCJwb3N0YWxDb2RlIjoiOTQxMDUiLCJhZGRyZXNzQ291bnRyeSI6IlVTIiwibGF0aXR1ZGUiOjM3LjQ3Mjg0MiwibG9uZ2l0dWRlIjotMTIyLjIxNzE0NH0=",
      "generation_timestamp": "2022-08-19T17:11:10.850Z"
    },
    {
      "data_record": "eyJAdHlwZSI6IlJlc3RhdXJhbnQiLCJAaWQiOiJyZXN0YXVyYW50MTIzIiwibmFtZSI6IlNvbWUgT3RoZXIgUmVzdGF1cmFudCIsInVybCI6Imh0dHBzOi8vd3d3LnByb3ZpZGVyLmNvbS9zb21lcmVzdGF1cmFudCIsInRlbGVwaG9uZSI6IisxNjUwMTIzMTIzNSIsInN0cmVldEFkZHJlc3MiOiIzODUgU3BlYXIgU3QiLCJhZGRyZXNzTG9jYWxpdHkiOiJTYW4gTWF0ZW8iLCJhZGRyZXNzUmVnaW9uIjoiQ0EiLCJwb3N0YWxDb2RlIjoiOTQxMTUiLCJhZGRyZXNzQ291bnRyeSI6IlVTIn0=",
      "generation_timestamp": "2022-08-19T17:11:10.850Z"
    }
  ]
}
    

উদাহরণ 3: একটি মেনু আইটেমের মূল্য আপডেট করা

ধরুন আপনাকে একটি মেনু আইটেমের দাম পরিবর্তন করতে হবে।

নিচের মত দেখতে একটি ব্যাচ ফিড বিবেচনা করুন:

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

তারপর POST এর মাধ্যমে আপনার রিয়েল-টাইম আপডেটটি নিম্নরূপ হবে:

JSON

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": {
        "@type": "MenuItemOffer",
        "@id": "menuitemoffer6680262",
        "sku": "offer-cola",
        "menuItemId": "menuitem896532",
        "price": 2,
        "priceCurrency": "USD"
      },
      "generation_timestamp": "2022-08-19T17:20:10Z"
    }
  ]
}
    

বেস64

একটি বেস64 এনকোডেড পেলোডের সাথে একই উদাহরণ।

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchPush
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": "eyJAdHlwZSI6Ik1lbnVJdGVtT2ZmZXIiLCJAaWQiOiJtZW51aXRlbW9mZmVyNjY4MDI2MiIsInNrdSI6Im9mZmVyLWNvbGEiLCJtZW51SXRlbUlkIjoibWVudWl0ZW04OTY1MzIiLCJwcmljZSI6MiwicHJpY2VDdXJyZW5jeSI6IlVTRCJ9",
      "generation_timestamp": "2022-08-19T17:20:10Z"
    }
  ]
}

    

সত্তা যোগ করা হচ্ছে

নতুন সত্তা যোগ করার জন্য রিয়েল-টাইম আপডেট ব্যবহার করবেন না কারণ এর ফলে ডেটার অসঙ্গতি হতে পারে। পরিবর্তে, ব্যাচ ইনজেশনের জন্য বর্ণিত ব্যাচ ফিড প্রক্রিয়াটি ব্যবহার করুন৷

সত্তা মুছে ফেলা হচ্ছে

আপনার ইনভেন্টরি থেকে সত্তা মুছে ফেলতে, DELETE endpoint ব্যবহার করুন এবং HTTP POST অনুরোধ পাঠান। প্রতিটি POST অনুরোধে অবশ্যই PARTNER_ID প্যারামিটারের সাথে JSON পেলোডের সাথে আপনার ইনভেন্টরিতে থাকা যেকোনো সত্তার শনাক্তকারী অন্তর্ভুক্ত করতে হবে।

অনুরোধ পেলোড মুছুন

একটি মুছে ফেলার অনুরোধের মূল অংশটি একটি আপডেট অনুরোধের মতোই গঠন করা হয়৷ এতে data_record এবং delete_time ফিল্ড সহ রেকর্ডের একটি তালিকা রয়েছে:

  {
    "records": [
      {
        "data_record":"BASE_64_ENCODED_REFERENCE",
        "delete_time": "DELETE_TIMESTAMP"
      }
    ]
  }

উপরের পেলোডে, নিম্নলিখিতগুলি প্রতিস্থাপন করুন:

  • BASE_64_ENCODED_REFERENCE : যে সত্তাটি সরানো হচ্ছে তার রেফারেন্সের Base64 এনকোড করা JSON স্ট্রিং৷ একটি রেফারেন্স শুধুমাত্র সত্তার ধরন এবং শনাক্তকারী থেকে গঠিত, উদাহরণস্বরূপ একটি MenuSection- এর একটি রেফারেন্সের JSON উপস্থাপনা:

    {"@type":"MenuSection","@id":"853705"}
  • DELETE_TIMESTAMP : আপনার ব্যাকএন্ড সিস্টেমে সত্তাটি কখন মুছে ফেলা হয়েছিল তার জন্য টাইমস্ট্যাম্প অন্তর্ভুক্ত করা নিশ্চিত করুন৷ এই টাইমস্ট্যাম্পটি ইনভেন্টরিতে কোন ডিলিট প্রয়োগ করা হবে তা নির্ধারণ করতে ব্যবহৃত হয়।

একটি batchDelete অনুরোধে 1,000টি পর্যন্ত সত্তা থাকতে পারে৷

উদাহরণ

উদাহরণ 1: দুটি MenuItem সত্তা সরানো

একটি একক API কলে দুটি মেনু আইটেম সরাতে, HTTP POST অনুরোধটি নিম্নরূপ হবে:

JSON

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": {
        "@type": "MenuItem",
        "@id": "item_1234"
      },
      "delete_time": "2022-08-21T15:23:00.000Z"
    },
    {
      "data_record": {
        "@type": "MenuItem",
        "@id": "item_5678"
      },
      "delete_time": "2022-08-21T15:23:00.000Z"
    }
  ]
}
    

বেস64

একটি বেস64 এনকোডেড পেলোডের সাথে একই উদাহরণ।

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": "eyJAdHlwZSI6Ik1lbnVJdGVtIiwiQGlkIjoiaXRlbV8xMjM0In0="
      "delete_time": "2022-08-21T15:23:00.000Z"
    },
    {
      "data_record": "eyJAdHlwZSI6Ik1lbnVJdGVtIiwiQGlkIjoiaXRlbV81Njc4In0="
      "delete_time": "2022-08-21T15:23:00.000Z"
    },
  ]
}
    

উদাহরণ 2: একটি Restaurant সত্তা মুছে ফেলা

এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে আপনি ব্যাচ ফিডে একটি রেস্টুরেন্ট মুছে ফেলতে চান। আপনি শুধুমাত্র রেস্টুরেন্ট সত্তা মুছে দিতে হবে. পরিষেবা এবং মেনুগুলির মতো উপ-সত্তাগুলি মুছুবেন না, কারণ সেগুলি স্বয়ংক্রিয়ভাবে সরানো হবে৷

আইডি https://www.provider.com/restaurant/12345 সহ একটি রেস্টুরেন্ট সত্তা মুছে ফেলার জন্য একটি নমুনা অনুরোধ :

JSON

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": {
        "@type": "Restaurant",
        "@id": "https://www.provider.com/restaurant/12345"
      },
      "delete_time": "2022-08-19T17:11:10.750Z"
    }
  ]
}
    

বেস64

একটি বেস64 এনকোডেড পেলোডের সাথে একই উদাহরণ।

POST v1alpha/inventory/partners/PARTNER_ID/feeds/owg.v2/record:batchDelete
Host: mapsbooking.googleapis.com
Content-Type: application/json
{
  "records": [
    {
      "data_record": "ewogICJAdHlwZSI6ICJSZXN0YXVyYW50IiwKICAiQGlkIjogImh0dHBzOi8vd3d3LnByb3ZpZGVyLmNvbS9yZXN0YXVyYW50LzEyMzQ1Igp9"
      "delete_time": "2022-08-19T17:11:10.750Z"
    }
  ]
}
    

বৈধতা এবং API প্রতিক্রিয়া কোড

রিয়েল-টাইম আপডেট API কলগুলিতে দুটি ধরণের বৈধতা সম্পাদিত হয়:

  • অনুরোধ-স্তর - এই যাচাইকরণগুলি পরীক্ষা করে যে পেলোড আপসার্ট বা ডিলিট স্কিমা অনুসরণ করে এবং প্রতিটি data_record @id এবং @type উভয় ক্ষেত্রই থাকে। এই চেকগুলি সিঙ্ক্রোনাস এবং ফলাফলগুলি API প্রতিক্রিয়া বডিতে ফেরত দেওয়া হয়৷ একটি প্রতিক্রিয়া কোড 200 এবং একটি খালি JSON বডি {} মানে এই বৈধতাগুলি পাস হয়ে গেছে এবং সেই অনুরোধে থাকা সংস্থাগুলি প্রক্রিয়াকরণের জন্য সারিবদ্ধ ছিল৷ 200 থেকে ভিন্ন একটি প্রতিক্রিয়া কোড মানে এই বৈধতাগুলির এক বা একাধিক ব্যর্থ হয়েছে এবং সম্পূর্ণ অনুরোধ প্রত্যাখ্যান করা হয়েছে (পেলোডের সমস্ত সত্তা সহ)। উদাহরণস্বরূপ, যদি একটি data_record একটি @type অনুপস্থিত ছিল, নিম্নলিখিত ত্রুটি প্রতিক্রিয়া ফিরে আসবে:

    {
      "error": {
        "code": 400,
        "message": "Record:{\"@id\":\"2717/86853/DELIVERY\",\"applicableServiceType\":[\"DELIVERY\",\"TAKEOUT\"],\"menuId\":[{\"@id\":\"2717/DELIVERY\",\"displayOrder\":1},{\"@id\":\"2717/TAKEOUT\",\"displayOrder\":2}],\"name\":\"Salad\",\"offeredById\":[\"2717\"]} has following errors: \nThe entity type could not be extracted from the entity value.\n",
        "status": "INVALID_ARGUMENT",
        "details": [
          {
            "@type": "type.googleapis.com/google.rpc.DebugInfo",
            "detail": "[ORIGINAL ERROR] generic::invalid_argument: Failed to parse one or more rtu records. Record:{\"@id\":\"2717/86853/DELIVERY\",\"applicableServiceType\":[\"DELIVERY\",\"TAKEOUT\"],\"menuId\":[{\"@id\":\"2717/DELIVERY\",\"displayOrder\":1},{\"@id\":\"2717/TAKEOUT\",\"displayOrder\":2}],\"name\":\"Salad\",\"offeredById\":[\"2717\"]} has following errors: \nThe entity type could not be extracted from the entity value.\n [google.rpc.error_details_ext] { message: \"Record:{\\\"@id\\\":\\\"2717/86853/DELIVERY\\\",\\\"applicableServiceType\\\":[\\\"DELIVERY\\\",\\\"TAKEOUT\\\"],\\\"menuId\\\":[{\\\"@id\\\":\\\"2717/DELIVERY\\\",\\\"displayOrder\\\":1},{\\\"@id\\\":\\\"2717/TAKEOUT\\\",\\\"displayOrder\\\":2}],\\\"name\\\":\\\"Salad\\\",\\\"offeredById\\\":[\\\"2717\\\"]} has following errors: \\nThe entity type could not be extracted from the entity value.\\n\" }"
          }
        ]
      }
    }
    
  • সত্তা-স্তর - পেলোডের প্রতিটি সত্তা রিলেশনাল স্কিমার বিরুদ্ধে যাচাই করা হয়। বৈধকরণের এই পর্যায়ে যে সমস্যার সম্মুখীন হয়েছে সেগুলি API প্রতিক্রিয়াতে রিপোর্ট করা হয় না। সেগুলি শুধুমাত্র RTU রিপোর্টিং ড্যাশবোর্ডে রিপোর্ট করা হয়।

API কোটা

রিয়েল-টাইম API আপডেটে প্রতি 60 সেকেন্ডে 1,500টি অনুরোধের কোটা বা গড়ে প্রতি সেকেন্ডে 25টি অনুরোধ থাকে। যখন একটি কোটা অতিক্রম করা হয়, Google নিম্নলিখিত ত্রুটি বার্তার সাথে প্রতিক্রিয়া জানায়:

{
  "error": {
    "code": 429,
    "message": "Insufficient tokens for quota ...",
    "status": "RESOURCE_EXHAUSTED",
    "details": [...]
  }
}

এটি পরিচালনা করতে, এটি সফল না হওয়া পর্যন্ত দ্রুতগতিতে বড় বিরতিতে কলটি আবার চেষ্টা করুন। আপনি যদি নিয়মিত কোটা শেষ করেন, তাহলে একটি API অনুরোধে আরও সত্তা অন্তর্ভুক্ত করার কথা বিবেচনা করুন। আপনি একটি API কলে 1,000টি পর্যন্ত সত্তা অন্তর্ভুক্ত করতে পারেন৷

কোড নমুনা

বিভিন্ন ভাষায় কীভাবে রিয়েল-টাইম আপডেট API ব্যবহার করবেন তার কিছু নমুনা নিচে দেওয়া হল। এই নমুনাগুলি অ্যাকাউন্ট সেটআপের সময় তৈরি করা একটি পরিষেবা অ্যাকাউন্ট কী ফাইল ব্যবহার করে প্রমাণীকরণের জন্য Google প্রমাণীকরণ লাইব্রেরি ব্যবহার করে। বিকল্প সমাধানের জন্য, সার্ভার থেকে সার্ভার অ্যাপ্লিকেশনের জন্য OAuth 2.0 ব্যবহার করুন দেখুন। ইনভেন্টরি এবং রিয়েল-টাইম আপডেট অবজেক্টের ধরনগুলির জন্য সোর্স কোড তৈরি করতে জেনারেট ক্লায়েন্ট লাইব্রেরিতে উপলব্ধ স্কিমা ব্যবহার করার কথা বিবেচনা করুন।

সত্তা আপডেট করা হচ্ছে

Node.js

এই কোডটি Node.js-এর জন্য Google auth লাইব্রেরি ব্যবহার করে।

/* Sample code for Real-time update batchPush implementation.
 *
 * Required libraries:
 * - google-auth-library
 */

const {JWT} = require('google-auth-library');

// ACTION REQUIRED: Change this to the path of the service account client secret
// file downloaded from the Google Cloud Console.
const serviceAccountJson = require('./service-account.json');

// ACTION REQUIRED: Change this to your Partner ID received from Google.
// The Partner ID is available on the Partner Portal.
const PARTNER_ID = 1234;

const HOST = {
  prod: 'https://mapsbooking.googleapis.com',
  sandbox: 'https://partnerdev-mapsbooking.googleapis.com'
};

// ACTION REQUIRED: Change to 'prod' for production
const ENV = 'sandbox';

// Feed name for Order with Google including the version.
const FEED_NAME = 'owg.v2';

// Endpoint url
const url = `${HOST[ENV]}/v1alpha/inventory/partners/${PARTNER_ID}/feeds/${
    FEED_NAME}/record:batchPush`;

/**
 * Send a Real-time update request to update/insert entities
 */
async function batchUpsert(entities) {
  /**
   * Sign JWT token using private key from service account secret file
   * provided. The client can be created without providing a service account
   * secret file by implementing Application Default Credentials.
   * https://github.com/googleapis/google-auth-library-nodejs
   */
  const client = new JWT({
    email: serviceAccountJson.client_email,
    key: serviceAccountJson.private_key,
    scopes: ['https://www.googleapis.com/auth/mapsbooking'],
  });
  const request = {records: toPushRecords(entities)};
  const body = JSON.stringify(request);
  try {
    const response = await client.request({
      method: 'POST',
      url,
      data: body,
      headers: {'Content-Type': 'application/json'}
    });
    console.log('request body:', body);
    console.log('response status:', response.status);
    console.log(
        'response data:', response.data);  // successful response returns '{}'
  } catch (error) {
    console.log('error:', error);
  }
}

/**
 * Maps array of entities to records for batch push requests
 */
const toPushRecords = (entities) => {
  return entities.map((entity) => {
    // Using dateModified to set generation_timestamp. Defaulting to the
    // current timestamp for records that do not have dateModified.
    const generation_timestamp =
        entity.dateModified ? entity.dateModified : new Date().toISOString();
    return {data_record: btoa(JSON.stringify(entity)), generation_timestamp};
  });
};

// Call batchUpsert with example entities. dateModified is optional and is
// used to hold the actual timestamp when the entity was updated/created.
batchUpsert([
  {
    '@type': 'MenuItemOffer',
    '@id': '6680261',
    'menuItemId': '18931508',
    'price': 15.5,
    'priceCurrency': 'USD',
    'applicableServiceType': ['DELIVERY', 'TAKEOUT'],
    'inventoryLevel': 0,
    'dateModified': '2022-06-19T15:43:50.970Z'
  },
  {
    '@type': 'MenuItemOffer',
    '@id': '6680262',
    'menuItemId': '18931509',
    'price': 25.5,
    'priceCurrency': 'USD',
    'applicableServiceType': ['DELIVERY', 'TAKEOUT'],
    'inventoryLevel': 0,
    'dateModified': '2022-06-19T15:43:50.970Z'
  }
]);

পাইথন

এই কোডটি পাইথনের জন্য Google auth লাইব্রেরি ব্যবহার করে।

"""Sample code for the Real-time update batchPush implementation."""

# Required libraries:
# - google-auth

import base64
import datetime
import json
from google.auth.transport.requests import AuthorizedSession
from google.oauth2 import service_account

# ACTION REQUIRED: Change this to the Partner ID received from Google.
# Partner ID is available on the Partner Portal.
# https://partnerdash.google.com/apps/reservewithgoogle
_PARTNER_ID = '1234'

# ACTION REQUIRED: Change this to the path of the service account client secret
# file downloaded from the Google Cloud Console.
_SERVICE_ACCOUNT_KEY_JSON_FILE = 'service-account-creds.json'

_HOST_MAP = {
    'sandbox': 'https://partnerdev-mapsbooking.googleapis.com',
    'prod': 'https://mapsbooking.googleapis.com'
}

# ACTION REQUIRED: Change to 'prod' for production
_ENV = 'sandbox'

# Feed name for Order with Google including the version.
_FEED_NAME = 'owg.v2'

_ENDPOINT = '{}/v1alpha/inventory/partners/{}/feeds/{}/record:batchPush'.format(
    _HOST_MAP[_ENV], _PARTNER_ID, _FEED_NAME)


def batch_upsert(entities):
  """Makes a batchPush request using the Real-time updates REST service.

  Args:
      entities: The list of entity objects to update or add.
  """

  # Creates credentials by providing a json file. Credentials can also be
  # provided by implementing Application Default Credentials.
  # https://googleapis.dev/python/google-auth/latest/user-guide.html
  credentials = service_account.Credentials.from_service_account_file(
      _SERVICE_ACCOUNT_KEY_JSON_FILE,
      scopes=['https://www.googleapis.com/auth/mapsbooking'])
  authorized_session = AuthorizedSession(credentials)

  # JSON request object
  batch_request = {'records': [create_push_record(x) for x in entities]}
  response = authorized_session.post(_ENDPOINT, json=batch_request)
  print('request body:', json.dumps(batch_request))
  print('response status:', response.status_code)
  print('response data:', response.text)  # successful response returns '{}'


def create_push_record(entity):
  """Creates a record from an entity for batchPush requests.

  Args:
      entity: The entity object to create the record from.

  Returns:
      The constructed record for the batchPush request payload.
  """
  data_bytes = json.dumps(entity).encode('utf-8')
  base64_bytes = base64.b64encode(data_bytes)
  # Using dateModified to set generation_timestamp. Defaulting to the
  # current timestamp for records that do not have dateModified.
  generation_timestamp = entity.dateModified if 'dateModified' in entity else datetime.datetime.now(
  ).strftime('%Y-%m-%dT%H:%M:%S.%fZ')
  return {
      'generation_timestamp': generation_timestamp,
      'data_record': base64_bytes.decode('utf-8')
  }


# Call batch_upsert with example entities. dateModified is optional and is
# used to hold the actual timestamp when the entity was updated/created.
batch_upsert([{
    '@type': 'MenuItemOffer',
    '@id': '6680261',
    'menuItemId': '18931508',
    'price': 15.5,
    'priceCurrency': 'USD',
    'applicableServiceType': ['DELIVERY', 'TAKEOUT'],
    'inventoryLevel': 0,
    'dateModified': '2022-06-19T15:43:50.970Z'
}, {
    '@type': 'MenuItemOffer',
    '@id': '6680262',
    'menuItemId': '18931509',
    'price': 25.5,
    'priceCurrency': 'USD',
    'applicableServiceType': ['DELIVERY', 'TAKEOUT'],
    'inventoryLevel': 0,
    'dateModified': '2022-06-19T15:43:50.970Z'
}])

জাভা

এই কোডটি Java এর জন্য Google auth লাইব্রেরি ব্যবহার করে।

rtusamples.inventory এবং rtusamples.realtime প্যাকেজে ক্লায়েন্ট সোর্স কোড মডেলগুলি তৈরি করা হয়েছে ক্লায়েন্ট লাইব্রেরি তৈরির ধাপ অনুসরণ করে।

/*
 * Required Libraries:
 * - JDK >= 11
 * - google-auth-library-oauth2-http
 */
package rtusamples;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.Charset;
import java.time.Clock;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import rtusamples.inventory.MenuItemOffer;
import rtusamples.inventory.MenuItemOfferType;
import rtusamples.inventory.ServiceTypeElement;
import rtusamples.realtime.BatchPushGenericRecordRequest;
import rtusamples.realtime.GenericRecord;

/** Sample code for Real-time update batchPush implementation. */
public final class BasicPush {
  // ACTION REQUIRED: Change this to your Partner ID received from Google. The Partner ID is
  // available on the Partner Portal.
  private static final long PARTNER_ID = 12345678;

  // ACTION REQUIRED: Change this to the path of the service account client secret file downloaded
  // from the Google Cloud Console.
  private static final String JSON_KEY_FULL_PATH =
      "<path to your JSON credentials>/credentials.json";

  // ACTION REQUIRED: Change this to the endpoint that is needed.
  private static final String ENDPOINT =
      //    "https://partnerdev-mapsbooking.googleapis.com"; // for sandbox
      "https://mapsbooking.googleapis.com"; // for prod

  // Feed name for Order with Google including the version.
  private static final String FEED_NAME = "owg.v2";

  private static final ObjectMapper objectMapper = new ObjectMapper();

  private static final DateTimeFormatter TIMESTAMP_FORMATTER =
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'");

  private static final Charset UTF_8 = Charset.forName("UTF-8");

  public static void main(String[] args) throws Exception {

    /**
     * Create credentials from service account secret file. Alternatively, the credentials can be
     * created by implementing Application Default Credentials.
     * https://github.com/googleapis/google-auth-library-java
     */
    // GoogleCredentials sourceCredentials =
    //     GoogleCredentials.getApplicationDefault()
    //         .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking"));

    // ImpersonatedCredentials credentials =
    //     ImpersonatedCredentials.create(
    //         sourceCredentials,
    //         "fo-test@projectname.iam.gserviceaccount.com",
    //         null,
    //         Arrays.asList("https://www.googleapis.com/auth/mapsbooking"),
    //         300);

    GoogleCredentials credentials =
        GoogleCredentials.fromStream(new FileInputStream(JSON_KEY_FULL_PATH))
            .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking"));

    // Create example MenuItemOffer entities, dateModified is optional and is used to hold
    // the actual timestamp when the entity was updated/created.
    MenuItemOffer menuItemOfferPizza = new MenuItemOffer();
    menuItemOfferPizza.setID("6680261");
    menuItemOfferPizza.setType(MenuItemOfferType.MENU_ITEM_OFFER);
    menuItemOfferPizza.setMenuItemID("18931508");
    menuItemOfferPizza.setPrice(15.5);
    menuItemOfferPizza.setPriceCurrency("USD");
    menuItemOfferPizza.setApplicableServiceType(
        new ServiceTypeElement[] {ServiceTypeElement.TAKEOUT, ServiceTypeElement.DELIVERY});
    menuItemOfferPizza.setInventoryLevel(0.0);
    menuItemOfferPizza.setDateModified("2022-10-07T13:00:00.000Z");

    MenuItemOffer menuItemOfferSalad = new MenuItemOffer();
    menuItemOfferSalad.setID("6680262");
    menuItemOfferSalad.setType(MenuItemOfferType.MENU_ITEM_OFFER);
    menuItemOfferSalad.setMenuItemID("18931509");
    menuItemOfferSalad.setPrice(25.5);
    menuItemOfferSalad.setPriceCurrency("USD");
    menuItemOfferSalad.setApplicableServiceType(
        new ServiceTypeElement[] {ServiceTypeElement.TAKEOUT, ServiceTypeElement.DELIVERY});
    menuItemOfferSalad.setInventoryLevel(0.0);
    menuItemOfferSalad.setDateModified("2022-10-07T13:00:00.000Z");

    // Example array of MenuItemOffer entities to update.
    List<MenuItemOffer> menuItemOffers = Arrays.asList(menuItemOfferPizza, menuItemOfferSalad);

    // Create list of GenericRecord from menuItemOffers.
    List<GenericRecord> menuItemOfferGenericRecords =
        menuItemOffers.stream()
            .map(
                (menuItemOffer) ->
                    toBatchPushRecord(menuItemOffer, menuItemOffer.getDateModified()))
            .collect(Collectors.toList());

    // List of records to be updated/created.
    List<GenericRecord> recordsToBeUpdated = new ArrayList<>();

    // Add list of menuItemOffer generic records.
    recordsToBeUpdated.addAll(menuItemOfferGenericRecords);

    // Request object that contains all records.
    BatchPushGenericRecordRequest batchPushRequest = new BatchPushGenericRecordRequest();
    batchPushRequest.setRecords(recordsToBeUpdated.toArray(new GenericRecord[0]));

    // Execute batchPush request.
    BasicPush basicPush = new BasicPush();
    basicPush.batchPush(batchPushRequest, credentials);
  }

  public void batchPush(
      BatchPushGenericRecordRequest batchPushRequest, GoogleCredentials credentials)
      throws IOException {

    credentials.refreshIfExpired();
    AccessToken token = credentials.getAccessToken();

    String requestBody = objectMapper.writeValueAsString(batchPushRequest);
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request =
        HttpRequest.newBuilder()
            .uri(
                URI.create(
                    String.format(
                        "%s/v1alpha/inventory/partners/%s/feeds/%s/record:batchPush",
                        ENDPOINT, PARTNER_ID, FEED_NAME)))
            .header("Content-Type", "application/json")
            .header("Authorization", String.format("Bearer %s", token.getTokenValue()))
            .POST(BodyPublishers.ofString(requestBody))
            .build();

    HttpResponse<String> response = null;
    try {
      response = client.send(request, BodyHandlers.ofString());
      System.out.println("Request body:" + requestBody);
      System.out.println("Response status:" + response.statusCode());
      System.out.println("Response body:" + response.body());
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }

  public static <T> GenericRecord toBatchPushRecord(T entity, String dateModified) {
    GenericRecord genericRecord = new GenericRecord();
    try {
      String json = objectMapper.writeValueAsString(entity);
      genericRecord.setDataRecord(Base64.getEncoder().encodeToString(json.getBytes(UTF_8)));
      // Using dateModified to set generation_timestamp. Defaulting to the
      // current timestamp for records that do not have dateModified.
      String generationTimestamp =
          Optional.ofNullable(dateModified)
              .orElse(OffsetDateTime.now(Clock.systemUTC()).format(TIMESTAMP_FORMATTER));
      genericRecord.setGenerationTimestamp(generationTimestamp);
    } catch (JsonProcessingException e) {
      System.out.println(e.getMessage());
    }
    return genericRecord;
  }
}

সত্তা সরানো হচ্ছে

Node.js

এই কোডটি Node.js-এর জন্য Google auth লাইব্রেরি ব্যবহার করে।

/* Sample code for Real-time update batchDelete implementation.
 *
 * Required libraries:
 * - google-auth-library
 */

const {JWT} = require('google-auth-library');

// ACTION REQUIRED: Change this to the path of the service account client secret
// file downloaded from the Google Cloud Console.
const serviceAccountJson = require('./service-account.json');

// ACTION REQUIRED: Change this to your Partner ID received from Google.
// The Partner ID is available on the Partner Portal.
const PARTNER_ID = 1234;

const HOST = {
  prod: 'https://mapsbooking.googleapis.com',
  sandbox: 'https://partnerdev-mapsbooking.googleapis.com'
};

// ACTION REQUIRED: Change to 'prod' for production
const ENV = 'sandbox';

// Feed name for Order with Google including the version.
const FEED_NAME = 'owg.v2';

// Endpoint url
const url = `${HOST[ENV]}/v1alpha/inventory/partners/${PARTNER_ID}/feeds/${
    FEED_NAME}/record:batchDelete`;


/**
 * Send a Real-time update request to delete entities
 */
async function batchDelete(entities) {
  try {
    /**
     * Sign JWT token using private key from service account secret file
     * provided. The client can be created without providing a service account
     * secret file by implementing Application Default Credentials.
     * https://github.com/googleapis/google-auth-library-nodejs
     */
    const client = new JWT({
      email: serviceAccountJson.client_email,
      key: serviceAccountJson.private_key,
      scopes: ['https://www.googleapis.com/auth/mapsbooking'],
    });
    const request = {
      records: toDeleteRecords(entities)
    };
    const body = JSON.stringify(request);
    try {
      const response = await client.request({
        method: 'POST',
        url,
        data: body,
        headers: {'Content-Type': 'application/json'}
      });
      console.log('request body:', body);
      console.log('response status:', response.status);
      console.log('response data:', response.data);  // successful response returns '{}'
    } catch (error) {
      console.log('error:', error);
    }
  }

  /**
   * Maps array of entities to records for batch delete requests
   */
  const toDeleteRecords = (entities) => {
    return entities.map((entity) => {
      // Using dateModified to set delete_time. Defaulting to the current
      // timestamp for records that do not have dateModified.
      const delete_time =
          entity.dateModified ? entity.dateModified : new Date().toISOString();
      return {data_record: btoa(JSON.stringify(entity)), delete_time};
    });
  };

  // Call batchDelete with example entities. dateModified is optional and is
  // used to hold the actual timestamp when the entity was deleted.
  batchDelete([
    {
      '@type': 'Menu',
      '@id': '853706',
      'dateModified': '2022-06-19T15:43:50.970Z'
    },
    {
      '@type': 'Menu',
      '@id': '853705',
      'dateModified': '2022-06-19T15:13:00.280Z'
    }
  ]);

পাইথন

এই কোডটি পাইথনের জন্য Google auth লাইব্রেরি ব্যবহার করে।

"""Sample code for the Real-time update batchDelete implementation."""

# Required libraries:
# - google-auth

import base64
import datetime
import json
from google.auth.transport.requests import AuthorizedSession
from google.oauth2 import service_account

# ACTION REQUIRED: Change this to the Partner ID received from Google.
# Partner ID is available on the Partner Portal.
# https://partnerdash.google.com/apps/reservewithgoogle
_PARTNER_ID = '1234'

# ACTION REQUIRED: Change this to the path of the service account client secret
# file downloaded from the Google Cloud Console.
_SERVICE_ACCOUNT_KEY_JSON_FILE = 'service-account-creds.json'

_HOST_MAP = {
    'sandbox': 'https://partnerdev-mapsbooking.googleapis.com',
    'prod': 'https://mapsbooking.googleapis.com'
}

# ACTION REQUIRED: Change to 'prod' for production
_ENV = 'sandbox'

# Feed name for Order with Google including the version.
_FEED_NAME = 'owg.v2'

_ENDPOINT = '{}/v1alpha/inventory/partners/{}/feeds/{}/record:batchDelete'.format(
    _HOST_MAP[_ENV], _PARTNER_ID, _FEED_NAME)


def batch_delete(entities):
  """Makes a batch delete request using the Real-time updates REST service.

  Args:
      entities: The list of entity objects to delete.
  """

  # Creates credentials by providing a json file. Credentials can also be
  # provided by implementing Application Default Credentials.
  # https://googleapis.dev/python/google-auth/latest/user-guide.html
  credentials = service_account.Credentials.from_service_account_file(
      _SERVICE_ACCOUNT_KEY_JSON_FILE,
      scopes=['https://www.googleapis.com/auth/mapsbooking'])
  authorized_session = AuthorizedSession(credentials)

  # JSON request object
  batch_request = {'records': [create_delete_record(x) for x in entities]}
  response = authorized_session.post(_ENDPOINT, json=batch_request)
  print('request body:', json.dumps(batch_request))
  print('response status:', response.status_code)
  print('response data:', response.text)  # successful response returns '{}'


def create_delete_record(entity):
  """Creates a record from an entity for batchDelete requests.

  Args:
    entity: The entity object to create the record from.

  Returns:
    The constructed record for the batchDelete request payload.
  """
  data_bytes = json.dumps(entity).encode('utf-8')
  base64_bytes = base64.b64encode(data_bytes)
  # Using dateModified to set delete_time. Defaulting to the current
  # timestamp for records that do not have dateModified.
  delete_time = entity.dateModified if 'dateModified' in entity else datetime.datetime.now(
  ).strftime('%Y-%m-%dT%H:%M:%S.%fZ')
  return {
      'delete_time': delete_time,
      'data_record': base64_bytes.decode('utf-8')
  }


# Call batch_delete with example entities. dateModified is optional and is
# used to hold the actual timestamp when the entity was deleted.
batch_delete([{
    '@type': 'Menu',
    '@id': '853706',
    'dateModified': '2022-06-19T13:10:00.000Z'
}, {
    '@type': 'Menu',
    '@id': '853705',
    'dateModified': '2022-06-19T13:30:10.000Z'
}])

জাভা

এই কোডটি Java এর জন্য Google auth লাইব্রেরি ব্যবহার করে।

rtusamples.inventory এবং rtusamples.realtime প্যাকেজে ক্লায়েন্ট সোর্স কোড মডেলগুলি তৈরি করা হয়েছে ক্লায়েন্ট লাইব্রেরি তৈরির ধাপ অনুসরণ করে।

/*
 * Required Libraries:
 * - JDK >= 11
 * - google-auth-library-oauth2-http
 */
package rtusamples;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.auth.oauth2.AccessToken;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.Charset;
import java.time.Clock;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import rtusamples.inventory.Menu;
import rtusamples.inventory.MenuType;
import rtusamples.realtime.BatchDeleteGenericRecordsRequest;
import rtusamples.realtime.GenericDeleteRecord;

/** Sample code for the Real-time update batchDelete implementation. */
public final class BasicDelete {
  // ACTION REQUIRED: Change this to your Partner ID received from Google. The Partner ID is
  // available on the Partner Portal.
  private static final long PARTNER_ID = 123456789;

  // ACTION REQUIRED: Change this to the path of the service account client secret file downloaded
  // from the Google Cloud Console.
  private static final String JSON_KEY_FULL_PATH =
      "<path to your JSON credentials>/credentials.json";

  // ACTION REQUIRED: Change this to the endpoint that is needed.
  private static final String ENDPOINT =
      "https://partnerdev-mapsbooking.googleapis.com"; // for sandbox
  // "https://mapsbooking.googleapis.com" // for prod

  // Feed name for Order with Google including the version.
  private static final String FEED_NAME = "owg.v2";

  private static final ObjectMapper objectMapper = new ObjectMapper();

  private static final DateTimeFormatter TIMESTAMP_FORMATTER =
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'");

  private static final Charset UTF_8 = Charset.forName("UTF-8");

  public static void main(String[] args) throws Exception {

    /**
     * Create credentials from service account secret file. Alternatively, the credentials can be
     * created by implementing Application Default Credentials.
     * https://github.com/googleapis/google-auth-library-java
     */
    // GoogleCredentials sourceCredentials =
    //     GoogleCredentials.getApplicationDefault()
    //         .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking"));

    // ImpersonatedCredentials credentials =
    //     ImpersonatedCredentials.create(
    //         sourceCredentials,
    //         "fo-test@projectname.iam.gserviceaccount.com",
    //         null,
    //         Arrays.asList("https://www.googleapis.com/auth/mapsbooking"),
    //         300);

    GoogleCredentials credentials =
        GoogleCredentials.fromStream(new FileInputStream(JSON_KEY_FULL_PATH))
            .createScoped(Arrays.asList("https://www.googleapis.com/auth/mapsbooking"));

    // Create example Menu entities, dateModified is optional and is used to hold
    // the actual timestamp when the entity was deleted.
    Menu menuLunch = new Menu();
    menuLunch.setID("853705");
    menuLunch.setType(MenuType.MENU);
    menuLunch.setDateModified("2022-09-19T13:10:00.000Z");

    Menu menuDinner = new Menu();
    menuDinner.setID("853706");
    menuDinner.setType(MenuType.MENU);
    menuDinner.setDateModified("2022-09-19T13:13:10.000Z");

    // Example array of Menu entities to update.
    List<Menu> menus = Arrays.asList(menuLunch, menuDinner);

    // Create list of GenericDeleteRecord from menus.
    List<GenericDeleteRecord> menuGenericDeleteRecords =
        menus.stream()
            .map((menu) -> toBatchDeleteRecord(menu, menu.getDateModified()))
            .collect(Collectors.toList());

    // List of records to be deleted.
    List<GenericDeleteRecord> recordsToBeDeleted = new ArrayList<>();

    // Add list of menu generic records.
    recordsToBeDeleted.addAll(menuGenericDeleteRecords);

    // Request object that contains all records.
    BatchDeleteGenericRecordsRequest batchDeleteRequest = new BatchDeleteGenericRecordsRequest();
    batchDeleteRequest.setRecords(recordsToBeDeleted.toArray(new GenericDeleteRecord[0]));

    // Execute batchDelete request.
    BasicDelete basicDelete = new BasicDelete();
    basicDelete.batchDelete(batchDeleteRequest, credentials);
  }

  public void batchDelete(
      BatchDeleteGenericRecordsRequest batchDeleteRequest, GoogleCredentials credentials)
      throws IOException {

    credentials.refreshIfExpired();
    AccessToken token = credentials.getAccessToken();

    String requestBody = objectMapper.writeValueAsString(batchDeleteRequest);
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request =
        HttpRequest.newBuilder()
            .uri(
                URI.create(
                    String.format(
                        "%s/v1alpha/inventory/partners/%s/feeds/%s/record:batchDelete",
                        ENDPOINT, PARTNER_ID, FEED_NAME)))
            .header("Content-Type", "application/json")
            .header("Authorization", String.format("Bearer %s", token.getTokenValue()))
            .POST(BodyPublishers.ofString(requestBody))
            .build();

    HttpResponse<String> response = null;
    try {
      response = client.send(request, BodyHandlers.ofString());
      System.out.println("Request body:" + requestBody);
      System.out.println("Response status:" + response.statusCode());
      System.out.println("Response body:" + response.body());
    } catch (IOException | InterruptedException e) {
      e.printStackTrace();
    }
  }

  public static <T> GenericDeleteRecord toBatchDeleteRecord(T entity, String dateModified) {
    GenericDeleteRecord genericRecord = new GenericDeleteRecord();
    try {
      String json = objectMapper.writeValueAsString(entity);
      genericRecord.setDataRecord(Base64.getEncoder().encodeToString(json.getBytes(UTF_8)));
      // Using dateModified to set delete_time. Defaulting to the current
      // timestamp for records that do not have dateModified.
      String deleteTime =
          Optional.ofNullable(dateModified)
              .orElse(OffsetDateTime.now(Clock.systemUTC()).format(TIMESTAMP_FORMATTER));
      genericRecord.setDeleteTime(deleteTime);
    } catch (JsonProcessingException e) {
      System.out.println(e.getMessage());
    }
    return genericRecord;
  }
}

ব্যবহারের ক্ষেত্রে

নিম্নলিখিত ব্যবহারের ক্ষেত্রেগুলি হল রিয়েল-টাইম আপডেট, ব্যাচ ফিড আপডেট এবং API কলে উচ্চ স্তরের সামগ্রীর উদাহরণ:

দৃশ্যকল্প আপডেট করার জন্য সত্তা বর্ণনা এবং প্রভাব
একটি পরিষেবা অক্ষম করা হচ্ছে Service

আপনাকে একটি অপ্রত্যাশিত কারণে একটি পরিষেবা নিষ্ক্রিয় করতে হবে৷

রিয়েল-টাইম আপডেট: প্রশ্নে থাকা Service সত্তাটিকে তার isDisabled প্রপার্টি true এ সেট করে আপডেট করুন, কিন্তু অন্যান্য বৈশিষ্ট্য একই রাখুন।

সম্পূর্ণ ফিড: Google দ্বারা পরবর্তী আনয়নের পূর্বে isDisabled true সেট করার জন্য সম্পূর্ণ ফিড থেকে সত্তাটি আপডেট করা নিশ্চিত করুন, অন্যথায় সত্তাটি পুনরায় সক্ষম হবে।

নির্দিষ্ট আইটেম আউট অফ স্টক MenuItemOffer রিয়েল-টাইম আপডেট: প্রদত্ত MenuItem এর জন্য inventoryLevel সেট সহ এনক্যাপসুলেটিং MenuItemOffer সত্তা পাঠান এবং অন্যান্য সমস্ত ডেটা অপরিবর্তিত।
মেনু আইটেম মূল্য পরিবর্তন MenuItemOffer রিয়েল-টাইম আপডেট: প্রদত্ত MenuItem এর জন্য আপডেট করা মূল্যে সেট করা price সহ encapsulating MenuItemOffer সত্তা পাঠান এবং অন্যান্য সমস্ত ডেটা অপরিবর্তিত।

নতুন শীর্ষ-স্তরের সত্তা যোগ করুন

শুধুমাত্র Menu , Restaurant এবং Service ধরনের সত্তার জন্য প্রযোজ্য।

Menu , Restaurant , Service

উদাহরণস্বরূপ, আপনাকে একটি রেস্টুরেন্টে একটি নতুন মেনু যোগ করতে হবে।

সম্পূর্ণ ফিড: আপনার ডেটা ফিডে সত্তা যোগ করুন এবং ব্যাচ ইনজেশনের জন্য অপেক্ষা করুন।

স্থায়ীভাবে শীর্ষ-স্তরের সত্তা মুছুন

শুধুমাত্র Menu , Restaurant এবং Service ধরনের সত্তার জন্য প্রযোজ্য।

Menu , Restaurant , Service

রিয়েল-টাইম আপডেট: একটি স্পষ্ট মুছে পাঠান।

সম্পূর্ণ ফিড: Google দ্বারা পরবর্তী আনার আগে সম্পূর্ণ ফিড থেকে সত্তাটিকে সরিয়ে ফেলা নিশ্চিত করুন, অন্যথায় সত্তাটি পুনরায় যুক্ত করা হবে।

একটি নির্দিষ্ট Service একটি নতুন ডেলিভারি এলাকা যোগ করুন ServiceArea ব্যাচ ফিডস: ServiceArea সত্তাকে তার সমস্ত ক্ষেত্র অক্ষত রেখে প্রশ্নে পাঠান, যেমন আপনি সাধারণত সম্পূর্ণ ফিডের মধ্যে থাকেন, polygon , geoRadius বা postalCode মধ্যে নির্দিষ্ট করা নতুন ডেলিভারি এলাকা সহ।
Service পৌঁছানোর আনুমানিক সময় ডেলিভারি আপডেট করুন ServiceHours ব্যাচ ফিড: ServiceHours ফিডের মতোই পাঠান, এর leadTimeMin সেই অনুযায়ী আপডেট করা ছাড়া।
Service ডেলিভারির দাম আপডেট করুন Fee ব্যাচ ফিড: আপডেট price সহ সম্পূর্ণ ডেলিভারি Fee পাঠান।
Service ডেলিভারি বা টেকআউটের সময় আপডেট করুন ServiceHours ব্যাচ ফিড: ServiceHours ফিডের মতোই পাঠান, এর opens এবং closes বৈশিষ্ট্যগুলি সেই অনুযায়ী আপডেট করা ছাড়া।
Service (ন্যূনতম অর্ডারের পরিমাণ পরিবর্তন করুন) Fee ব্যাচ ফিড: minPrice আপডেট সহ সম্পূর্ণ Fee পাঠান
স্থায়ীভাবে একটি MenuItem মুছুন Menu ব্যাচ ফিড: MenuItem ফিডের মতোই পাঠান, কিন্তু parentMenuSectionId খালি দিয়ে।

ব্যাচের কাজ এবং রিয়েল-টাইম আপডেটের জন্য প্রক্রিয়াকরণের সময়

একটি ব্যাচ ফিডের মাধ্যমে আপডেট করা বা মুছে ফেলা একটি সত্তা 2 ঘন্টার মধ্যে প্রক্রিয়া করা হবে যেখানে একটি রিয়েল-টাইম আপডেটের মাধ্যমে আপডেট করা একটি সত্তা 5 মিনিটের মধ্যে প্রক্রিয়া করা হবে। একটি পুরানো সত্তা 14 দিনের মধ্যে মুছে ফেলা হয়।

আপনি হয় Google পাঠাতে পারেন:

  • আপনার ইনভেন্টরি আপ টু ডেট রাখতে প্রতিদিন একাধিক ব্যাচের কাজ, বা
  • আপনার ইনভেন্টরি আপ টু ডেট রাখতে প্রতিদিন একটি ব্যাচের কাজ এবং রিয়েল-টাইম আপডেট।