98 lines
3.9 KiB
Kotlin
98 lines
3.9 KiB
Kotlin
package space.luminic.budgerapp.services
|
|
|
|
|
|
import com.interaso.webpush.VapidKeys
|
|
import com.interaso.webpush.WebPushService
|
|
import kotlinx.serialization.encodeToString
|
|
import kotlinx.serialization.json.Json
|
|
import org.slf4j.LoggerFactory
|
|
import org.springframework.dao.DuplicateKeyException
|
|
import org.springframework.stereotype.Service
|
|
import reactor.core.publisher.Mono
|
|
import space.luminic.budgerapp.models.PushMessage
|
|
import space.luminic.budgerapp.models.Subscription
|
|
import space.luminic.budgerapp.models.SubscriptionDTO
|
|
import space.luminic.budgerapp.models.User
|
|
import space.luminic.budgerapp.repos.SubscriptionRepo
|
|
import space.luminic.budgerapp.services.VapidConstants.VAPID_PRIVATE_KEY
|
|
import space.luminic.budgerapp.services.VapidConstants.VAPID_PUBLIC_KEY
|
|
import space.luminic.budgerapp.services.VapidConstants.VAPID_SUBJECT
|
|
|
|
object VapidConstants {
|
|
const val VAPID_PUBLIC_KEY =
|
|
"BKmMyBUhpkcmzYWcYsjH_spqcy0zf_8eVtZo60f7949TgLztCmv3YD0E_vtV2dTfECQ4sdLdPK3ICDcyOkCqr84"
|
|
const val VAPID_PRIVATE_KEY = "YeJH_0LhnVYN6RdxMidgR6WMYlpGXTJS3HjT9V3NSGI"
|
|
const val VAPID_SUBJECT = "mailto:voroninvyu@gmail.com"
|
|
}
|
|
|
|
@Service
|
|
class SubscriptionService(private val subscriptionRepo: SubscriptionRepo) {
|
|
|
|
private val logger = LoggerFactory.getLogger(javaClass)
|
|
private val pushService =
|
|
WebPushService(
|
|
subject = VAPID_SUBJECT,
|
|
vapidKeys = VapidKeys.fromUncompressedBytes(VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY)
|
|
)
|
|
|
|
fun sendNotification(endpoint: String, p256dh: String, auth: String, payload: PushMessage): Mono<Void> {
|
|
return Mono.fromRunnable<Void> {
|
|
pushService.send(
|
|
payload = Json.encodeToString(payload),
|
|
endpoint = endpoint,
|
|
p256dh = p256dh,
|
|
auth = auth
|
|
)
|
|
}
|
|
.doOnSuccess {
|
|
logger.info("Уведомление успешно отправлено на endpoint: $endpoint")
|
|
}
|
|
.doOnError { e ->
|
|
logger.error("Ошибка при отправке уведомления на endpoint $endpoint: ${e.message}")
|
|
}
|
|
.onErrorResume { e ->
|
|
Mono.error(e) // Пробрасываем ошибку дальше, если нужна обработка выше
|
|
}
|
|
}
|
|
|
|
|
|
fun sendToAll(payload: PushMessage): Mono<List<String>> {
|
|
return subscriptionRepo.findAll()
|
|
.flatMap { sub ->
|
|
sendNotification(sub.endpoint, sub.p256dh, sub.auth, payload)
|
|
.then(Mono.just("${sub.user?.username} at endpoint ${sub.endpoint}"))
|
|
.onErrorResume { e ->
|
|
sub.isActive = false
|
|
subscriptionRepo.save(sub).then(Mono.empty())
|
|
}
|
|
}
|
|
.collectList() // Собираем результаты в список
|
|
}
|
|
|
|
|
|
fun subscribe(subscriptionDTO: SubscriptionDTO, user: User): Mono<String> {
|
|
val subscription = Subscription(
|
|
id = null,
|
|
user = user,
|
|
endpoint = subscriptionDTO.endpoint,
|
|
auth = subscriptionDTO.keys["auth"].orEmpty(),
|
|
p256dh = subscriptionDTO.keys["p256dh"].orEmpty(),
|
|
isActive = true
|
|
)
|
|
|
|
return subscriptionRepo.save(subscription)
|
|
.flatMap { savedSubscription ->
|
|
Mono.just("Subscription created with ID: ${savedSubscription.id}")
|
|
}
|
|
.onErrorResume(DuplicateKeyException::class.java) {
|
|
logger.info("Subscription already exists. Skipping.")
|
|
Mono.just("Subscription already exists. Skipping.")
|
|
}
|
|
.onErrorResume { e ->
|
|
logger.error("Error while saving subscription: ${e.message}")
|
|
Mono.error(RuntimeException("Error while saving subscription"))
|
|
}
|
|
}
|
|
|
|
}
|