mirror of
https://github.com/n08i40k/schedule-parser-rusted.git
synced 2025-12-06 17:57:47 +03:00
Эндпоинт fcm/set-token.
This commit is contained in:
@@ -2,5 +2,5 @@ CREATE TABLE fcm
|
|||||||
(
|
(
|
||||||
user_id text PRIMARY KEY NOT NULL REFERENCES users (id),
|
user_id text PRIMARY KEY NOT NULL REFERENCES users (id),
|
||||||
token text NOT NULL,
|
token text NOT NULL,
|
||||||
topics text[] NOT NULL
|
topics text[] NOT NULL CHECK ( array_position(topics, null) is null )
|
||||||
);
|
);
|
||||||
@@ -50,7 +50,8 @@ pub fn get_api_scope<
|
|||||||
|
|
||||||
let fcm_scope = utoipa_actix_web::scope("/fcm")
|
let fcm_scope = utoipa_actix_web::scope("/fcm")
|
||||||
.wrap(JWTAuthorization)
|
.wrap(JWTAuthorization)
|
||||||
.service(routes::fcm::update_callback);
|
.service(routes::fcm::update_callback)
|
||||||
|
.service(routes::fcm::set_token);
|
||||||
|
|
||||||
let vk_id_scope = utoipa_actix_web::scope("/vkid") //
|
let vk_id_scope = utoipa_actix_web::scope("/vkid") //
|
||||||
.service(routes::vk_id::oauth);
|
.service(routes::vk_id::oauth);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
mod update_callback;
|
mod update_callback;
|
||||||
|
mod set_token;
|
||||||
|
|
||||||
pub use update_callback::*;
|
pub use update_callback::*;
|
||||||
|
pub use set_token::*;
|
||||||
|
|||||||
112
src/routes/fcm/set_token.rs
Normal file
112
src/routes/fcm/set_token.rs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
use crate::app_state::AppState;
|
||||||
|
use crate::database;
|
||||||
|
use crate::database::models::FCM;
|
||||||
|
use crate::extractors::authorized_user::UserExtractor;
|
||||||
|
use crate::extractors::base::SyncExtractor;
|
||||||
|
use crate::utility::mutex::{MutexScope, MutexScopeAsync};
|
||||||
|
use actix_web::{HttpResponse, Responder, patch, web};
|
||||||
|
use diesel::{RunQueryDsl, SaveChangesDsl};
|
||||||
|
use firebase_messaging_rs::FCMClient;
|
||||||
|
use firebase_messaging_rs::topic::{TopicManagementError, TopicManagementSupport};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Params {
|
||||||
|
pub token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_fcm(
|
||||||
|
app_state: &web::Data<AppState>,
|
||||||
|
user_data: &UserExtractor<true>,
|
||||||
|
token: String,
|
||||||
|
) -> Result<FCM, diesel::result::Error> {
|
||||||
|
match user_data.fcm() {
|
||||||
|
Some(fcm) => {
|
||||||
|
let mut fcm = fcm.clone();
|
||||||
|
fcm.token = token;
|
||||||
|
|
||||||
|
Ok(fcm)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let fcm = FCM {
|
||||||
|
user_id: user_data.user().id.clone(),
|
||||||
|
token,
|
||||||
|
topics: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
match app_state.database.scope(|conn| {
|
||||||
|
diesel::insert_into(database::schema::fcm::table)
|
||||||
|
.values(&fcm)
|
||||||
|
.execute(conn)
|
||||||
|
}) {
|
||||||
|
Ok(_) => Ok(fcm),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[utoipa::path(responses((status = OK)))]
|
||||||
|
#[patch("/set-token")]
|
||||||
|
pub async fn set_token(
|
||||||
|
app_state: web::Data<AppState>,
|
||||||
|
web::Query(params): web::Query<Params>,
|
||||||
|
user_data: SyncExtractor<UserExtractor<true>>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let user_data = user_data.into_inner();
|
||||||
|
|
||||||
|
// If token not changes - exit.
|
||||||
|
if let Some(fcm) = user_data.fcm() {
|
||||||
|
if fcm.token == params.token {
|
||||||
|
return HttpResponse::Ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fcm = get_fcm(&app_state, &user_data, params.token.clone()).await;
|
||||||
|
if let Err(e) = fcm {
|
||||||
|
eprintln!("Failed to get FCM: {e}");
|
||||||
|
return HttpResponse::Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut fcm = fcm.ok().unwrap();
|
||||||
|
|
||||||
|
// Add default topics.
|
||||||
|
if !fcm.topics.contains(&Some("common".to_string())) {
|
||||||
|
fcm.topics.push(Some("common".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribe to default topics.
|
||||||
|
if let Some(e) = app_state
|
||||||
|
.fcm_client
|
||||||
|
.async_scope(
|
||||||
|
async |client: &mut FCMClient| -> Result<(), TopicManagementError> {
|
||||||
|
let mut tokens: Vec<String> = Vec::new();
|
||||||
|
tokens.push(fcm.token.clone());
|
||||||
|
|
||||||
|
for topic in fcm.topics.clone() {
|
||||||
|
if let Some(topic) = topic {
|
||||||
|
client.register_tokens_to_topic(topic.clone(), tokens.clone()).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.err()
|
||||||
|
{
|
||||||
|
eprintln!("Failed to subscribe token to topic: {:?}", e);
|
||||||
|
return HttpResponse::Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write updates to db.
|
||||||
|
if let Some(e) = app_state
|
||||||
|
.database
|
||||||
|
.scope(|conn| fcm.save_changes::<FCM>(conn))
|
||||||
|
.err()
|
||||||
|
{
|
||||||
|
eprintln!("Failed to update FCM object: {e}");
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse::Ok()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user