
최근 도에서 열리는 학생 해커톤 페스티벌에 참가하게 되면서 웹 푸시알림을 구현할 일이 생겼다.
이에 웹 푸시를 구현하면서 알게 된 내용을 간단하게 정리해보려고 한다.
web-push 모듈 설치
먼저 NodeJS에서 웹 푸시를 쉽게 구현해주는 web-push 모듈을 설치합니다.
npm i web-push
VAPID 생성
웹 푸시 알림 전송에는 VAPID라 불리우는 키쌍이 필요합니다.
web-push 패키지에는 VAPID를 생성할 수 있는 기능을 지원하기에 VAPID를 생성해줍니다.
npx web-push generate-vapid-keys
그럼 아래와 같이 키가 생성되는데 이후 푸시알림 전송시 필요하니 유출되지 않도 잘 간직해둡니다.

서비스워커 작성
그 다음 웹 브라우저에서 푸시 알림을 처리할 수 있도록 서비스워커에 push 이벤트를 처리하는 코드를 작성해야합니다.
서비스워커는 브라우저가 백그라운드에서 실행하는 코드로, 웹페이지와는 완전히 별개로 백그라운드에서 열심히 이벤트를 처리하는 역할을 합니다.
위에서 서술했듯 서비스워커는 웹페이지와 완전 별개로 떨어저 있기에 서비스워커에서는 DOM, window 요소등을 사용할 수 없습니다.
먼저 서비스워커로 사용할 js 파일을 퍼블릭 폴더에 생성해줍니다.
이후 push 이벤트 리스너를 추가하여 푸시알림 수신 이벤트를 생성해줍니다.
/* serviceworker.js */
self.addEventListener("push", (event) => {
});
그다음 이벤트에서 수신된 내용을 바탕으로 실제 알림으로 표시하는 코드를 작성해줍니다.
서버단에서 보낸 푸시 정보는 event.data로 수신되니 으로 수신되니 서버에서 보낸 형식에 맞게 파싱해줍니다.
알림 표시의 경우는 브라우저의 Notification API를 사용하여 구현합니다.
/* serviceworker.js */
self.addEventListener("push", (event) => {
const payload = event.data.json();
event.waitUntil(
registration.showNotification(payload.title, {
body: payload.body,
vibrate: [100, 100, 100],
})
);
});
웹페이지 알림 전송 권한 요청 및 푸시 알림 구독
이후 웹 푸시알림을 브라우저가 처리하고, 알림을 보낼수 있도록 해야합니다.
웹페이지 내에 JS코드를 생성한후 먼저 serviceWorker, PushManager, Notification을 브라우저에서 지원하는지 확인해줍니다.
/* index.js */
if ("serviceWorker" in navigator && "PushManager" in window && 'Notification' in window) {
}
그다음 serviceWorker를 등록해줍니다. 저의 경우 서비스워커를 /javascripts/serviceworker.js에 저장했기에 이를 기준으로 등록하였습니다.
/* index.js */
navigator.serviceWorker.register("/javascripts/serviceworker.js").then(e => {
});
이후 웹페이지 알림 전송권한을 취득합니다.
알림 전송권한을 취득하였다면 subscribePushNoti를 호출해 푸시알림을 등록해줍니다.
/* index.js */
navigator.serviceWorker.register("/javascripts/serviceworker.js").then(e => {
if(Notification.permission == 'default') {
Notification.requestPermission((permission) => {
if(permission == 'granted') {
// 푸시알림 구독
subscribePushNoti(e);
}
});
}else if(Notification.permission == 'granted') {
// 푸시알림 구독
subscribePushNoti(e);
}
});
subscribePushNoti함수는 아래와 같이 작성하였습니다.
async function subscribePushNoti(e) {
let subInfo = await e.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: PUBLIC_KEY
});
await fetch('/api/subscribe', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subInfo)
})
}
serviceWoeker.register().then(e => {})에 포함된 e.pushManager.subscribe()를 사용하여 푸시 알림을 구독합니다.
subscribe()에 사용되는 옵션은 다음과 같습니다.
userVisibleOnly: 사용자에게 표시되는 알림만 받기
applicationServerKey: 발급한 VAPID의 Public Key
이후 e.pushManager.subscribe()를 실행하여 나온 구독 정보를 서버로 전송합니다.
푸시알림 구독 처리
이후 서버단에서 구독 정보를 토대로 처리해줍니다.
ExpressJS로 구현하였습니다.
var express = require('express');
var router = express.Router();
var webpush = require('web-push');
let subInfo = {};
// web-push 모듈 설정
webpush.setVapidDetails(
'mailto:<email 주소>',
VAPID_PUBLIC_KEY,
VAPIID_PRIVATE_KEY
);
// 푸시알림 전송
router.post('/event', function(req, res, next) {
// status 0: 전송 성공
// status -1: 구독 정보 없음
if(!!!subInfo) {
res.json({status: -1});
return;
}
webpush.sendNotification(subInfo, JSON.stringify({title: 'test', body: 'test'}))
res.json({status:0}
);
});
// 푸시알림 구독정보 저장
router.post('/subscribe', function(req, res, next) {
subInfo = req.body;
res.json({status: 0});
});
웹으로 전송한 구독정보를 subInfo 변수에 저장후 /event로 POST 요청 전송시 subInfo에 저장된 구독 정보를 바탕으로 푸시알림을 전송합니다.
이후 웹페이지에 한번 접속하여 알림 전송을 허용해준후, /event로 POST 요청을 보내면 웹브라우저로 알림이 전송되는것을 확인할 수 있습니다.
[해당글은 https://blog.bass9030.dev/post/15 에서 이동된 글입니다]
'코딩 스래기' 카테고리의 다른 글
마훅 - 마후마후 트윗 번역 웹훅 제작기 (0) | 2025.01.20 |
---|---|
[Android] Intent로 웹페이지를 열면 웹뷰 충돌이 발생할때 (0) | 2024.04.03 |
[Web] form 태그에서 js 추가 안하고 원하는 페이지로 리다이렉트하기 (0) | 2021.04.01 |
[Python] win32api 모듈을 사용한 코드를 exe로 변환시 'win32api : 지정된 모듈을 찾을수 없습니다.' (0) | 2020.03.09 |