알림 기능을 구현해 보겠습니다.
실시간 알림은 websocket 등으로 구현 하면 되지만 디지털액자는 그렇게까지 실시간으로 알림을 보지 않아도 되기 때문에 2~5초 간격으로 서버에 ajax 요청을 보냅니다. 서버는 알림 배열을 반환합니다.
클라이언트는 이 배열을 읽고 알림 표시 기한(expire)이 지났는지 확인한 후 알림을 display_time 초 동안 표시합니다. 랜덤 id 값이 부여되기 때문에 클라이언크는 알림을 표시했으면 localstorage 에 이 id 값을 저장합니다.
이 localstorage 는 새로고침해도 데이터가 지워지지 않습니다. 따라서 한번 표시된 알림은 다시 표시되지 않습니다.
이제 notification 을 자동으로 넣어주는 코드를 짜야 합니다. 우선 일정 시작 전 알려주는 코드를 짭니다.
매 1분마다 작업을 돌려줘야 하기 때문에 fastapi_utils 라이브러리를 사용했습니다.
@app.on_event("startup")
@repeat_every(seconds=60 * 1) # 1 minute
def event_notification() -> None:
now = datetime.datetime.now(tz=tzoffset(None, 32400))
evt_list = get_event_list()
expire = 60 * 10 # 10 분
display_time = 30 # 30 초
for evt in evt_list:
for reminders in evt.reminders:
reminder_at = get_evt_start_date(evt) - datetime.timedelta(minutes=reminders.minutes_before_start)
if now <= reminder_at < now + datetime.timedelta(minutes=1):
start_date = get_evt_start_date(evt).strftime("%m-%d %H:%M")
add_notification(f"{start_date}<br>{evt.summary}<br>일정이 {reminders.minutes_before_start}분 후 시작합니다.",
expire=now.timestamp() + expire, display_time=display_time, show_notiboard=False)
if len(evt.reminders) == 0:
reminder_at = get_evt_start_date(evt) - datetime.timedelta(minutes=30)
if now <= reminder_at < now + datetime.timedelta(minutes=1):
start_date = get_evt_start_date(evt).strftime("%m-%d %H:%M")
add_notification(f"{start_date}<br>{evt.summary}<br>일정이 {30}분 후 시작합니다.",
expire=now.timestamp() + expire, display_time=display_time, show_notiboard=False)
임의의 초에 1분마다 실행되는 것이기 때문에 (현재시각 <= 리마인더시각 < 현재시각 + 1분) 범위로 잡아야 알림을 빠짐없이 잡을 수 있습니다.
다음은 학사·학과공지 코드로 알림을 구현할 예정입니다.