use crate::{
models::{AppState, PublishPayload},
utils::ApiResponse,
};
use actix_web::{Responder, http::StatusCode, post, web};
use arifa::prelude::{MessageKind, MessageScope, WsMessage};
use tracing::error;
#[post("/pipey/publish")]
pub async fn publish_to_pipe(
state: web::Data<AppState>,
payload: web::Json<PublishPayload>,
) -> impl Responder {
let user_id = payload.recipient.to_string();
let node_id = match state.arifa.get_user_node_id(&user_id).await {
Ok(Some(node_id)) => node_id,
Ok(None) => {
return ApiResponse::error("Recipient is offline", StatusCode::NOT_FOUND);
}
Err(err) => {
error!(%user_id, %err, "failed to lookup recipient node");
return ApiResponse::error(
"Failed to lookup recipient status",
StatusCode::INTERNAL_SERVER_ERROR,
);
}
};
let payload = payload.into_inner();
let channel = format!("User::{user_id}");
let message = WsMessage {
scope: MessageScope::Private, kind: MessageKind::Event,
node_id: Some(node_id), payload: payload.payload,
};
match state.arifa.publish(&channel, &message).await {
Ok(_) => ApiResponse::ok_empty("Event published", StatusCode::OK),
Err(err) => {
error!(%user_id, %err, "failed to publish event");
ApiResponse::error("Failed to publish event", StatusCode::INTERNAL_SERVER_ERROR)
}
}
}