refactor (backend-rs): remove duplicate code

This commit is contained in:
naskya 2024-05-01 13:04:03 +09:00
parent c13d6344e1
commit e26b75c5c8
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C

View file

@ -24,9 +24,7 @@ pub enum Error {
static CLIENT: OnceCell<IsahcWebPushClient> = OnceCell::new();
fn get_client() -> Result<IsahcWebPushClient, WebPushError> {
CLIENT
.get_or_try_init(IsahcWebPushClient::new)
.cloned()
CLIENT.get_or_try_init(IsahcWebPushClient::new).cloned()
}
#[derive(strum::Display, PartialEq)]
@ -97,26 +95,45 @@ fn compact_content(
Ok(serde_json::from_value(Json::Object(object.clone()))?)
}
async fn handle_web_push_failure(
db: &DatabaseConnection,
err: WebPushError,
subscription_id: &str,
error_message: &str,
) -> Result<(), DbErr> {
match err {
WebPushError::BadRequest(_)
| WebPushError::ServerError(_)
| WebPushError::InvalidUri
| WebPushError::EndpointNotValid
| WebPushError::EndpointNotFound
| WebPushError::TlsError
| WebPushError::SslError
| WebPushError::InvalidPackageName
| WebPushError::MissingCryptoKeys
| WebPushError::InvalidCryptoKeys
| WebPushError::InvalidResponse => {
sw_subscription::Entity::delete_by_id(subscription_id)
.exec(db)
.await?;
tracing::info!("{}; {} was unsubscribed", error_message, subscription_id);
tracing::debug!("reason: {:#?}", err);
}
_ => {
tracing::warn!("{}; subscription id: {}", error_message, subscription_id);
tracing::info!("reason: {:#?}", err);
}
};
Ok(())
}
#[crate::export]
pub async fn send_push_notification(
receiver_user_id: &str,
kind: PushNotificationKind,
content: &serde_json::Value,
) -> Result<(), Error> {
const WEBPUSH_ERRORS_FOR_UNSUBSCRIBING: [WebPushError; 11] = [
WebPushError::BadRequest(None),
WebPushError::ServerError(None),
WebPushError::InvalidUri,
WebPushError::EndpointNotValid,
WebPushError::EndpointNotFound,
WebPushError::TlsError,
WebPushError::SslError,
WebPushError::InvalidPackageName,
WebPushError::MissingCryptoKeys,
WebPushError::InvalidCryptoKeys,
WebPushError::InvalidResponse,
];
let meta = fetch_meta(true).await?;
if !meta.enable_service_worker || meta.sw_public_key.is_none() || meta.sw_private_key.is_none()
@ -143,6 +160,7 @@ pub async fn send_push_notification(
chrono::Utc::now().timestamp_millis(),
serde_json::to_string(&compact_content(&kind, content.clone())?)?
);
tracing::trace!("payload: {:#?}", payload);
for subscription in subscriptions.iter() {
if !subscription.send_read_message
@ -179,31 +197,10 @@ pub async fn send_push_notification(
.clone()
.add_sub_info(&subscription_info)
.build();
if let Err(err) = &signature {
let error_kind = std::mem::discriminant(err);
if WEBPUSH_ERRORS_FOR_UNSUBSCRIBING
.iter()
.map(std::mem::discriminant)
.any(|e| error_kind == e)
{
sw_subscription::Entity::delete_by_id(&subscription.id)
.exec(db)
.await?;
tracing::info!(
"failed to build a push notification signature; {} was unsubscribed",
subscription.id
);
tracing::debug!("reason: {:#?}", err);
} else {
tracing::warn!(
"failed to build a push notification signature; subscription id: {}",
subscription.id
);
tracing::info!("reason: {:#?}", err);
}
if let Err(err) = signature {
handle_web_push_failure(db, err, &subscription.id, "failed to build a signature")
.await?;
continue;
}
@ -213,63 +210,17 @@ pub async fn send_push_notification(
message_builder.set_vapid_signature(signature.unwrap());
let message = message_builder.build();
if let Err(err) = message {
let error_kind = std::mem::discriminant(&err);
if WEBPUSH_ERRORS_FOR_UNSUBSCRIBING
.iter()
.map(std::mem::discriminant)
.any(|e| error_kind == e)
{
sw_subscription::Entity::delete_by_id(&subscription.id)
.exec(db)
.await?;
tracing::info!(
"failed to build a push notification payload; {} was unsubscribed",
subscription.id
);
tracing::debug!("reason: {:#?}", err);
} else {
tracing::warn!(
"failed to build a push notification payload; subscription id: {}",
subscription.id
);
tracing::info!("reason: {:#?}", err);
}
handle_web_push_failure(db, err, &subscription.id, "failed to build a payload").await?;
continue;
}
if let Err(err) = get_client()?.send(message.unwrap()).await {
handle_web_push_failure(db, err, &subscription.id, "failed to send").await?;
continue;
}
let result = get_client()?.send(message.unwrap()).await;
if let Err(err) = result {
let error_kind = std::mem::discriminant(&err);
if WEBPUSH_ERRORS_FOR_UNSUBSCRIBING
.iter()
.map(std::mem::discriminant)
.any(|e| error_kind == e)
{
sw_subscription::Entity::delete_by_id(&subscription.id)
.exec(db)
.await?;
tracing::info!(
"failed to send a push notification; {} was unsubscribed",
subscription.id
);
tracing::debug!("reason: {:#?}", err);
} else {
tracing::warn!(
"failed to send a push notification; subscription id: {}",
subscription.id
);
tracing::info!("reason: {:#?}", err);
}
continue;
}
tracing::debug!("success; subscription id: {}", subscription.id);
}
Ok(())