HTML5 Notification API
웹브라우저 → 클라이언트로 알림기능을 전송할 수 있는 기능을 html에서 API로 제공한다.
사용 방법은 크게 두단계로
- 권한 허용
- 메시지 전송
으로 끝.
알림 권한 허용
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