Engage SDK ব্যবহার করে Google TV-এর সাথে অ্যাপ এনটাইটেলমেন্ট শেয়ার করুন

বই_পথ: /distribute/other-docs/_book.yaml প্রকল্প_পথ: /distribute/other-docs/_project.yaml

এই নির্দেশিকাটিতে ডেভেলপারদের জন্য Engage SDK ব্যবহার করে Google TV-এর সাথে অ্যাপ সাবস্ক্রিপশন এবং এনটাইটেলমেন্ট ডেটা শেয়ার করার নির্দেশাবলী রয়েছে। ব্যবহারকারীরা তাদের অধিকারী সামগ্রী খুঁজে পেতে পারেন এবং Google TV-কে টিভি, মোবাইল এবং ট্যাবলেটে সরাসরি Google TV অভিজ্ঞতার মধ্যে ব্যবহারকারীদের কাছে অত্যন্ত প্রাসঙ্গিক সামগ্রীর সুপারিশ সরবরাহ করতে সক্ষম করতে পারেন।

পূর্বশর্ত

ডিভাইস এনটাইটেলমেন্ট API ব্যবহার করার আগে মিডিয়া অ্যাকশন ফিড অনবোর্ডিং করা আবশ্যক। যদি আপনি ইতিমধ্যে এটি না করে থাকেন, তাহলে মিডিয়া অ্যাকশন ফিড অনবোর্ডিং প্রক্রিয়াটি সম্পূর্ণ করুন।

প্রাক-কাজ

"শুরু করা" নির্দেশিকায় প্রাক-কাজের নির্দেশাবলী পূরণ করুন।

  1. নিম্নলিখিত ইভেন্টগুলির সাবস্ক্রিপশন তথ্য প্রকাশ করুন:
    1. ব্যবহারকারী আপনার অ্যাপে লগ ইন করে।
    2. ব্যবহারকারী প্রোফাইলের মধ্যে স্যুইচ করে (যদি প্রোফাইল সমর্থিত হয়)।
    3. ব্যবহারকারী একটি নতুন সাবস্ক্রিপশন ক্রয় করেন।
    4. ব্যবহারকারী একটি বিদ্যমান সাবস্ক্রিপশন আপগ্রেড করে।
    5. ব্যবহারকারীর সাবস্ক্রিপশনের মেয়াদ শেষ।

ইন্টিগ্রেশন

এই বিভাগটি বিভিন্ন ধরণের সাবস্ক্রিপশন পরিচালনা করার জন্য SubscriptionEntity বাস্তবায়নের জন্য প্রয়োজনীয় কোড উদাহরণ এবং নির্দেশাবলী প্রদান করে।

সাধারণ স্তরের সাবস্ক্রিপশন

মিডিয়া প্রোভাইডার পরিষেবার মৌলিক সাবস্ক্রিপশন ব্যবহারকারীদের জন্য, উদাহরণস্বরূপ, এমন একটি পরিষেবা যার একটি সাবস্ক্রিপশন স্তর রয়েছে যা সমস্ত অর্থপ্রদানের সামগ্রীতে অ্যাক্সেস দেয়, এই প্রয়োজনীয় বিবরণগুলি প্রদান করুন:

  1. SubscriptionType : ব্যবহারকারীর নির্দিষ্ট সাবস্ক্রিপশন প্ল্যানটি স্পষ্টভাবে উল্লেখ করুন।

    • SUBSCRIPTION_TYPE_ACTIVE : ব্যবহারকারীর একটি সক্রিয় অর্থপ্রদানকারী সদস্যতা রয়েছে।
    • SUBSCRIPTION_TYPE_ACTIVE_TRIAL : ব্যবহারকারীর একটি ট্রায়াল সাবস্ক্রিপশন আছে।
    • SUBSCRIPTION_TYPE_INACTIVE : ব্যবহারকারীর একটি অ্যাকাউন্ট আছে কিন্তু কোনও সক্রিয় সাবস্ক্রিপশন বা ট্রায়াল নেই।
  2. ExpirationTimeMillis : ঐচ্ছিক সময় মিলিসেকেন্ডে। সাবস্ক্রিপশন কখন মেয়াদ শেষ হবে তা নির্দিষ্ট করুন।

  3. ProviderPackageName : সাবস্ক্রিপশন পরিচালনা করে এমন অ্যাপের প্যাকেজের নাম উল্লেখ করুন।

নমুনা মিডিয়া প্রোভাইডার ফিডের উদাহরণ।

"actionAccessibilityRequirement": [
  {
    "@type": "ActionAccessSpecification",
    "category": "subscription",
    "availabilityStarts": "2022-06-01T07:00:00Z",
    "availabilityEnds": "2026-05-31T07:00:00Z",
    "requiresSubscription": {
    "@type": "MediaSubscription",
    // Don't match this string,
    // ID is only used to for reconciliation purpose
    "@id": "https://www.example.com/971bfc78-d13a-4419",
    // Don't match this, as name is only used for displaying purpose
    "name": "Basic common name",
    "commonTier": true
  }

নিম্নলিখিত উদাহরণটি একজন ব্যবহারকারীর জন্য একটি SubscriptionEntity তৈরি করে:

val subscription = SubscriptionEntity.Builder()
  setSubscriptionType(
    SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
  )
  .setProviderPackageName("com.google.android.example")
  // Optional
  // December 30, 2025 12:00:00AM in milliseconds since epoch
  .setExpirationTimeMillis(1767052800000)
  .build()

প্রিমিয়াম সাবস্ক্রিপশন

যদি অ্যাপটি বহু-স্তরযুক্ত প্রিমিয়াম সাবস্ক্রিপশন প্যাকেজ অফার করে, যার মধ্যে সাধারণ স্তরের বাইরে প্রসারিত সামগ্রী বা বৈশিষ্ট্য অন্তর্ভুক্ত থাকে, তাহলে সাবস্ক্রিপশনে এক বা একাধিক এনটাইটেলমেন্ট যোগ করে এটি উপস্থাপন করুন।

এই অধিকারের নিম্নলিখিত ক্ষেত্রগুলি রয়েছে:

  1. Identifier : এই এনটাইটেলমেন্টের জন্য প্রয়োজনীয় আইডেন্টিফায়ার স্ট্রিং। এটি অবশ্যই Google TV-তে প্রকাশিত মিডিয়া প্রোভাইডার ফিডে প্রদত্ত এনটাইটেলমেন্ট আইডেন্টিফায়ারগুলির একটির সাথে মিলবে (মনে রাখবেন এটি আইডি ফিল্ড নয়)।
  2. Name : এটি সহায়ক তথ্য এবং এনটাইটেলমেন্ট মেলানোর জন্য ব্যবহৃত হয়। ঐচ্ছিক হলেও, একটি মানুষের পঠনযোগ্য এনটাইটেলমেন্ট নাম প্রদান করলে ডেভেলপার এবং সহায়তা দল উভয়ের জন্য ব্যবহারকারীর এনটাইটেলমেন্ট সম্পর্কে ধারণা বৃদ্ধি পায়। উদাহরণস্বরূপ: স্লিং অরেঞ্জ।
  3. ExpirationTimeMillis : ঐচ্ছিকভাবে এই এনটাইটেলমেন্টের মেয়াদ শেষ হওয়ার সময় মিলিসেকেন্ডে উল্লেখ করুন, যদি এটি সাবস্ক্রিপশনের মেয়াদ শেষ হওয়ার সময় থেকে আলাদা হয়। ডিফল্টরূপে, সাবস্ক্রিপশনের মেয়াদ শেষ হওয়ার সাথে সাথে এনটাইটেলমেন্টের মেয়াদ শেষ হয়ে যাবে।

নিম্নলিখিত নমুনা মিডিয়া প্রোভাইডার ফিড স্নিপেটের জন্য:

"actionAccessibilityRequirement": [
  {
    "@type": "ActionAccessSpecification",
    "category": "subscription",
    "availabilityStarts": "2022-06-01T07:00:00Z",
    "availabilityEnds": "2026-05-31T07:00:00Z",
    "requiresSubscription": {
    "@type": "MediaSubscription",
    // Don't match this string,
    // ID is only used to for reconciliation purpose
    "@id": "https://www.example.com/971bfc78-d13a-4419",

    // Don't match this, as name is only used for displaying purpose
    "name": "Example entitlement name",
    "commonTier": false,
    // match this identifier in your API. This is the crucial
    // entitlement identifier used for recommendation purpose.
    "identifier": "example.com:entitlementString1"
  }

নিম্নলিখিত উদাহরণটি একজন সাবস্ক্রাইব করা ব্যবহারকারীর জন্য একটি SubscriptionEntity তৈরি করে:

// Subscription with entitlements.
// The entitlement expires at the same time as its subscription.
val subscription = SubscriptionEntity.Builder()
  .setSubscriptionType(
    SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
  )
  .setProviderPackageName("com.google.android.example")
  // Optional
  // December 30, 2025 12:00:00AM in milliseconds
  .setExpirationTimeMillis(1767052800000)
  .addEntitlement(
    SubscriptionEntitlement.Builder()
    // matches with the identifier in media provider feed
    .setEntitlementId("example.com:entitlementString1")
    .setDisplayName("entitlement name1")
    .build()
  )
  .build()
// Subscription with entitlements
// The entitement has different expiration time from its subscription
val subscription = SubscriptionEntity.Builder()
  .setSubscriptionType(
    SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
  )
  .setProviderPackageName("com.google.android.example")
  // Optional
  // December 30, 2025 12:00:00AM in milliseconds
  .setExpirationTimeMillis(1767052800000)
  .addEntitlement(
    SubscriptionEntitlement.Builder()
    .setEntitlementId("example.com:entitlementString1")
    .setDisplayName("entitlement name1")
    // You may set the expiration time for entitlement
    // December 15, 2025 10:00:00 AM in milliseconds
    .setExpirationTimeMillis(1765792800000)
    .build())
  .build()

লিঙ্কড সার্ভিস প্যাকেজের জন্য সাবস্ক্রিপশন

যদিও সাবস্ক্রিপশন সাধারণত মূল অ্যাপের মিডিয়া প্রদানকারীর অন্তর্গত, সাবস্ক্রিপশনের মধ্যে লিঙ্ক করা পরিষেবা প্যাকেজের নাম উল্লেখ করে একটি সাবস্ক্রিপশনকে একটি লিঙ্ক করা পরিষেবা প্যাকেজের সাথে যুক্ত করা যেতে পারে।

নিম্নলিখিত কোড নমুনাটি কীভাবে ব্যবহারকারীর সাবস্ক্রিপশন তৈরি করতে হয় তা প্রদর্শন করে।

// Subscription for linked service package
val subscription = SubscriptionEntity.Builder()
  .setSubscriptionType(
    SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
  )
  .setProviderPackageName("com.google.android.example")
  // Optional
  // December 30, 2025 12:00:00AM in milliseconds since epoch
  .setExpirationTimeMillis(1767052800000)
  .build()

এছাড়াও, যদি ব্যবহারকারীর কোনও সহায়ক পরিষেবার জন্য অন্য সাবস্ক্রিপশন থাকে, তাহলে অন্য একটি সাবস্ক্রিপশন যোগ করুন এবং সেই অনুযায়ী লিঙ্ক করা পরিষেবা প্যাকেজের নাম সেট করুন।

// Subscription for linked service package
val linkedSubscription = Subscription.Builder()
  .setSubscriptionType(
    SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE
  )
  .setProviderPackageName("linked service package name")
  // Optional
  // December 30, 2025 12:00:00AM in milliseconds since epoch
  .setExpirationTimeMillis(1767052800000)
  .addBundledSubscription(
    BundledSubscription.Builder()
      .setBundledSubscriptionProviderPackageName(
        "bundled-subscription-package-name"
      )
      .setSubscriptionType(SubscriptionType.SUBSCRIPTION_TYPE_ACTIVE)
      .setExpirationTimeMillis(111)
      .addEntitlement(
        SubscriptionEntitlement.Builder()
        .setExpirationTimeMillis(111)
        .setDisplayName("Silver subscription")
        .setEntitlementId("subscription.tier.platinum")
        .build()
      )
      .build()
  )
    .build()

ঐচ্ছিকভাবে, একটি লিঙ্ক করা পরিষেবা সাবস্ক্রিপশনেও এনটাইটেলমেন্ট যোগ করুন।

সাবস্ক্রিপশন সেট প্রদান করুন

অ্যাপটি ফোরগ্রাউন্ডে থাকাকালীন কন্টেন্ট প্রকাশের কাজটি চালান।

একটি SubscriptionCluster অবজেক্ট প্রকাশ করতে AppEngagePublishClient ক্লাস থেকে publishSubscriptionCluster() পদ্ধতি ব্যবহার করুন।

ক্লায়েন্টটি শুরু করতে ভুলবেন না এবং "শুরু করা" নির্দেশিকায় বর্ণিত পরিষেবার প্রাপ্যতা পরীক্ষা করুন।

client.publishSubscription(
  PublishSubscriptionRequest.Builder()
    .setAccountProfile(accountProfile)
    .setSubscription(subscription)
    .build()
  )

ব্যবহারকারীর পরিষেবাটিতে শুধুমাত্র একটি সাবস্ক্রিপশন থাকা উচিত কিনা তা যাচাই করতে setSubscription() ব্যবহার করুন।

addLinkedSubscription() , অথবা addLinkedSubscriptions() ব্যবহার করুন যা লিঙ্ক করা সাবস্ক্রিপশনের তালিকা গ্রহণ করে, যাতে ব্যবহারকারী শূন্য বা তার বেশি লিঙ্ক করা সাবস্ক্রিপশন পেতে পারেন।

যখন পরিষেবাটি অনুরোধ গ্রহণ করে, তখন একটি নতুন এন্ট্রি তৈরি করা হয় এবং 60 দিন পরে পুরাতন এন্ট্রিটি স্বয়ংক্রিয়ভাবে মুছে ফেলা হয়। সিস্টেম সর্বদা সর্বশেষ এন্ট্রি ব্যবহার করে। কোনও ত্রুটির ক্ষেত্রে, সম্পূর্ণ অনুরোধটি প্রত্যাখ্যান করা হয় এবং বিদ্যমান অবস্থা বজায় রাখা হয়।

সাবস্ক্রিপশন আপ-টু-ডেট রাখুন

  1. পরিবর্তনের তাৎক্ষণিক আপডেট প্রদানের জন্য, যখনই কোনও ব্যবহারকারীর সাবস্ক্রিপশন অবস্থা সক্রিয়করণ, নিষ্ক্রিয়করণ, আপগ্রেড, ডাউনগ্রেডের মতো পরিবর্তন হয়, তখনই publishSubscriptionCluster কল করুন।

  2. চলমান নির্ভুলতার জন্য নিয়মিত যাচাইকরণ প্রদানের জন্য, প্রতি মাসে অন্তত একবার publishSubscriptionCluster কল করুন।

  3. ভিডিও আবিষ্কারের ডেটা মুছে ফেলার জন্য, ৬০ দিনের স্ট্যান্ডার্ড ধরে রাখার সময়কালের আগে Google TV সার্ভার থেকে ব্যবহারকারীর ডেটা ম্যানুয়ালি মুছে ফেলুন, client.deleteClusters পদ্ধতি ব্যবহার করুন। এটি অ্যাকাউন্ট প্রোফাইলের জন্য বা প্রদত্ত DeleteReason উপর নির্ভর করে সমগ্র অ্যাকাউন্টের জন্য বিদ্যমান সমস্ত ভিডিও আবিষ্কারের ডেটা মুছে ফেলে।

    নিম্নলিখিত কোড স্নিপেটটি দেখায় কিভাবে ব্যবহারকারীর সাবস্ক্রিপশন অপসারণ করতে হয়:

    // If the user logs out from your media app, you must make the following call
    // to remove subscription and other video discovery data from the current
    // google TV device.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
        .setAccountProfile(accountProfile)
      .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
      .build()
      )
    

    ব্যবহারকারী সম্মতি প্রত্যাহার করলে নিম্নলিখিত কোড স্নিপেটটি ব্যবহারকারীর সাবস্ক্রিপশন অপসারণের বিষয়টি প্রদর্শন করে:

    // If the user revokes the consent to share across device, make the call
    // to remove subscription and other video discovery data from all google
    // TV devices.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
        .setAccountProfile(accountProfile)
        .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT)
        .build()
    )
    

    নিম্নলিখিত কোডটি দেখায় যে ব্যবহারকারীর প্রোফাইল মুছে ফেলার সময় সাবস্ক্রিপশন ডেটা কীভাবে সরানো যায়।

    // If the user delete a specific profile, you must make the following call
    // to remove subscription data and other video discovery data.
    client.deleteClusters(
      new DeleteClustersRequest.Builder()
      .setAccountProfile(accountProfile)
      .setReason(DeleteReason.DELETE_REASON_ACCOUNT_PROFILE_DELETION)
      .build()
    )
    

পরীক্ষামূলক

এই বিভাগটি সাবস্ক্রিপশন বাস্তবায়ন পরীক্ষা করার জন্য ধাপে ধাপে নির্দেশিকা প্রদান করে। লঞ্চের আগে ডেটার নির্ভুলতা এবং সঠিক কার্যকারিতা যাচাই করুন।

ইন্টিগ্রেশন চেকলিস্ট প্রকাশ করুন

  1. প্রকাশনা তখনই হওয়া উচিত যখন অ্যাপটি সামনে থাকে এবং ব্যবহারকারী সক্রিয়ভাবে এর সাথে ইন্টারঅ্যাক্ট করে।

  2. প্রকাশ করুন যখন:

    • ব্যবহারকারী প্রথমবারের মতো লগ ইন করেন।
    • ব্যবহারকারী প্রোফাইল পরিবর্তন করে (যদি প্রোফাইল সমর্থিত হয়)।
    • ব্যবহারকারী নতুন সাবস্ক্রিপশন ক্রয় করেন।
    • ব্যবহারকারী সাবস্ক্রিপশন আপগ্রেড করে।
    • ব্যবহারকারীর সাবস্ক্রিপশনের মেয়াদ শেষ।
  3. প্রকাশনা ইভেন্টগুলিতে, logcat-এ অ্যাপটি সঠিকভাবে isServiceAvailable() এবং publishClusters() API কল করছে কিনা তা পরীক্ষা করুন।

  4. যাচাইকরণ অ্যাপে ডেটা দৃশ্যমান কিনা তা যাচাই করুন। যাচাইকরণ অ্যাপটিতে সাবস্ক্রিপশনটি একটি পৃথক সারি হিসেবে প্রদর্শন করা উচিত। যখন প্রকাশনা API চালু করা হয়, তখন ডেটা যাচাইকরণ অ্যাপে প্রদর্শিত হওয়া উচিত।

  5. অ্যাপে যান এবং নিম্নলিখিত প্রতিটি ক্রিয়া সম্পাদন করুন:

    • সাইন ইন করুন।
    • প্রোফাইলের মধ্যে স্যুইচ করুন (যদি সমর্থিত হয়)।
    • একটি নতুন সাবস্ক্রিপশন কিনুন।
    • একটি বিদ্যমান সাবস্ক্রিপশন আপগ্রেড করুন।
    • সাবস্ক্রিপশনের মেয়াদ শেষ করুন।

ইন্টিগ্রেশন যাচাই করুন

আপনার ইন্টিগ্রেশন পরীক্ষা করতে, যাচাইকরণ অ্যাপ ব্যবহার করুন।

  1. প্রতিটি ইভেন্টের জন্য, অ্যাপটি publishSubscription API ব্যবহার করেছে কিনা তা পরীক্ষা করুন। যাচাইকরণ অ্যাপে প্রকাশিত ডেটা যাচাই করুন। যাচাইকরণ অ্যাপে সবকিছু সবুজ আছে কিনা তা যাচাই করুন।
  2. যদি সত্তার সমস্ত তথ্য সঠিক হয়, তাহলে এটি সমস্ত সত্তায় "সব ভালো" সবুজ টিক চিহ্ন দেখায়।

    যাচাইকরণ অ্যাপের সাফল্যের স্ক্রিনশট
    চিত্র ১. সফল সাবস্ক্রিপশন
  3. যাচাইকরণ অ্যাপেও সমস্যাগুলি হাইলাইট করা হয়

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

    যাচাইকরণ অ্যাপ ত্রুটির বিবরণ স্ক্রিনশট
    চিত্র ৩. সাবস্ক্রিপশন ত্রুটি
  5. এনটাইটেলমেন্টের সমস্যাগুলি দেখতে, টিভি রিমোটটি ব্যবহার করে সেই নির্দিষ্ট এনটাইটেলের উপর ফোকাস করুন এবং সমস্যাগুলি দেখতে ক্লিক করুন। সমস্যাগুলি লাল রঙে হাইলাইট করা হয়েছে।

    যাচাইকরণ অ্যাপ ত্রুটির স্ক্রিনশট
    চিত্র ৪. সাবস্ক্রিপশন ত্রুটির বিবরণ