Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

푸시 알림 전송 기능 + 알림 스케줄러 기능 구현 #19

Closed
wants to merge 11 commits into from
2 changes: 2 additions & 0 deletions src/main/kotlin/com/ondosee/OndoseeApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.ondosee

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import java.util.*

@SpringBootApplication
class OndoseeApplication

fun main(args: Array<String>) {
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul"))
runApplication<OndoseeApplication>(*args)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ondosee.common.adapter.notification

import com.ondosee.common.spi.notification.QueryNotificationPort
import com.ondosee.domain.notification.domain.entity.Notification
import com.ondosee.domain.notification.domain.repository.NotificationRepository
import org.springframework.stereotype.Component

Expand All @@ -11,4 +12,8 @@ class QueryNotificationAdapter(
override fun existByDeviceToken(deviceToken: String): Boolean {
return notificationRepository.existsByDeviceToken(deviceToken)
}

override fun findByAlarmTime(alarmTime: String): List<Notification> {
return notificationRepository.findByAlarmTime(alarmTime)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.ondosee.common.spi.notification

import com.ondosee.domain.notification.domain.entity.NotificationAlarm

interface NotificationPort {
fun sendSingleNotification(deviceToken: String, notificationAlarm: NotificationAlarm)
fun sendMultipleNotification(deviceTokens: List<String>, notificationAlarm: NotificationAlarm)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.ondosee.common.spi.notification

import com.ondosee.domain.notification.domain.entity.Notification

interface QueryNotificationPort {
fun existByDeviceToken(deviceToken: String): Boolean
fun findByAlarmTime(alarmTime: String): List<Notification>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ondosee.domain.notification.domain.entity

data class NotificationAlarm(
val title: String,
val body: String,
val writer: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ import org.springframework.data.jpa.repository.JpaRepository
interface NotificationRepository : JpaRepository<Notification, Long> {
fun existsByDeviceToken(deviceToken: String): Boolean
fun deleteByDeviceToken(deviceToken: String)
fun findByAlarmTime(alarmTime: String): List<Notification>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.ondosee.domain.notification.scheduler

import com.ondosee.domain.notification.service.NotificationService
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component

@Component
class NotificationScheduler(
private val notificationService: NotificationService
) {
@Scheduled(cron = "0 * * * * *")
fun sendNotificationAlarm() {
notificationService.sendAlarm()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import com.ondosee.domain.notification.presentation.web.req.SetAlarmWebRequest

interface NotificationService {
fun setAlarm(webRequest: SetAlarmWebRequest)
fun sendAlarm()
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.ondosee.domain.notification.service

import com.ondosee.common.spi.notification.CommandNotificationPort
import com.ondosee.common.spi.notification.NotificationPort
import com.ondosee.common.spi.notification.QueryNotificationPort
import com.ondosee.domain.notification.domain.entity.NotificationAlarm
import com.ondosee.domain.notification.presentation.web.req.SetAlarmWebRequest
import com.ondosee.thirdparty.firebase.data.enums.NotificationMessage
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

@Service
@Transactional(rollbackFor = [Exception::class])
class NotificationServiceImpl(
private val notificationPort: NotificationPort,
private val queryNotificationPort: QueryNotificationPort,
private val commandNotificationPort: CommandNotificationPort
) : NotificationService {
Expand All @@ -21,4 +27,29 @@ class NotificationServiceImpl(
commandNotificationPort.saveAlarm(deviceToken, alarmTime)
}
}

override fun sendAlarm() {
val currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm"))

val notificationList = queryNotificationPort.findByAlarmTime(currentTime)

if (notificationList.isNotEmpty()) {
val notificationAlarm = NotificationAlarm(
title = NotificationMessage.ALARM_MESSAGE.title,
body = NotificationMessage.ALARM_MESSAGE.body,
writer = "ON°C"
)

when (notificationList.size) {
1 -> notificationPort.sendSingleNotification(
deviceToken = notificationList.first().deviceToken,
notificationAlarm = notificationAlarm
) else ->
notificationPort.sendMultipleNotification(
deviceTokens = notificationList.map { it.deviceToken },
notificationAlarm = notificationAlarm
)
}
}
}
}
8 changes: 8 additions & 0 deletions src/main/kotlin/com/ondosee/global/config/ScheduleConfig.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.ondosee.global.config

import org.springframework.context.annotation.Configuration
import org.springframework.scheduling.annotation.EnableScheduling

@Configuration
@EnableScheduling
class ScheduleConfig
42 changes: 42 additions & 0 deletions src/main/kotlin/com/ondosee/thirdparty/firebase/FirebaseAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ondosee.thirdparty.firebase

import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.Message
import com.google.firebase.messaging.MulticastMessage
import com.ondosee.common.spi.notification.NotificationPort
import com.ondosee.domain.notification.domain.entity.NotificationAlarm
import org.springframework.context.annotation.Configuration

@Configuration
class FirebaseAdapter : NotificationPort {
private val firebaseInstance: FirebaseMessaging
get() = FirebaseMessaging.getInstance()

override fun sendSingleNotification(deviceToken: String, notificationAlarm: NotificationAlarm) {
val message = getMassageBuilderByNotification(notificationAlarm)
.setToken(deviceToken)
.build()
firebaseInstance.send(message)
}

override fun sendMultipleNotification(deviceTokens: List<String>, notificationAlarm: NotificationAlarm) {
val message = getMulticastMassageBuilderByNotification(notificationAlarm)
.addAllTokens(deviceTokens)
.build()
firebaseInstance.sendMulticastAsync(message)
}

private fun getMassageBuilderByNotification(notificationAlarm: NotificationAlarm) =
with(notificationAlarm) {
Message.builder()
.putData("title", title)
.putData("body", body)
}

private fun getMulticastMassageBuilderByNotification(notificationAlarm: NotificationAlarm) =
with(notificationAlarm) {
MulticastMessage.builder()
.putData("title", title)
.putData("body", body)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ondosee.thirdparty.firebase.data.enums

enum class NotificationMessage(
val title: String,
val body: String
) {
ALARM_MESSAGE(
title = "오늘의 날씨 특이사항은??",
body = "ON°C 가 설정하신 시간에 알림을 보냈어요 :)"
)
}
Loading