서비스 소개
2024년 1학기부터 2학기까지 개발한 서비스를 소개하려고 합니다!
아주대학교 공지사항을 유튜브처럼 구독할 수 있는 서비스인데요,
핵심 기능은 학교 공지사항과 키워드를 구독해서 푸시 알림을 받을 수 있습니다.
일반, 장학/학과/단과대/기숙사 공지사항 푸시 알림을 제공해주는 것 외에도
이벤트 배너, 이번주 인기글, 찜하기, 구독한 공지사항&키워드 글 확인, 구글 캘린더 연동을 도입해서
최대한 사용자들이 교내 공지사항이나 이벤트들을 놓치지 않도록 제작했습니다.
거두절미하고, 사이트 링크와 서비스 화면을 보여드리겠습니다.
(아래 설명부터는 편의상 반말로 작성하겠습니다... ㅎㅎ)
아주대학교 이벤트 알림 웹앱
팀 이쿠죠
www.ajouevent.com

푸시 알림

구독

홈화면, 검색, 찜하기

상세페이지 & 바로가기 & 구글 캘린더 연동

설치


구글 로그인

개발 배경


기존에 학교 공지사항을 올려주는 오픈채팅방이 있었고, 이미 많은 분들이 사용을 하고 계시지만
일반 공지사항만 제공하는 점,
학과, 단과대, 기숙사 등의 공지사항은 제공해주지 않아 아쉬움이 있었다.
또한 카카오톡 오픈채팅방의 참가 인원수는 1500명으로 제한되어 있다.
그리고 카카오톡은 주로 메신저로 사용하는 만큼, 학교 공지사항을 따로 알림 받을 수 있는 앱이 있으면 좋겠다는 생각이 들었다.

무엇보다 키워드 알림이 https://www.ajouevent.com 서비스를 만들게 된 가장 큰 이유다.
2023년 1학기 복학 후 학교에서 일본(도쿄)을 보내준다는 해외현장연수 프로그램이 있다는 것을 알게 되었다.
겨울 방학 때 오사카, 교토를 다녀온 뒤에 도쿄를 가고 싶다는 생각이 계속 들었기 때문에 공지가 올라올 날만을 기다렸다.
여느 때와 같이 강의가 끝나고 동기들이랑 쓰리팝에서 롤을 하고 있었는데,
5인큐가 끝난 이후에 다른 친구의 카톡을 통해 선발 공지사항이 올라왔다는 걸 알게 되었다.
신청은 2인 1팀으로 나는 지석이와 같이 신청을 했다. 나와 지석이는 군대 전역 후 복학한 직후라 활동을 한 것이 없었다.
지원 신청서에도 적을만한 내용이 없어 선발 인원 중 20%를 뽑는 선착순을 노려야 했는데 이미 늦은 뒤였다.

그리고 24년 1학기 다시 공지사항이 올라올 시기가 되었다.
이때는 사실 ajouevent를 파란학기로 개발하고 있는 시점이었지만, 아직 개발이 완성되지 않았다.
그래서 시간만 나면 소프트웨어융합대학 공지사항에 들어가 선발 공지사항이 올라왔는지 확인했다.

모집공고가 2023년과 다르게 2024년에는 좀 더 늦게 올라왔고, 나의 노가다 기간도 길어졌다.
이런 비효율적인 일을 반복하면서 키워드 알림 기능이 반드시 필요하구나라는 것을 깨달았다.
아쉬운 부분이 있으면 직접 만들어야겠다고 생각해서, 기존에 파란학기제를 같이 하기로 한 동기 2명에게 아이디어를 말했고,
2024-1학기 파란학기제 도전 과제로 제출했다.
알림 수단에 대한 고민
크롤링 부분은 이전에 장원이형이 GO로 만들어놓은 크롤링 프로그램을 물려받았다.
처음 장원이형이 만든 공지사항 크롤링 프로그램은 공지사항을 슬랙 채널로 올려서 알림을 띄우는 방식이었다.
아무래도 슬랙에 익숙하지않은 사람도 많았고, 설치부터 사용까지 다소 러닝커브가 있었다.
그래서 ajouevent.com 을 개발할 때는 사용자들에게 익숙한 수단으로 알림을 제공하고자했다.

후보에는 카카오톡, 텔레그램, 디스코드, 메일, PWA(Progressive Web App)+FCM(Firebase Cloud Messaging)이 있었다.
카카오톡은 이미 공지사항 오픈채팅방이 있었고, 비즈니스 채널로 하기엔 사업자 등록번호가 있어야 해서 제외했다.
텔레그램/디스코드는 사용자들이 익숙하지 않다고 판단하여 제외했다.
메일의 경우에는 사용자 수가 1000명, 2000명이 커질수록 메일 전송에 제약이 생길 수 있다는 문제가 있었다.
최종적으로 PWA+FCM 조합을 선택했다.
PWA를 통해 사용자들이 앱처럼 쓸 수 있고, 브라우저 기반으로 동작해 다양한 플랫폼에서 접근성을 높일 수 있다는 장점이 있다.
또한 PWA는 푸시 알림을 지원하고, 서비스 워커(Service Worker)를 통해 오프라인 상태에서도 알림을 처리할 수 있다.
다만, 사용자가 브라우저에서 ‘홈화면에 추가’를 통해 설치 과정을 거쳐야 하므로 이 점이 생소할 수 있는데,
설치 가이드를 명확히 제공하고 노트북과 갤럭시에서는 클릭을 통한 설치 팝업, iOS에서는 '홈화면에 추가' 방식을 설명하는 팝업을 통해 보완하고자 했다.

푸시 알림 방식으로 FCM(Firebase Cloud Messaging)을 선택한 이유
푸시 알림을 구현하는 방법으로는 주로 SSE(Server-Sent-Events)와 FCM(Firebase Cloud Messaging)을 사용하는 방식이 있다.
SSE(Server-Sent-Events)
일반적인 HTTP 통신에서는 클라이언트가 서버에 요청을 보내야만 서버가 응답을 보낼 수 있다. 그러나 푸시 알림 시스템에서는, 클라이언트의 요청이 없이도 공지사항이 등록되면 서버에서 클라이언트로 즉시 알림을 보내야 한다.
SSE는 서버에서 클라이언트로 데이터를 실시간으로 전송하는 기술이다. 일반적으로 HTTP 연결을 유지하며, 서버가 새로운 데이터를 생성할 때마다 클라이언트로 전송할 수 있다.
단점으로, 모바일 기기에서는 브라우저가 백그라운드로 전환되거나 클라이언트가 애플리케이션을 닫으면 알림을 수신할 수 없다. 또한 서버와 지속적으로 연결을 유지해야 하므로 네트워크 비용이 증가한다.
FCM(Firebase Cloud Messaging)
FCM은 교차 플랫폼 메시징 솔루션으로
Web, iOS, Android 등의 특정 플랫폼에 종속되지 않고 메시지를 전송할 수 있다.
애플리케이션 서버가 아니라 클라우드 메시징 서버가 메시지 전송의 역할을 담한다. 따라서 애플리케이션이 계속 실행 중일 필요 없이 낮은 배터리 소모와 네트워크 사용만으로도 실시간 메시지 송수신이 가능하다.
그래서 FCM을 이용하면 사용자가 앱을 실행하고 있지 않을 때에도 푸시 알림을 받을 수 있다.
물론 FCM 서버에 의존하기 때문에, FCM 서버 상태에 따라 지연이나 장애가 발생할 수 있는건 단점이다. SSE의 실시간성에 비해서도 느린 편이다.
우리 서비스는 웹 브라우저 뿐만 아니라, iOS, Android 등 모바일 기기까지 다양한 기기에서 사용될 것을 고려하여, 많은 플랫폼을 수용할 수 있는 FCM을 선택했다.
특히, 주로 모바일 기기에서 푸시 알림을 확인한다고 생각하여 배터리를 크게 소모하지 않으면서, PWA가 실행 중이지 않더라도 알림을 받을 수 있는 FCM이 적합하다고 판단했다.

FCM에서 제공하는 여러 기능들도 활용했다.
Topic 기능을 활용해 학교 공지사항이나 사용자 맞춤형 키워드마다 별도의 Topic을 생성했다.
FCM에서 발급하는 Token을 활용해 사용자 1명이 여러 개의 토큰을 가질 수 있도록 하여 여러 기기에서 푸시 알림을 받을 수 있도록 했다.
아키텍처


인프라는 비용 최적화를 중점으로 설계했다. AWS 프리티어를 최대한 활용한 아키텍처다.
VPC와 서브넷 구축, 백엔드 CI/CD 파이프라인 구성은 영준이 형과 함께했다. 서비스로 아키텍처까지 그려줬는데 너무 마음에 든다.
템플릿도 받았는데 앞으로 요긴하게 활용할 예정이다.
Fronted CI/CD pipeline

프론트엔드 배포에서도 Vercel 무료 플랜을 최대한 활용했다.
GitHub Organization의 레포지토리를 Vercel에 배포하려면 유료 플랜인 Team Plan을 써야 한다.
비용 절감을 위해 팀 레포지토리를 나의 개인 레포지토리로 fork(public) 한 뒤, Vercel에 배포하는 방식을 선택했다.
단, 이 방식은 팀 레포지토리와 개인 레포지토리 간의 싱크가 맞지 않는 문제가 발생할 수 있다.
이를 위해 Github Actions를 설정해서 팀 레포지토리의 main 브랜치에 commit이나 push가 발생하면,
자동으로 개인 레포지토리로 변경 사항을 push 하도록 구현했다.
prod와 dev 환경을 나누기 위해 Vercel의 브랜치별 배포 기능도 활용하여 dev 브랜치에도 Github Actions을 적용했다
React+PWA를 선택한 이유
파란학기제를 함께하는 석찬이가 아무래도 React를 주로 개발해 왔기 때문에 React Native, Flutter나 Swift, 코틀린을 새로 배우기에는 러닝 커브가 크고 무리라고 판단했다.
대신 React + PWA(Progressive Web Application) 조합을 채택해서 앱 형태로 제공할 수 있도록 하여 사용자 경험을 향상하기로 했다.
특히, PWA는 브라우저 기반으로 작동하면서도 네이티브 앱과 유사한 UX를 제공하며, 알림 기능까지 구현할 수 있었다.
또한, iOS의 경우, 기존에는 웹 푸시 알림 기능을 지원하지 않았지만, iOS 16.4 버전부터 웹 푸시 알림 기능을 지원하게 되었고, 이 점이 PWA 선택에 큰 영향을 주었다.

Safari 16.4 Release Notes | Apple Developer Documentation
Safari 16.4 Release Notes | Apple Developer Documentation
Released March 27, 2023 — Version 16.4 (18615.1.26)
developer.apple.com
Sending web push notifications in web apps and browsers | Apple Developer Documentation
Sending web push notifications in web apps and browsers | Apple Developer Documentation
Update your web server and website to send push notifications that work in Safari, other browsers, and web apps, following cross-browser standards.
developer.apple.com
그러다 개강하기 전 2024년 2월, iOS 17.4 버전부터 PWA 지원을 중단한다는 애플의 발표를 듣고 심장이 철렁했다.

iOS 17.4 Update Ends PWA Support in the European Union
iOS 17.4 Update Ends PWA Support in the European Union
In the latest iOS 17.4 beta update, Apple made a significant move by disabling the functionality of...
dev.to
하지만 유럽에서 보이콧이라는 강수를 둔 바람에 지원 철회를 철회했고(?) 무사히 프로젝트를 진행할 수 있었다.

Update on apps distributed in the European Union - Support - Apple Developer
Update on apps distributed in the European Union - Support - Apple Developer
Update on apps distributed in the European Union
developer.apple.com
스프링을 선택한 이유
파란학기제를 같이하는 나와 은정이 둘 다 스프링을 주력으로 개발했기 때문에 스프링 + JPA를 선택했다. 개발한 뒤에 이유를 덧붙이자면, 위의 아키텍처에서 볼 수 있듯이 스프링이 크롤링 서버가 보낸 공지사항을 특정 API로 받는 역할도 하고, 일반 API 서버로서의 역할도 하고, FCM으로 푸시 요청도 해주는 여러 가지 역할을 수행한다.
따라서 이렇게 여러 역할을 수행하고, 크롤링한 공지사항을 받아서, DB에 저장하고, FCM에 푸시 알림 요청까지 하는 과정이, 동시에 일어나는 경우도 있기 때문에 멀티스레드로 다루는 것이 적합하다고 생각했다.
나중에는 이를 분리할 계획이지만, 단일 서버로 다루기에는 스프링이 적합하다고 생각했다.
현황
2024년 6월 파란학기제 성과 발표제에서 배포한 이후로 지금까지 계속해서 운영 중이다.
가입자 수는 2024년 12월 18일 기준 240명이며, 단과대 축제 부스 이후에 MAU가 170명은 찍힌다.
실제 사용자가 있으니까 더 잘 운영하고 싶고, 리팩토링 할 욕심이 생긴다.


앞으로의 계획
- 서버비 충당: 현재 월 3만원 정도의 AWS 서버비가 나가는데(prod + dev) 이 돈을 충당할 방법을 강구 중이다… 도와줘요 아주대…
- 예산을 충분히 지원 받는다면, 쿠버네티스, Kafka, ELK 같은 오픈스택도 마음껏 써보고 싶다. 그전까지 리팩토링을 통해 코드를 유지보수하기 좋게 만들려고한다.
- 신설학과, 단과대 추가: -자유전공학부, 프런티어과학학부, 경제정치사회융합학부, 응용화학과, 첨단바이오융합대학이 추가되었다. 서비스의 구독 목록에 추가해야 한다.
- 알림 ON/OFF 옵션 추가: 현재는 구독 탭에서 구독한 공지사항에 대해서는 무조건 푸시 알림을 받는다. 특히 아주대학교-일반 공지사항은 하루에 30개가 넘게 공지사항이 올라와 너무 자주 알림이 온다는 의견을 반영하여 결정했다.
- 유튜브의 구독 기능처럼, 구독은 하고 알림은 받지 않는 기능을 추가할 생각이다. 구독한 공지사항에 푸시 알림이 오지 않더라도 , 네비게이션바의 구독탭에 뱃지가 바뀌기 때문에 종종 올라오면서 확인을 할 것이라고 생각했다.

- 알림 목록 구현: 현재 사용자들은 푸시 알림을 받을 수 있지만, 앱 내부에서 알림 목록을 따로 확인할 수 있는 페이지는 없다. 따라서 알림 목록 페이지를 구현하고, PWA에서 뱃지 기능을 구현해서 사용자가 알림 몇 개를 읽지 않았는지 확인할 수 있게할 예정이다.

Display a badge on the app icon - Progressive web apps | MDN
Display a badge on the app icon - Progressive web apps | MDN
Applications native to mobile and desktop operating systems can display badges on top of their app icons to inform users that new content is available. For example, an email client application can display the total number of unread messages in a badge and
developer.mozilla.org
- 푸시 알림 및 크롤링 모니터링: FCM을 사용하기 때문에 현재 Firebase 콘솔을 통해 메시지의 전송량은 모니터링할 수 있지만, 클릭률이나 수신률에 대해서는 모니터링이 되지 않는다. 따라서 클릭률과 수신률 같은 푸시 알림 데이터를 모니터링하는 시스템을 구축할 계획이다. 또한 크롤링을 할때도 실패 처리, 누락 처리와 같은 예외처리를 정교화하고 안정적인 서비스 운영을 위한 모니터링을 구축할 계획이다.

'ajouevent.com' 카테고리의 다른 글
| 유튜브처럼, 구독한 공지사항별 알림 설정 기능을 도입해보자 (0) | 2025.10.02 |
|---|---|
| [MySQL] URL 저장을 위한 데이터 타입 VARCHAR vs TEXT (0) | 2025.01.19 |
| FCM 키워드 알림 기능 개발기 feat. FCM Topic 한글, 특수문자 사용 가능 여부 (3) | 2025.01.12 |