pipey 0.1.1

A lightweight HTTP-to-WebSocket event delivery service.
Documentation
use actix_web::{Responder, http::StatusCode, post, web};
use arifa::prelude::{MessageKind, MessageScope, WsMessage};

use crate::{
    models::{AppState, PublishPayload},
    utils::ApiResponse,
};

#[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 online = match state.arifa.is_user_online(&user_id).await {
        Ok(online) => online,
        Err(_) => {
            return ApiResponse::error(
                "Failed to check recipient status",
                StatusCode::INTERNAL_SERVER_ERROR,
            );
        }
    };

    if !online {
        return ApiResponse::error("Recipient is offline", StatusCode::NOT_FOUND);
    }

    let message = WsMessage {
        scope: MessageScope::Private,
        kind: MessageKind::Event,
        node_id: None,
        payload: payload.payload.clone(),
    };

    let channel = format!("User::{user_id}");

    match state.arifa.publish(&channel, &message).await {
        Ok(_) => ApiResponse::ok_empty("Event published", StatusCode::OK),
        Err(_) => ApiResponse::error("Failed to publish event", StatusCode::INTERNAL_SERVER_ERROR),
    }
}