김솔비 블로그
기술 블로그

[Part 7] 개인정보 없이 매주 알림 보내기 (웹 푸시)

4분 읽기시리즈 8/10

TL;DR

  • 매주 월요일 오전 10시에 이번 주 TOP 10을 웹 푸시로 알린다. 구독 정보만 저장하고 개인정보는 받지 않는다.
  • 끊긴 구독(404·410)은 보낼 때 자동으로 지운다.
  • 아이폰은 iOS 16.4 이상 + 홈 화면에 추가한 경우만 된다. 그래서 아이폰에는 버튼 대신 안내 문구를 보여 준다.

문제

프롬피드는 한 번 들어와서 프롬프트 하나 복사하고 나가기 쉬운 사이트다. 다시 올 이유가 필요했다. 매주 순위가 바뀌는 TOP 10이 그 이유가 될 수 있다. 문제는 바뀐 걸 어떻게 알리느냐다.

선택지

방법문제
이메일 뉴스레터이메일 주소를 받아야 한다. 개인정보를 최소로 한다는 원칙과 맞지 않는다
웹 푸시브라우저가 주는 구독 정보만 있으면 된다. 이름·전화번호·이메일이 필요 없다

웹 푸시를 골랐다.

구조

  1. 방문자가 알림 받기를 누르면, 브라우저가 구독 정보(푸시를 보낼 주소와 암호화 키)를 만든다. 이것만 DB에 저장한다.
  2. 매주 월요일 10시(한국 시간)에 Vercel Cron이 알림 경로를 부른다.
  3. 서버는 이번 주 상위 3개 제목으로 알림을 만들어 구독자에게 보낸다. 서버를 인증하는 키는 VAPID 키 쌍이고, 개인 키는 Vercel 환경변수에만 둔다.
  4. 방문자 브라우저의 서비스 워커가 알림을 받아 띄우고, 누르면 TOP 10 페이지를 연다.

서비스 워커

js
// public/sw.js — 주간 TOP 10 알림만 처리한다 (페이지 캐시는 하지 않음) self.addEventListener("push", (event) => { const data = event.data ? event.data.json() : {}; event.waitUntil( self.registration.showNotification(data.title || "프롬피드", { body: data.body || "이번 주 TOP 10이 나왔어요", icon: "/icons/icon-192.png", data: { url: data.url || "/top" }, }), ); }); self.addEventListener("notificationclick", (event) => { event.notification.close(); const url = new URL(event.notification.data?.url || "/top", self.location.origin).href; // 이미 열린 탭이 있으면 그 탭을 쓰고, 없으면 새로 연다 event.waitUntil( self.clients.matchAll({ type: "window" }).then((list) => { const open = list.find((c) => c.url.startsWith(self.location.origin)); return open ? open.navigate(url).then((c) => c && c.focus()) : self.clients.openWindow(url); }), ); });

서비스 워커는 알림만 처리한다. 페이지 캐시는 하지 않는다.

끊긴 구독은 지운다

알림을 끈 사람이나 브라우저 데이터를 지운 사람의 구독은 더 이상 유효하지 않다. 이런 구독으로 보내면 푸시 서버가 404나 410을 돌려준다. 보낼 때 이 응답을 받은 구독은 바로 지운다. 그래서 구독 목록이 쌓이기만 하지 않는다.

아이폰의 제약

아이폰 사파리의 웹 푸시는 조건이 있다.

  • iOS 16.4 이상이어야 한다.
  • 사이트를 홈 화면에 추가해서 앱처럼 연 경우에만 된다.

그냥 사파리로 들어온 아이폰 사용자에게 알림 버튼을 보여 주면, 눌러도 아무 일이 안 일어난다. 그래서 이 경우에는 버튼 대신 안내 문구를 보여 준다. 홈 화면에 추가하는 방법은 공지사항에 따로 정리해 뒀다.

결과

  • 개인정보 없이 매주 알림을 보낸다. 저장하는 건 구독 정보뿐이다.
  • 끊긴 구독은 자동으로 정리된다.
  • 아이폰 사용자는 눌러도 안 되는 버튼 대신 방법을 안내받는다.

배운 점

  • 다시 오게 만드는 장치에도 개인정보 원칙을 지킬 방법이 있다. 웹 푸시는 이름도 이메일도 필요 없다.
  • 플랫폼 제약은 기능을 숨기기보다 왜 안 되는지와 어떻게 하면 되는지를 알려 주는 쪽이 낫다.

프롬피드 개발기

프롬피드: promfeed.solfany.com