wsprism_gateway/services/
chat.rs1use async_trait::async_trait;
2use serde::Deserialize;
3use serde_json::json;
4
5use wsprism_core::error::{Result, WsPrismError};
6use wsprism_core::protocol::text::Envelope;
7
8use crate::dispatch::TextService;
9use crate::realtime::{Outgoing, Payload, QoS, RealtimeCtx};
10
11#[derive(Default)]
12pub struct ChatService;
14
15impl ChatService {
16 pub fn new() -> Self {
17 Self
18 }
19}
20
21#[derive(Debug, Deserialize)]
22struct SendReq {
23 msg: String,
24}
25
26#[async_trait]
27impl TextService for ChatService {
28 fn svc(&self) -> &'static str {
29 "chat"
30 }
31
32 async fn handle(&self, ctx: RealtimeCtx, env: Envelope) -> Result<()> {
33 match env.msg_type.as_str() {
34 "send" => {
35 let room = env
36 .room
37 .clone()
38 .ok_or_else(|| WsPrismError::BadRequest("chat.send requires room".into()))?;
39
40 let raw = env
41 .data
42 .as_ref()
43 .ok_or_else(|| WsPrismError::BadRequest("chat.send requires data".into()))?;
44
45 let req: SendReq = serde_json::from_str(raw.get())
46 .map_err(|e| WsPrismError::BadRequest(format!("chat.send invalid data: {e}")))?;
47
48 let out = Outgoing {
49 qos: QoS::Reliable { timeout_ms: 1500 },
50 payload: Payload::TextJson(json!({
51 "v": 1,
52 "svc": "chat",
53 "type": "msg",
54 "room": room,
55 "data": { "from": ctx.user(), "msg": req.msg }
56 })),
57 };
58
59 ctx.publish_room_reliable(&room, out).await
61 }
62 _ => Err(WsPrismError::BadRequest("unknown chat type".into())),
63 }
64 }
65}