ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Node.js로 간단한 Push 만들기
    SERVER DEVELOPMENT/NodeJS 2021. 5. 2. 14:07

    위와 같이 mac이나 윈도우에 푸쉬 알람오는 것을 간단하게 node.js로 만들어보겠습니다.

     

    1. 터미널에서 push_notification이라는 폴더를 생성합니다.

    mkdir push_notification

    2. npm init -y로 package.json을 생성해주시고 다음 패키지들을 설치해주세요.

    npm i web-push express body-parser

    3. 설치되셨다면 index.js파일을 만들어서 다음과 같이 작성해보세요.

    const express = require("express");
    const webpush = require("web-push");
    const bodyParser = require("body-parser");
    const path = require("path");
    
    const app = express();
    

     

    4. push key를 생성해봅시다. 터미널에서 다음과 같이 입력해보세요.

    ./node_modules/.bin/web-push generate-vapid-keys
    

     그러면 public key와 private key가 추출되게 됩니다.

    index.js에 해당 내용을 세팅해줍니다.

    ...
    
    const publicVapidKey = '방금 추출된 public Key';
    const privateVapidKey = '방금 추출된 private key';
    
    webpush.setVapidDetails('mailto:copstyle@naver.com', publicVapidKey, privateVapidKey);

    mailto 정보는 실제로 푸시 트리거 요청의 일부로 웹 푸시 서비스에 전송됩니다.

    이것이 수행되는 이유는 웹 푸시 서비스가 발신자와 연락해야하는 경우 발신자와 연락 할 수있는 몇 가지 정보를 가지기 때문입니다.

     

    5. Subscibe Route를 생성해서 노티피케이션 객체를 payload형태로 전달합니다.

    ...
    
    const app = express();
    
    app.use(bodyParser.json());
    
    
    const publicVapidKey =
    ...
    
    webpush.setVapidDetails(
        "mailto:copstyle86@gmail.com",
        publicVapidKey,
        privateVapidKey
    );
    
    // Subscribe Route
    app.post("/subscribe", (req, res) => {
        //Get pushSubscription Object
        const subscription = req.body;
    
        // Send 201 - resource created
        res.status(201).json({});
    
        // Create payload
        const payload = JSON.stringify({ title: "Push Test" });
    
        // Pass Object into sendNotification
        webpush
            .sendNotification(subscription, payload)
            .catch((err) => console.error(err));
    });
    
    const port = 5000;
    
    app.listen(port, () => console.log(`server started on port ${port}`));
    

    6. static 폴더를 설정해주세요 ~ 클라이언트를 만들 예정입니다.

    ...
    
    const app = express();
    
    // Set Static path
    app.use(express.static(path.join(__dirname, "client")));
    
    app.use(bodyParser.json());
    ...

    7. node index.js로 실행하여 서버를 띄워놓습니다.

     

    8. client 폴더를 만들어서 index.html, client.js, worker.js 생성

     

    // index.html
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Push Notification</title>
    </head>
    
    <body>
        <h1>Push Notification</h1>
        <script src="client.js"></script>
    </body>
    
    </html>

    http://localhost:5000 을 접속해서 확인해보세요!

     

    9. client.js 작성

    const publicVapidKey ="자신의 Public key";
    
    // Check for service worker
    if ("serviceWorker" in navigator) {
        send().catch((err) => console.error(err));
    }
    
    // 서비스워커 등록, 푸쉬 등록, 푸쉬 보내기
    async function send() {
        // 서비스워커 등록
        console.log("서비스워커 등록중...");
        const register = await navigator.serviceWorker.register("/worker.js", {
            scope: "/",
        });
    
        console.log("서비스워커 등록됨");
    
        // 푸쉬 등록
        console.log("푸쉬 등록중..");
        const subscription = await register.pushManager.subscribe({
            userVisibleOnly: true,
            applicationServerKey: urlBase64ToUint8Array(publicVapidKey),
        });
        console.log("푸쉬 등록 됨");
    
        // 푸쉬 보내기
        console.log("푸쉬 보내기");
        await fetch("/subscribe", {
            method: "POST",
            body: JSON.stringify(subscription),
            headers: {
                "content-type": "application/json",
            },
        });
        console.log("푸쉬 보냄");
    }
    
    // Vapid key를 안전하게 base64 스트링을 Unit8Array로 변환..
    function urlBase64ToUint8Array(base64String) {
        var padding = "=".repeat((4 - (base64String.length % 4)) % 4);
        var base64 = (base64String + padding)
            .replace(/\-/g, "+")
            .replace(/_/g, "/");
    
        var rawData = window.atob(base64);
        var outputArray = new Uint8Array(rawData.length);
    
        for (var i = 0; i < rawData.length; ++i) {
            outputArray[i] = rawData.charCodeAt(i);
        }
        return outputArray;
    }
    

    안전하게 base64 스트링으로 된 server내의 publicVapid key를 조금 더 안전하게 unit8array로 보내기 위한 장치가 포함되어있습니다.

    서비스워커 등록 및 스코프를 루트로 잡아놓고 푸쉬도 등록하는데 이 때 publicVapidKey는 안전하게 처리를 하고 미리 만들어두었던  node 서버의 /subscibe로 fetch를 보냅니다. 

     

    그러면 이제 서비스워커를 마지막으로 만들어보도록 하겠습니다.

    console.log("서비스워커 로드됨...");
    
    self.addEventListener("push", (e) => {
        const data = e.data.json();
        console.log("push 받음");
        self.registration.showNotification(data.title, {
            body: "Notified by Noel",
            icon:
                "https://tistory2.daumcdn.net/tistory/2794117/attach/aa31f12030a2404cafc028e2c8e2b1af",
        });
    });

    위와 같이 작성하면 client.js에서 서비스워커를 등록하기 위해서 호출 할 때 현재창에서 push알람 이벤트가 트리거 됩니다.

    그렇게 showNotification이 registration(등록) 되고 타이틀과 body, 그리고 아이콘 이미지가 나오게 됩니다.

     

    서버를 재시작해서 다시 한번 확인해보세요!!  (node index.js)

     

    감사합니다.

     

     

     

    출처 : www.youtube.com/watch?v=HlYFW2zaYQM

    출처 : github.com/bradtraversy/node_push_notifications

    'SERVER DEVELOPMENT > NodeJS' 카테고리의 다른 글

    Node.js 14 버전 릴리즈 소식  (0) 2020.04.25
Designed by Tistory.