ایجاد پروژه آزمایشی برای ارسال و دریافت push notification (قسمت دوم)

ایجاد پروژه آزمایشی برای ارسال و دریافت push notification (قسمت دوم)

در قسمت قبل از سری مقالات «آموزش ارسال notification در یک سایت»، دو پروژه راه اندازی کردیم تا به وسیله ی آنها فرایند ارسال و دریافت push notification را برررسی کنیم. یک پروژه برای سرور و یک پروژه ی دیگر برای client. همانطور که در قسمت قبل مرحله به مرحله پیش رفتیم، ساختار فایل پروژه ای که برای سمت client ایجاد کردیم به این شکل بود:

در ادامه ی این آموزش می خواهیم با هم این کد را تکمیل کنیم.

مرحله ی اول: ایجاد رابط کاربری مناسب

در این بخش، با مراجعه به پروژه ای که در قسمت قبل برای client ایجاد کرده ایم، رابط کاربری دلخواهمان را به آن اضافه می کنیم.

در مسیر پروژه فایل App.vue را به شکل زیر تغییر می دهیم:

<template>
  <div class="app-container">
    <header>
      <h6 class="welcome-message">Welcome to sokanacademy.com</h6>
      <h1>Test push notification project (client side)</h1>
    </header>
    <main>
      <section>
        <h2>Service worker</h2>
        <div class="buttons-container">
          <button @click="registerServiceWorker"
                  class="active-btn">Register service worker
          </button>
          <button @click="unRegisterServiceWorker"
                  class="deactive-btn">Unregister service worker
          </button>
        </div>
      </section>
      <section>
        <h2>Subscription</h2>
        <div class="buttons-container">
          <button @click="subscribeToPush"
                  class="active-btn">Subscribe to push
          </button>
          <button @click="unSubscribeToPush"
                  class="deactive-btn">Unsubscribe from push
          </button>
        </div>
      </section>
      <section>
        <h2>Notifications</h2>
        <div class="buttons-container">
          <button @click="notifyMe"
                  class="active-btn">Notify me
          </button>
          <button @click="notifyAll"
                  class="deactive-btn">Notify all
          </button>
        </div>
      </section>
    </main>
    <footer>
      visit us at
      <a href="https://sokanacademy.com">sokanacademy.com</a>
    </footer>
  </div>
</template>

<script>

export default {
  name: 'App',
  data: () => ({}),
  methods: {
    async registerServiceWorker() {
      
    },
    async unRegisterServiceWorker() {

    },
    async subscribeToPush() {

    },
    async unSubscribeToPush() {

    },
    async notifyMe() {

    },
    async notifyAll() {

    },
  }
}
</script>

<style>
body {
  font-family: sora;
}

.welcome-message {
  font-size: 1.2rem;
}

.app-container {
  padding-top: 50px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

header {
  margin-bottom: 50px;
}

section {
  margin-bottom: 80px;
  width: 400px;
}

section .buttons-container {
  display: flex;
  justify-content: space-between;
}

.buttons-container button {
  height: 40px;
  padding-top: 10px;
  padding-bottom: 10px;
  border-radius: 15px;
  cursor: pointer;
  width: 175px;
}

.active-btn {
  background-color: #0a0328;
  color: white;
}

.deactive-btn {
  background-color: #fcbf17;
}

footer {
  margin-top: 100px;
}
</style>

اگر مطابق آموزش پیش رفته باشید و پروژه را ایجاد کرده باشید، می توانید کد های همین قسمت را در پروژه خود copy/paste کنید و به صورت مستقیم از آن استفاده کنید.

(فایل های .vue معمولاً از سه بخش script ،template و style تشکیل شده اند. در بخش template تگ های html قرار می گیرند، در بخش script منطق مربوط به کامپوننت vue قرار می گیرد و در بخش style نیز نقش های css ای که می خواهیم به عناصر مختلف صفحه بدهیم جا می گیرد. ما در این آموزش قصد پرداختن به ساختار ها و مفاهیم vue.js را نداریم. اما اگر علاقه مند به یادگیری آن هستید، می توانید به دوره ی آموزش vue.js در سایت سکان آکادمی مراجعه کنید.)

پس از اضافه کردن کد بالا و با در حال اجرا داشتن دستور npm run serve در ترمینال، می توانید با مراجعه به آدرس localhost:8080 در مرورگر خود صفحه ای را که با هم ایجاد کرده ایم ببینید:

مرحله ی دوم: register کردن service worker

معمولاً در وبسایت ها و خصوصاً پروژه های سمت client، یک پوشه با نام هایی چون public یا static وجود دارد. این پوشه محلی ست که قرار است آن دسته از فایل هایی را در خود ذخیره کند که به صورت مستقیم serve می شوند و قبل از serve شدن سایت نیازی به کامپایل شدن یا طی فرایند خاصی ندارند. معمولاً فایل هایی مانند آیکون های وبسایت، فایل های کمکی، برخی از استایل ها و فایل مربوط به service worker در این پوشه قرار می گیرند.

همانطور که در بالا دیدیم، در ساختار فایل ما نیز یک پوشه به نام public وجود دارد که عهده دار این وظیفه است. ما فایل service worker خود را در آن قرار می دهیم.

از طرفی می دانیم که برای اضافه کردن فایل یک service worker نیاز داریم که ابتدا آن را در کد خود register کنیم.

به این منظور یک فایل خالی به نام service-worker.js در پوشه ی public ایجاد می کنیم. (فعلاً با محتوای این فایل کاری نداریم و بعداً کد آن را خواهیم نوشت.)

همان طور که در کد بالا می بینید، به ازای کلیک شدن دکمه ی Register service worker یک متد به نام registerServiceWorker صدا می خورد. حال محتوای این متد را به گونه ای تغییر می دهیم تا فایل service-worker.js را register کند:

async registerServiceWorker() {
  try {
    await navigator.serviceWorker.register('./service-worker.js');
    alert('Service worker registered successfully');
  } catch (err) {
    alert('There were some error on registering the service worker');
  }
},

اگر مراحلی که در بالا ذکر شد را به درستی طی کرده باشید، با مراجعه به ابزار توسعه ی مرورگر خود و مشاهده ی service worker های فعال، می توانید فایل service-worker.js را نیز مشاهده کنید، به این معنی که فایل service worker به درستی به کد ما اضافه شده است.

(در قسمت های قبل توضیح دادیم که برخی مرورگر ها از service worker پشتیبانی نمی کنند، از این رو می توانستیم با قرار دادن یک شرط، چک کنیم که آیا مرورگر کاربر از service worker پشتیبانی می کند یا خیر. که در این قطعه کد از قرار دادن این بخش صرف نظر کرده ایم)

حال متد کنترل کننده ی اتفاق کلیک شدن روی دکمه ی Unregister service worker را با هم می نویسیم. این دکمه قرار است service worker ای را که به برنامه اضافه کرده ایم، حذف کند. پس متد unRegisterServiceWorker را این گونه تغییر می دهیم:

async unRegisterServiceWorker() {
  try {
    const registration = await navigator.serviceWorker.getRegistration();
    await registration.unregister();
    alert('Service worker unregistered');
  } catch (err) {
    alert('There were some error on registering the service worker');
  }
},

تا کنون پروژه ای داریم که یک فایل service worker را با زدن دکمه ای به برنامه اضافه می کند(register می کند)، و با دکمه ای دیگر آن را از برنامه حذف می کند (unregister می کند).

مرحله ی سوم: مشترک شدن روی نوتیفیکیشن های وبسایت

همان طور که در کد و هم چنین تصویر برنامه دیدیم، ما دو دکمه با نام های Subscribe to push و Unsubscribe from push داریم. این دو دکمه قرار است وظیفه ی مشترک کردن مرورگر ما روی push service مربوطه را انجام دهند.

اما چنان که در قسمت های قبل گفتیم، نیاز داریم که ابتدا دو کلید، یکی کلید عمومی و دیگری کلید خصوصی را برای پیاده سازی ساختار احراز هویت پیام ها ایجاد کنیم.

به این منظور از یک پکیج معروف به نام web-push استفاده می کنیم:

npx web-push generate-vapid-keys

(برای کسب اطلاعات بیشتر در مورد دستور npx می توانید به مقاله ی مربوط به آن در سکان آکادمی مراجعه کنید.)

دستور بالا با استفاده از پکیج web-push کلید های مورد نیاز پروژه را برای ما ایجاد خواهد کرد. خروجی این دستور مانند تصویر زیر است:

ما باید کلید عمومی ایجاد شده را در جایی در اپلیکیشن client خود نگه داریم. هم چنین هر دو کلید را برای استفاده های بعدی، در سمت سرور نیز نگهداری کنیم. به این منظور مقادیر بالا را در یک فایل env. به عنوان متغیر محیطی (environment variable) تعریف می کنیم تا بعداً بتوانیم از آنها استفاده کنیم.

پس یک فایل به نام env. در مسیر اصلی پروژه ایجاد می کنیم و در آن مقدار کلید عمومی تولید شده را به متغیری با نام VUE_APP_VAPID_PUBLIC_KEY می دهیم:

VUE_APP_VAPID_PUBLIC_KEY="BLAhpQMrurfVGr1LJ28x0KbWPQlC00VC7G5yJjKESOWcTyffj5HVekNJVdq6_-ajLe-8Y6YVplW70610xy0ewgs"

(دلیل نامگذاری این متغیر محیطی با پیشوند VUE_APP این است که ما پروژه را با vue cli راه اندازی کرده ایم که طبق تنظیمات پیش فرض آن، در فایل env. تمامی متغیر هایی که با VUE_APP آغاز می شوند، در برنامه قابل دسترسی هستند. اگر از vue cli استفاده نمی کنید، می توانید به کمک پکیج dotenv متغیر های محیطی خود را در دسترس فایل های پروژه قرار دهید. لازم به ذکر است این که ما از متغیر محیطی برای نگه داشتن مقدار کلید عمومی استفاده کرده ایم، به دلیل استاندارد و اصولی بودن، و امنیت و جداسازی محیط های مختلف برای توسعه و استقرار محصول است، اما هیچ اجبار یا لزومی به استفاده از متغیر محیطی نیست.)

(برای کسب اطلاعات بیشتر در مورد پکیج dotenv نیز می توانید به آدرس اصلی آن در سایت npm مراجعه کنید)

در این مقاله یک رابط کاربری مناسب برای آزمایش روند ارسال و دریافت نوتیفیکیشن ایجاد کردیم و همچنین منطق register کردن service worker به پروژه و یا حذف کردن آن را با هم دیدیم. در انتها نیز کلید های مورد نیاز این فرایند را ایجاد کردیم و آن را به متغیر های محیطی برنامه اضافه کردیم.

در قسمت بعد به شرح چگونگی مشترک شدن مرورگر روی پوش نوتیفیکیشن ها می پردازیم و توضیح می دهیم که متد‍‌های subscribeToPush و UnsubscribeFromPush چگونه نوشته می شوند و چه کاری انجام می‌دهند.

از بهترین نوشته‌های کاربران سکان آکادمی در سکان پلاس


online-support-icon