Skip to content

Commit f54939f

Browse files
committed
refactor(api): update status api endpoint to be able to change the bot status via the panel
1 parent 950b562 commit f54939f

2 files changed

Lines changed: 96 additions & 2 deletions

File tree

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,115 @@
1+
use crate::commands::status::BotStatus as PresenceStatus;
2+
use crate::i18n::get_translated_message;
13
use crate::prelude::types::*;
24
use axum::Json;
35
use axum::extract::State;
46
use axum::http::StatusCode;
57
use axum::response::IntoResponse;
8+
use serenity::all::ActivityData;
9+
use std::str::FromStr;
610
use std::sync::Arc;
11+
use std::sync::atomic::Ordering;
712
use tokio::sync::Mutex;
813

914
pub async fn handle_status_bot(State(bot_state): State<Arc<Mutex<BotState>>>) -> impl IntoResponse {
1015
let state_lock = bot_state.lock().await;
16+
let presence_status = state_lock.presence_status.read().await.clone();
1117

1218
match state_lock.status {
1319
BotStatus::Running { .. } => (
1420
StatusCode::OK,
15-
Json(serde_json::json!({"status": "running"})),
21+
Json(serde_json::json!({
22+
"status": "running",
23+
"presence": presence_status
24+
})),
1625
),
1726
BotStatus::Stopped => (
1827
StatusCode::OK,
19-
Json(serde_json::json!({"status": "stopped"})),
28+
Json(serde_json::json!({
29+
"status": "stopped",
30+
"presence": presence_status
31+
})),
2032
),
2133
}
2234
}
35+
36+
#[derive(serde::Deserialize)]
37+
pub struct PresenceStatusRequest {
38+
pub status: String,
39+
}
40+
41+
pub async fn handle_set_presence(
42+
State(bot_state): State<Arc<Mutex<BotState>>>,
43+
Json(payload): Json<PresenceStatusRequest>,
44+
) -> impl IntoResponse {
45+
let presence = match PresenceStatus::from_str(&payload.status) {
46+
Ok(s) => s,
47+
Err(_) => {
48+
return (
49+
StatusCode::BAD_REQUEST,
50+
Json(serde_json::json!({"error": "Invalid status value"})),
51+
);
52+
}
53+
};
54+
55+
let state_lock = bot_state.lock().await;
56+
57+
let ctx_guard = state_lock.bot_context.read().await;
58+
let ctx = match ctx_guard.as_ref() {
59+
Some(c) => c,
60+
None => {
61+
return (
62+
StatusCode::SERVICE_UNAVAILABLE,
63+
Json(serde_json::json!({"error": "Bot is not running"})),
64+
);
65+
}
66+
};
67+
68+
let config = match &state_lock.config {
69+
Some(c) => c.clone(),
70+
None => {
71+
return (
72+
StatusCode::INTERNAL_SERVER_ERROR,
73+
Json(serde_json::json!({"error": "Config not loaded"})),
74+
);
75+
}
76+
};
77+
78+
match presence {
79+
PresenceStatus::Online => {
80+
state_lock.maintenance_mode.store(false, Ordering::Relaxed);
81+
ctx.set_activity(Some(ActivityData::playing(&config.bot.status)));
82+
ctx.online();
83+
}
84+
PresenceStatus::Idle => {
85+
ctx.idle();
86+
}
87+
PresenceStatus::Dnd => {
88+
ctx.dnd();
89+
}
90+
PresenceStatus::Invisible => {
91+
ctx.invisible();
92+
}
93+
PresenceStatus::Maintenance => {
94+
state_lock.maintenance_mode.store(true, Ordering::Relaxed);
95+
let maintenance_status = futures::executor::block_on(get_translated_message(
96+
&config,
97+
"status.maintenance_activity",
98+
None,
99+
None,
100+
None,
101+
None,
102+
));
103+
ctx.set_activity(Some(ActivityData::playing(&maintenance_status)));
104+
ctx.dnd();
105+
}
106+
}
107+
108+
let mut presence_guard = state_lock.presence_status.write().await;
109+
*presence_guard = payload.status.clone();
110+
111+
(
112+
StatusCode::OK,
113+
Json(serde_json::json!({"status": payload.status})),
114+
)
115+
}

rustmail/src/api/routes/bot.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub fn create_bot_router(bot_state: Arc<Mutex<BotState>>) -> Router<Arc<Mutex<Bo
1111
.route("/start", post(handle_start_bot))
1212
.route("/stop", post(handle_stop_bot))
1313
.route("/restart", post(handle_restart_bot))
14+
.route("/presence", post(handle_set_presence))
1415
.layer(axum::middleware::from_fn_with_state(
1516
bot_state.clone(),
1617
move |state, jar, req, next| {

0 commit comments

Comments
 (0)