একটি ব্যবহারকারী সদস্যতা

প্রথম ধাপ হল ব্যবহারকারীর কাছ থেকে তাদের পুশ বার্তা পাঠানোর অনুমতি নেওয়া এবং তারপরে আমরা একটি PushSubscription হাত পেতে পারি।

এটি করার জন্য জাভাস্ক্রিপ্ট এপিআই যুক্তিসঙ্গতভাবে সোজা সামনে, তাই আসুন লজিক প্রবাহের মধ্য দিয়ে যাই।

বৈশিষ্ট্য সনাক্তকরণ

প্রথমে আমাদের বর্তমান ব্রাউজারটি আসলে পুশ মেসেজিং সমর্থন করে কিনা তা পরীক্ষা করতে হবে। আমরা দুটি সাধারণ চেক দিয়ে পুশ সমর্থিত কিনা তা পরীক্ষা করতে পারি।

  1. ন্যাভিগেটরে সার্ভিস ওয়ার্কারের জন্য চেক করুন।
  2. উইন্ডোতে PushManager চেক করুন।
if (!('serviceWorker' in navigator)) {
  // Service Worker isn't supported on this browser, disable or hide UI.
  return;
}

if (!('PushManager' in window)) {
  // Push isn't supported on this browser, disable or hide UI.
  return;
}

যদিও ব্রাউজার সমর্থন পরিষেবা কর্মী এবং পুশ মেসেজিং উভয়ের জন্যই দ্রুত বাড়ছে, উভয়ের জন্য বৈশিষ্ট্য সনাক্ত করা এবং ধীরে ধীরে উন্নত করা সর্বদা একটি ভাল ধারণা৷

একটি সেবা কর্মী নিবন্ধন

বৈশিষ্ট্য সনাক্তকরণের মাধ্যমে আমরা জানি যে পরিষেবা কর্মী এবং পুশ উভয়ই সমর্থিত। পরবর্তী ধাপ হল আমাদের পরিষেবা কর্মীকে "নিবন্ধন" করা।

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

একটি পরিষেবা কর্মী নিবন্ধন করতে, navigator.serviceWorker.register() কল করুন, আমাদের ফাইলের পাথ দিয়ে যান৷ তাই ভালো:

function registerServiceWorker() {
  return navigator.serviceWorker
    .register('/service-worker.js')
    .then(function (registration) {
      console.log('Service worker successfully registered.');
      return registration;
    })
    .catch(function (err) {
      console.error('Unable to register service worker.', err);
    });
}

এই ফাংশনটি ব্রাউজারকে বলে যে আমাদের কাছে একটি পরিষেবা কর্মী ফাইল আছে এবং এটি কোথায় অবস্থিত। এই ক্ষেত্রে, পরিষেবা কর্মী ফাইলটি /service-worker.js এ রয়েছে। register() কল করার পর দৃশ্যের আড়ালে ব্রাউজার নিম্নলিখিত পদক্ষেপগুলি গ্রহণ করবে:

  1. পরিষেবা কর্মী ফাইল ডাউনলোড করুন।

  2. জাভাস্ক্রিপ্ট চালান।

  3. যদি সবকিছু সঠিকভাবে চলে এবং কোন ত্রুটি না থাকে, তাহলে register() দ্বারা প্রত্যাবর্তিত প্রতিশ্রুতি সমাধান হবে। কোনো ধরনের ত্রুটি থাকলে প্রতিশ্রুতি প্রত্যাখ্যান করা হবে।

register() প্রত্যাখ্যান করলে, Chrome DevTools-এ টাইপ/ত্রুটির জন্য আপনার JavaScript দুবার চেক করুন।

যখন register() সমাধান করে, এটি একটি ServiceWorkerRegistration প্রদান করে। আমরা PushManager API অ্যাক্সেস করতে এই নিবন্ধনটি ব্যবহার করব।

PushManager API ব্রাউজার সামঞ্জস্য

ব্রাউজার সমর্থন

  • 42
  • 17
  • 44
  • 16

উৎস

অনুমতি চাইছে

আমরা আমাদের পরিষেবা কর্মীকে নিবন্ধিত করেছি এবং ব্যবহারকারীর সদস্যতা নিতে প্রস্তুত, পরবর্তী ধাপ হল ব্যবহারকারীর কাছ থেকে তাদের পুশ বার্তা পাঠানোর অনুমতি নেওয়া।

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

function askPermission() {
  return new Promise(function (resolve, reject) {
    const permissionResult = Notification.requestPermission(function (result) {
      resolve(result);
    });

    if (permissionResult) {
      permissionResult.then(resolve, reject);
    }
  }).then(function (permissionResult) {
    if (permissionResult !== 'granted') {
      throw new Error("We weren't granted permission.");
    }
  });
}

উপরের কোডে, কোডের গুরুত্বপূর্ণ স্নিপেট হল Notification.requestPermission() এ কল করা। এই পদ্ধতিটি ব্যবহারকারীকে একটি প্রম্পট প্রদর্শন করবে:

ডেস্কটপ এবং মোবাইল ক্রোমে অনুমতি প্রম্পট।

একবার ব্যবহারকারী অনুমতি প্রম্পটের সাথে Allow, Block, বা শুধু বন্ধ করে চাপ দিয়ে ইন্টারঅ্যাক্ট করলে, আমাদের একটি স্ট্রিং হিসাবে ফলাফল দেওয়া হবে: 'granted' , 'default' বা 'denied'

উপরের নমুনা কোডে, askPermission() দ্বারা প্রত্যাবর্তিত প্রতিশ্রুতি যদি অনুমতি দেওয়া হয় তা সমাধান করে, অন্যথায় আমরা প্রতিশ্রুতি প্রত্যাখ্যান করার জন্য একটি ত্রুটি নিক্ষেপ করি।

ব্যবহারকারী যদি 'ব্লক' বোতামে ক্লিক করে তাহলে একটি প্রান্তের ক্ষেত্রে আপনাকে পরিচালনা করতে হবে। যদি এটি ঘটে তবে আপনার ওয়েব অ্যাপ ব্যবহারকারীর কাছে আবার অনুমতি চাইতে পারবে না। তাদের অনুমতির অবস্থা পরিবর্তন করে আপনার অ্যাপটিকে ম্যানুয়ালি "আনব্লক" করতে হবে, যা একটি সেটিংস প্যানেলে সমাহিত। আপনি কীভাবে এবং কখন ব্যবহারকারীর অনুমতি চান সে সম্পর্কে সাবধানে চিন্তা করুন, কারণ যদি তারা ব্লক ক্লিক করে, তাহলে সিদ্ধান্তটি ফিরিয়ে আনার এটি একটি সহজ উপায় নয়।

ভাল খবর হল যে অধিকাংশ ব্যবহারকারী অনুমতি দিতে খুশি হন যতক্ষণ না তারা জানেন কেন অনুমতি চাওয়া হচ্ছে।

আমরা পরে দেখব কিভাবে কিছু জনপ্রিয় সাইট অনুমতি চায়।

PushManager এর সাথে একজন ব্যবহারকারীকে সাবস্ক্রাইব করুন

একবার আমাদের পরিষেবা কর্মী নিবন্ধিত হয়ে গেলে এবং আমরা অনুমতি পেয়ে গেলে, আমরা registration.pushManager.subscribe() কল করে একজন ব্যবহারকারীকে সদস্যতা নিতে পারি।

function subscribeUserToPush() {
  return navigator.serviceWorker
    .register('/service-worker.js')
    .then(function (registration) {
      const subscribeOptions = {
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(
          'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
        ),
      };

      return registration.pushManager.subscribe(subscribeOptions);
    })
    .then(function (pushSubscription) {
      console.log(
        'Received PushSubscription: ',
        JSON.stringify(pushSubscription),
      );
      return pushSubscription;
    });
}

subscribe() পদ্ধতিতে কল করার সময়, আমরা একটি বিকল্প অবজেক্টে পাস করি, যা প্রয়োজনীয় এবং ঐচ্ছিক উভয় প্যারামিটার নিয়ে গঠিত।

আসুন আমরা পাস করতে পারি এমন সমস্ত বিকল্প দেখি।

userVisibleOnly অপশন

যখন পুশ প্রথম ব্রাউজারগুলিতে যোগ করা হয়েছিল, তখন ডেভেলপাররা একটি পুশ বার্তা পাঠাতে সক্ষম হবেন এবং একটি বিজ্ঞপ্তি দেখাবেন না তা নিয়ে অনিশ্চয়তা ছিল। এটিকে সাধারণত নীরব ধাক্কা হিসাবে উল্লেখ করা হয়, কারণ ব্যবহারকারী জানেন না যে পটভূমিতে কিছু ঘটেছে।

উদ্বেগের বিষয় ছিল যে বিকাশকারীরা ব্যবহারকারীর অজান্তেই একটি চলমান ভিত্তিতে ব্যবহারকারীর অবস্থান ট্র্যাক করার মতো বাজে কাজ করতে পারে।

এই পরিস্থিতি এড়াতে এবং এই বৈশিষ্ট্যটিকে কীভাবে সর্বোত্তম সমর্থন করা যায় তা বিবেচনা করার জন্য নির্দিষ্ট লেখকদের সময় দেওয়ার জন্য, userVisibleOnly বিকল্পটি যোগ করা হয়েছিল এবং true মান দিয়ে পাস করা ব্রাউজারের সাথে একটি প্রতীকী চুক্তি যে ওয়েব অ্যাপ প্রতিবার পুশ করার সময় একটি বিজ্ঞপ্তি দেখাবে। প্রাপ্ত হয় (অর্থাৎ কোন নীরব ধাক্কা)

এই মুহুর্তে আপনাকে অবশ্যই true একটি মান পাস করতে হবে। আপনি যদি userVisibleOnly কী অন্তর্ভুক্ত না করেন বা false পাস করেন তবে আপনি নিম্নলিখিত ত্রুটিটি পাবেন:

ক্রোম বর্তমানে শুধুমাত্র সাবস্ক্রিপশনের জন্য Push API সমর্থন করে যার ফলে ব্যবহারকারী-দৃশ্যমান বার্তা আসবে। আপনি পরিবর্তে pushManager.subscribe({userVisibleOnly: true}) কল করে এটি নির্দেশ করতে পারেন। আরও বিস্তারিত জানার জন্য https://goo.gl/yqv4Q4 দেখুন।

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

অ্যাপ্লিকেশন সার্ভারকি বিকল্প

আমরা পূর্ববর্তী বিভাগে সংক্ষেপে "অ্যাপ্লিকেশন সার্ভার কী" উল্লেখ করেছি। "অ্যাপ্লিকেশন সার্ভার কী" একটি পুশ পরিষেবা দ্বারা ব্যবহার করা হয় একটি ব্যবহারকারীর সাবস্ক্রাইব করা অ্যাপ্লিকেশনটিকে সনাক্ত করতে এবং নিশ্চিত করতে যে একই অ্যাপ্লিকেশন সেই ব্যবহারকারীকে মেসেজ করছে৷

অ্যাপ্লিকেশন সার্ভার কীগুলি একটি সর্বজনীন এবং ব্যক্তিগত কী জোড়া যা আপনার অ্যাপ্লিকেশনের জন্য অনন্য। প্রাইভেট কী আপনার অ্যাপ্লিকেশনের কাছে গোপন রাখা উচিত এবং সর্বজনীন কীটি অবাধে ভাগ করা যেতে পারে।

subscribe() কলে পাস করা applicationServerKey বিকল্পটি অ্যাপ্লিকেশনটির সর্বজনীন কী। ব্যবহারকারীর সদস্যতা নেওয়ার সময় ব্রাউজার এটিকে একটি পুশ পরিষেবাতে পাস করে, যার অর্থ পুশ পরিষেবাটি ব্যবহারকারীর PushSubscription সাথে আপনার অ্যাপ্লিকেশনের সর্বজনীন কী টাই করতে পারে৷

নীচের চিত্রটি এই পদক্ষেপগুলিকে চিত্রিত করে।

  1. আপনার ওয়েব অ্যাপটি একটি ব্রাউজারে লোড হয়েছে এবং আপনি আপনার সর্বজনীন অ্যাপ্লিকেশন সার্ভার কী পাস করে subscribe() কল করেন।
  2. ব্রাউজারটি তখন একটি পুশ পরিষেবার কাছে একটি নেটওয়ার্ক অনুরোধ করে যারা একটি এন্ডপয়েন্ট তৈরি করবে, এই এন্ডপয়েন্টটিকে অ্যাপ্লিকেশন পাবলিক কী এর সাথে যুক্ত করবে এবং ব্রাউজারে এন্ডপয়েন্ট ফিরিয়ে দেবে।
  3. ব্রাউজার এই এন্ডপয়েন্টটিকে PushSubscription এ যোগ করবে, যা subscribe() প্রতিশ্রুতির মাধ্যমে ফেরত দেওয়া হয়।

সাবস্ক্রাইব পদ্ধতিতে পাবলিক অ্যাপ্লিকেশান সার্ভার কী-এর ইলাস্ট্রেশন ব্যবহার করা হয়।

আপনি যখন পরে একটি পুশ বার্তা পাঠাতে চান, তখন আপনাকে একটি অনুমোদন শিরোনাম তৈরি করতে হবে যাতে আপনার অ্যাপ্লিকেশন সার্ভারের ব্যক্তিগত কী দিয়ে স্বাক্ষরিত তথ্য থাকবে৷ যখন পুশ পরিষেবা একটি পুশ বার্তা পাঠানোর জন্য একটি অনুরোধ পায়, তখন এটি অনুরোধ প্রাপ্তির শেষ পয়েন্টের সাথে লিঙ্কযুক্ত পাবলিক কীটি দেখে এই স্বাক্ষরিত অনুমোদন শিরোনামটিকে যাচাই করতে পারে৷ স্বাক্ষরটি বৈধ হলে পুশ পরিষেবাটি জানে যে এটি অবশ্যই প্রাইভেট কী সহ অ্যাপ্লিকেশন সার্ভার থেকে এসেছে। এটি মূলত একটি নিরাপত্তা ব্যবস্থা যা অন্য কেউ একটি অ্যাপ্লিকেশন ব্যবহারকারীদের কাছে বার্তা পাঠাতে বাধা দেয়।

একটি বার্তা পাঠানোর সময় ব্যক্তিগত অ্যাপ্লিকেশন সার্ভার কী কীভাবে ব্যবহার করা হয়

প্রযুক্তিগতভাবে, applicationServerKey ঐচ্ছিক। যাইহোক, ক্রোমে সবচেয়ে সহজ বাস্তবায়নের জন্য এটি প্রয়োজন, এবং অন্যান্য ব্রাউজারে ভবিষ্যতে এটির প্রয়োজন হতে পারে। এটা ফায়ারফক্সে ঐচ্ছিক।

যে স্পেসিফিকেশনটি সংজ্ঞায়িত করে যে অ্যাপ্লিকেশন সার্ভার কী কী হওয়া উচিত তা হল VAPID স্পেক । যখনই আপনি "অ্যাপ্লিকেশন সার্ভার কী" বা "VAPID কী" উল্লেখ করে কিছু পড়েন, শুধু মনে রাখবেন যে তারা একই জিনিস।

কিভাবে অ্যাপ্লিকেশন সার্ভার কী তৈরি করতে হয়

আপনি web-push-codelab.glitch.me পরিদর্শন করে অ্যাপ্লিকেশন সার্ভার কীগুলির একটি সর্বজনীন এবং ব্যক্তিগত সেট তৈরি করতে পারেন বা আপনি নিম্নলিখিতগুলি করে কী তৈরি করতে ওয়েব-পুশ কমান্ড লাইন ব্যবহার করতে পারেন:

    $ npm install -g web-push
    $ web-push generate-vapid-keys

আপনার অ্যাপ্লিকেশনের জন্য আপনাকে শুধুমাত্র একবার এই কীগুলি তৈরি করতে হবে, শুধু নিশ্চিত করুন যে আপনি ব্যক্তিগত কীটি ব্যক্তিগত রাখবেন৷ (হ্যাঁ, আমি শুধু বলেছি।)

অনুমতি এবং সদস্যতা()

subscribe() কল করার একটি পার্শ্ব প্রতিক্রিয়া আছে। subscribe() কল করার সময় আপনার ওয়েব অ্যাপে বিজ্ঞপ্তি দেখানোর অনুমতি না থাকলে, ব্রাউজার আপনার জন্য অনুমতির জন্য অনুরোধ করবে। আপনার UI যদি এই প্রবাহের সাথে কাজ করে তবে এটি কার্যকর, তবে আপনি যদি আরও নিয়ন্ত্রণ চান (এবং আমি মনে করি বেশিরভাগ বিকাশকারীরা করবে), আমরা আগে ব্যবহার করা Notification.requestPermission() API-এ আটকে থাকি।

একটি PushSubscription কি?

আমরা subscribe() কল করি, কিছু বিকল্পে পাস করি এবং বিনিময়ে আমরা একটি প্রতিশ্রুতি পাই যা একটি PushSubscription সমাধান করে যার ফলে কিছু কোড আসে:

function subscribeUserToPush() {
  return navigator.serviceWorker
    .register('/service-worker.js')
    .then(function (registration) {
      const subscribeOptions = {
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(
          'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
        ),
      };

      return registration.pushManager.subscribe(subscribeOptions);
    })
    .then(function (pushSubscription) {
      console.log(
        'Received PushSubscription: ',
        JSON.stringify(pushSubscription),
      );
      return pushSubscription;
    });
}

PushSubscription অবজেক্টে সেই ব্যবহারকারীকে একটি পুশ বার্তা পাঠানোর জন্য প্রয়োজনীয় সমস্ত প্রয়োজনীয় তথ্য রয়েছে। আপনি JSON.stringify() ব্যবহার করে বিষয়বস্তু মুদ্রণ করলে, আপনি নিম্নলিখিতগুলি দেখতে পাবেন:

    {
      "endpoint": "https://some.pushservice.com/something-unique",
      "keys": {
        "p256dh":
    "BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
        "auth":"FPssNDTKnInHVndSTdbKFw=="
      }
    }

endpoint হল পুশ সার্ভিস URL। একটি পুশ বার্তা ট্রিগার করতে, এই URL-এ একটি POST অনুরোধ করুন৷

keys অবজেক্টে একটি পুশ বার্তার মাধ্যমে পাঠানো বার্তা ডেটা এনক্রিপ্ট করতে ব্যবহৃত মান রয়েছে (যা আমরা এই বিভাগে পরে আলোচনা করব)।

আপনার সার্ভারে একটি সদস্যতা পাঠান

একবার আপনার একটি পুশ সাবস্ক্রিপশন হয়ে গেলে আপনি এটি আপনার সার্ভারে পাঠাতে চাইবেন। আপনি কীভাবে এটি করবেন তা আপনার উপর নির্ভর করে তবে একটি ছোট টিপ হল সাবস্ক্রিপশন অবজেক্ট থেকে প্রয়োজনীয় সমস্ত ডেটা পেতে JSON.stringify() ব্যবহার করা। বিকল্পভাবে আপনি একই ফলাফল ম্যানুয়ালি একত্রিত করতে পারেন যেমন:

const subscriptionObject = {
  endpoint: pushSubscription.endpoint,
  keys: {
    p256dh: pushSubscription.getKeys('p256dh'),
    auth: pushSubscription.getKeys('auth'),
  },
};

// The above is the same output as:

const subscriptionObjectToo = JSON.stringify(pushSubscription);

সাবস্ক্রিপশন পাঠানো ওয়েব পেজে এভাবে করা হয়:

function sendSubscriptionToBackEnd(subscription) {
  return fetch('/api/save-subscription/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(subscription),
  })
    .then(function (response) {
      if (!response.ok) {
        throw new Error('Bad status code from server.');
      }

      return response.json();
    })
    .then(function (responseData) {
      if (!(responseData.data && responseData.data.success)) {
        throw new Error('Bad response from server.');
      }
    });
}

নোড সার্ভার এই অনুরোধটি গ্রহণ করে এবং পরবর্তীতে ব্যবহারের জন্য ডেটাবেসে ডেটা সংরক্ষণ করে।

app.post('/api/save-subscription/', function (req, res) {
  if (!isValidSaveRequest(req, res)) {
    return;
  }

  return saveSubscriptionToDatabase(req.body)
    .then(function (subscriptionId) {
      res.setHeader('Content-Type', 'application/json');
      res.send(JSON.stringify({data: {success: true}}));
    })
    .catch(function (err) {
      res.status(500);
      res.setHeader('Content-Type', 'application/json');
      res.send(
        JSON.stringify({
          error: {
            id: 'unable-to-save-subscription',
            message:
              'The subscription was received but we were unable to save it to our database.',
          },
        }),
      );
    });
});

আমাদের সার্ভারে PushSubscription বিশদ সহ আমরা যখনই চাই আমাদের ব্যবহারকারীকে একটি বার্তা পাঠাতে ভাল।

FAQs

কিছু সাধারণ প্রশ্ন লোকেরা এই সময়ে জিজ্ঞাসা করেছে:

আমি কি ব্রাউজার ব্যবহার করে পুশ পরিষেবা পরিবর্তন করতে পারি?

না। পুশ পরিষেবাটি ব্রাউজার দ্বারা নির্বাচন করা হয়েছে এবং আমরা subscribe() কলের মাধ্যমে দেখেছি, ব্রাউজার পুশসাবস্ক্রিপশন তৈরির বিশদগুলি পুনরুদ্ধার করার জন্য পুশ পরিষেবার কাছে নেটওয়ার্ক অনুরোধ করবে৷

প্রতিটি ব্রাউজার একটি আলাদা পুশ পরিষেবা ব্যবহার করে, তাদের কি আলাদা API নেই?

সমস্ত পুশ পরিষেবা একই API আশা করবে।

এই সাধারণ APIটিকে ওয়েব পুশ প্রোটোকল বলা হয় এবং একটি পুশ বার্তা ট্রিগার করার জন্য আপনার অ্যাপ্লিকেশনকে যে নেটওয়ার্ক অনুরোধ করতে হবে তা বর্ণনা করে।

আমি যদি একজন ব্যবহারকারীকে তাদের ডেস্কটপে সাবস্ক্রাইব করি, তাহলে তারা কি তাদের ফোনেও সাবস্ক্রাইব করবে?

দুর্ভাগ্যবশত না. একজন ব্যবহারকারীকে অবশ্যই প্রতিটি ব্রাউজারে পুশ করার জন্য নিবন্ধন করতে হবে যাতে তারা বার্তা পেতে চায়। এটিও লক্ষণীয় যে এর জন্য প্রতিটি ডিভাইসে ব্যবহারকারীর অনুমতির প্রয়োজন হবে৷

পরের দিকে কোথায় যেতে হবে

কোড ল্যাব