본문 바로가기
SERVER DEVELOPMENT/NodeJS

Node.js로 간단한 Push 만들기

by F.E.D 2021. 5. 2.

위와 같이 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

댓글