Web/JS-Bootstrap

웹브라우저에서 푸시 알림받기

HTML5 Notification API

웹브라우저 → 클라이언트로 알림기능을 전송할 수 있는 기능을 html에서 API로 제공한다.

사용 방법은 크게 두단계로

  1. 권한 허용
  2. 메시지 전송

으로 끝.

알림 권한 허용

Notification.requestPermission();

위 메소드를 호출하면 브라우저에 알림창이 뜨면서 사용자에게 현재 페이지에서 알림을 허용할지를 물어본다.

var permission = Notification.requestPermission();
console.log(permission)

이렇게 해서 어떻게 나오는지 보면

허용시 Promise.PromiseResult 메소드값이 granted로 나온다.

차단하면 denied로 바뀌어 나옴.

//알림 권한 요청
    function getNotificationPermission() {
        // 브라우저 지원 여부 체크
        if (!("Notification" in window)) {
            alert("데스크톱 알림을 지원하지 않는 브라우저입니다.");
        }
        // 데스크탑 알림 권한 요청
        Notification.requestPermission(function (result) {
            // 권한 거절
            if(result == 'denied') {
                Notification.requestPermission();
                alert('알림을 차단하셨습니다.\n브라우저의 사이트 설정에서 변경하실 수 있습니다.');
                return false;
            }
            else if (result == 'granted'){
                alert('알림을 허용하셨습니다.');
            }
        });
    }

참고한 문서에서 예제코드를 참조하여 사용해봤다. 차단시엔 알림 차단에 대한 alert 창이 뜨고, 허용시엔 허용에 대한 alert 창이 뜬다. 새로고침 할때마다 뜨니까 grant에 대한 alert은 왠만하면 빼는걸로.

데스크톱 푸시알림

new Notification("타이틀", {body:'메세지내용'});

코드 기본형.

이전엔 PWA로 만들어진 사이트가 아니면 이런식의 알림이 불가능하다고 알고 있었는데, 꼭 그런건 아닌가보다.

다만 , https가 적용된 웹 페이지에서만 가능하다는 제약은 존재한다. localhost에 접속하는 경우는 이를 무시하지만, 외부아이피로 동일 페이지에 접근하면 알람이 뜨지 않는다.

아예 권한 기본값이 denied로 설정되는듯.

Notification에는 다양한 프로퍼티가 존재하는데, 일부는 서비스워커가 동작하는 환경, 즉 PWA 환경에서만 사용이 가능하다.

이름 설명 비고
actions NotificationAction 배열을 전달한다. notification상에서 실행할 동작을 선택할 수 있다. 서비스 워커 필요. ServiceWorkerRegistration.showNotification() 메소드로 알림을 실행해야함.
badge 알림을 표시할 공간이 충분하지 않을 때 알림을 나타내는데 사용할 이미지의 URL이 포함된 USV String이 들어간다. 일반적인 경우에는 보기 힘듬.
body 메시지에 표시될 텍스트 거의 필수
data 알림과 관련된 임의의 데이터. 일반적으로 사용하는 형태는 아닌걸로 보임
dir 알림이 나올 방향. 기본은 auto지만 ltr이나 rtl로 설정할 수 있음. 대부분 브라우저에서 설정을 무시함.
icon 들어갈 아이콘의 URL  
image 들어갈 이미지의 URL  
lang 표기할 언어 명시 크게 의미는 없다.
maxActions 이 장치에서 최대로 표시 가능한 Actions 숫자 반환  
onclick 클릭시 실행할 동작 명시 메소드 생성 후에 함수형 선언 필요.
onclose 알림 닫을시 실행할 동작 명시 데스크톱상 이벤트 발생 조건을 모르겠음
onerror 에러 발생시 실행할 동작 명시  
permission 현재 브라우저의 Notification 권한이 어떻게 되어있는지 반환  
renotify 새 알림이 이전 알람을 대체한 다음 사용자에게 이를 알릴지 여부를 지정 기본값은 false, true 로 설정시 tag와 함께 설정해야함
tag 알림의 식별 태그  
requireInteraction 사용자가 클릭하거나 닫기전엔 자동으로 닫히지 않음 기본값은 false
silent 기기 알림에 관계없이 항상 무음 알림으로 나옴  
timestamp 알림 발생한 시간을 반환 별도의 date 함수 실행 필요
title 현재 알람의 제목을 반환  
vibrate 알림시 기기 하드웨어에 발생시킬 진동 패턴 배열로 넘어감 . 모바일 장치가 아니고서야 크게 의미가 없다.

Actions

actions:[
    {action : 'test1', title :'test2'},
    {action : 'test1', title :'test2'}
]

서비스워커가 필요하여 실행은 못해봄.

Badge

badge : 'http://127.0.0.1/static/img/wtlogo.png'

메시지가 안뜨는 조건을 아직 못찾아 결과물 확인을 못했다.

message

body:'loooooooong message'

들어갈 메시지의 내용

dir

dir : 'ltr',
dir : 'rtl',

설명대로 rtl이나 ltr이나 별 차이가 없었다.

icon

icon : 'http://127.0.0.1/static/img/logo.png'

아이콘에 들어갈 로고 이미지 URL

image

icon : 'http://127.0.0.1/static/img/lmage.png'

아이콘과 이미지의 차이가 보이나?

lang

lang : 'en-US'

표기할 언어코드 명시. 크게 체감은 없다.

maxActions

const maxActions = Notification.maxActions;
>undefined
maxActions
>2

현재 디바이스에 Actions 배열을 최대 몇개나 넘길 수 있는지를 알 수 있다.

onclick

n = new Notification("타이틀", message);
n.onclick = function(event){
    event.preventDefault();
    console.log("click?")
};

생성할때 인자로 넘기는 방식으로는 선언이 불가하고, 메소드를 변수에 저장해준 다음에 활용할 수 있다.

onclose

n.onclose = function(event){
            event.preventDefault();
            console.log("close?")
        };
혹은
n.addEventListener('close', () => console.log('close?'))
~~~
n.close()
> close?

데스크톱에서 close()이벤트를 그냥 호출시키는건 안되고, 콘솔이나 스크립트에서 별도로 close() 실행시에 동작했다.

Permission

Notification.permission
> 'granted'

이건 개별적으로 생성되는 Notification 메소드가 아닌 브라우저에 붙은 설정값을 가져오는걸로 보인다.

renofify, tag

renotify : true,
tag : 'renotify'

true로 할거면 반드시 tag 옵션을 함께 줘야한다. 알림이 올때마다 새로 갱신되는걸 확인 가능.

requireInteraction

requireInteraction : true

닫기버튼이 생기며 그냥 냅두는걸로는 영원히 닫히지 않는다.

silent

silent : true

소리가 안난다.

timestamp

timestamp: Math.floor(Date.now())
~~
n.timestamp
> 1632886237576

알람이 생성된 시간을 저장할 수 있다.

title

n.title
> '타이틀'

심플하게 타이틀만 출력해준다.

vibrate

vibrate : [200, 100, 200]

진동기능이 있으면 알림이 뜰 때 해당 진동 패턴이 갈듯.


with websocket

이제 이걸 웹소켓과 연동해서 알림을 띄워볼거다. 자바스크립트에서 sokect.on() 으로 이벤트를 수신하는 부분에 알림 생성 함수 실행코드만 추가해주면 된다.

socket.on('Event',function(ret){
    openAlertModal(1,ret.name+" 에 대한 분석이 완료되었습니다.");
    if($('.TaskCard[id='+ret.id+']')){
        $('.TaskCard[id='+ret.id+']').find('.TaskMDPath').html("<a href=/mddoc/"+ret.mdpath+" target='_blank'>report.md</a>");            
    }
    makeNotification(ret.name+" 에 대한 분석이 완료되었습니다.");
});

function makeNotification(message){
    var message = {
        body:message,
    }
    n = new Notification("분석 완료", message);        
}

이경우는 이렇게 하면 웹페이지 내부의 알람과 데스크톱상의 알람이 모두 뜨게 된다. 다만 웹소켓이 특정 페이지에만 한정되어있기 때문에 해당 페이지를 벗어나면 데스크톱 알림을 받을 수 없다는건 단점.

함수에 다양한 프로퍼티를 붙여 알림 클릭시 특정 페이지로 이동하거나 아이콘등을 추가하면 더 유용하게 사용할 수 있을듯.


참고 문서

https://dororongju.tistory.com/125

https://developer.mozilla.org/ko/docs/Web/API/notification

https://developer.mozilla.org/en-US/docs/Web/API/notification/actions

https://runebook.dev/ko/docs/dom/notification/notification