add discord membercount service & endpoint
a background worker is added that sends an approximate member count request every 60 seconds, caches it into memory, and serves the cache on a public endpoint
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::discordbot::MAIN_GUILD_ID;
|
||||
use chrono::{Datelike, Utc};
|
||||
use chrono_tz::Europe::Warsaw;
|
||||
use rand::{SeedableRng, seq::IndexedRandom};
|
||||
@@ -21,8 +22,6 @@ pub fn init_service(ctx: &Context, guild_id: &GuildId) {
|
||||
});
|
||||
}
|
||||
|
||||
const MAIN_GUILD_ID: GuildId = GuildId::new(447075692664979466);
|
||||
|
||||
pub enum Event {
|
||||
Normal,
|
||||
PolskaGórą,
|
||||
|
||||
22
src/discordbot/member_count/mod.rs
Normal file
22
src/discordbot/member_count/mod.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use crate::discordbot::MAIN_GUILD_ID;
|
||||
use serenity::all::{Context, GuildId};
|
||||
use service::run_membercount_service;
|
||||
use tracing::info;
|
||||
|
||||
mod service;
|
||||
|
||||
pub use service::get_member_count;
|
||||
|
||||
pub fn init_service(ctx: &Context, guild_id: &GuildId) {
|
||||
let (ctx, guild_id) = (ctx.clone(), guild_id.clone());
|
||||
info!("Initialising discord member count service...");
|
||||
|
||||
if guild_id != MAIN_GUILD_ID {
|
||||
info!("Guild member count service not initialised; Bot not running on main guild.");
|
||||
return;
|
||||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
run_membercount_service(ctx, guild_id).await;
|
||||
});
|
||||
}
|
||||
33
src/discordbot/member_count/service.rs
Normal file
33
src/discordbot/member_count/service.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use serenity::all::{Context, GuildId};
|
||||
use std::{
|
||||
sync::{Arc, LazyLock},
|
||||
time::Duration,
|
||||
};
|
||||
use tokio::{sync::RwLock, time::sleep};
|
||||
use tracing::error;
|
||||
|
||||
static MEMBER_COUNT: LazyLock<Arc<RwLock<Option<u64>>>> =
|
||||
LazyLock::new(|| Arc::new(RwLock::new(None)));
|
||||
|
||||
pub async fn run_membercount_service(ctx: Context, guild_id: GuildId) {
|
||||
loop {
|
||||
update_member_count(&ctx, guild_id).await;
|
||||
sleep(Duration::from_secs(60)).await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_member_count() -> Option<u64> {
|
||||
*MEMBER_COUNT.read().await
|
||||
}
|
||||
|
||||
async fn update_member_count(ctx: &Context, guild_id: GuildId) {
|
||||
let count = match ctx.http.get_guild_with_counts(guild_id).await {
|
||||
Ok(guild) => guild.approximate_member_count,
|
||||
Err(e) => {
|
||||
error!("Could not fetch guild member count: {e}");
|
||||
None
|
||||
}
|
||||
};
|
||||
let mut member_count = MEMBER_COUNT.write().await;
|
||||
*member_count = count;
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
use serenity::{
|
||||
all::{CreateInteractionResponse, CreateInteractionResponseMessage, Interaction, Ready},
|
||||
all::{
|
||||
CreateInteractionResponse, CreateInteractionResponseMessage, GuildId, Interaction, Ready,
|
||||
},
|
||||
async_trait,
|
||||
prelude::*,
|
||||
};
|
||||
@@ -12,8 +14,12 @@ struct Handler;
|
||||
|
||||
mod commands;
|
||||
mod events;
|
||||
mod member_count;
|
||||
mod status;
|
||||
|
||||
const MAIN_GUILD_ID: GuildId = GuildId::new(447075692664979466);
|
||||
pub use member_count::get_member_count;
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for Handler {
|
||||
async fn ready(&self, ctx: Context, ready: Ready) {
|
||||
@@ -37,6 +43,7 @@ impl EventHandler for Handler {
|
||||
|
||||
status::init_service(&ctx);
|
||||
events::init_service(&ctx, &guild_id);
|
||||
member_count::init_service(&ctx, &guild_id);
|
||||
}
|
||||
|
||||
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
use axum::{Router, routing::get};
|
||||
use axum::{Router, http::StatusCode, routing::get};
|
||||
|
||||
pub fn init() -> Router {
|
||||
Router::new().route("/", get(async || "root"))
|
||||
Router::new()
|
||||
.route("/", get(async || "root"))
|
||||
.route("/discord/member-count", get(get_member_count))
|
||||
}
|
||||
|
||||
async fn get_member_count() -> (StatusCode, String) {
|
||||
match crate::discordbot::get_member_count().await {
|
||||
Some(count) => (StatusCode::OK, format!("{count}")),
|
||||
None => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("An error occured - could not fetch discord member count."),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user