noisebell/src/discord.rs

84 lines
No EOL
2.5 KiB
Rust

use std::env;
use std::time::Instant;
use anyhow::Result;
use serenity::all::{prelude::*, Color, CreateEmbed, CreateMessage};
use serenity::model::id::ChannelId;
use tracing::{info, error};
const COLOR_OPEN: Color = Color::new(0x00FF00); // Green for open
const COLOR_CLOSED: Color = Color::new(0xFF0000); // Red for closed
#[derive(Debug)]
pub enum SpaceEvent {
Open,
Closed,
Initializing,
}
pub struct DiscordClient {
client: Client,
}
impl DiscordClient {
pub async fn new() -> Result<Self> {
let token = env::var("DISCORD_TOKEN").expect("Expected DISCORD_TOKEN in environment");
if let Err(e) = serenity::utils::token::validate(&token) {
return Err(anyhow::anyhow!("Invalid Discord token format: {}", e));
}
let intents = GatewayIntents::GUILD_MESSAGES;
let client = Client::builder(&token, intents)
.await
.expect("Error creating Discord client");
Ok(Self { client })
}
pub async fn handle_event(&self, event: SpaceEvent) -> Result<()> {
let start = Instant::now();
info!("Handling Discord event: {:?}", event);
send_discord_message(&self.client, &event).await?;
let duration = start.elapsed();
info!("Discord event handled successfully in {:?}", duration);
Ok(())
}
}
async fn send_discord_message(client: &Client, event: &SpaceEvent) -> Result<()> {
let (title, description, color, thumbnail) = match event {
SpaceEvent::Open => (
"Noisebridge is Open!",
"It's time to start hacking.",
COLOR_OPEN,
"https://www.noisebridge.net/images/7/7f/Open.png"
),
SpaceEvent::Closed => (
"Noisebridge is Closed!",
"We'll see you again soon.",
COLOR_CLOSED,
"https://www.noisebridge.net/images/c/c9/Closed.png"
),
SpaceEvent::Initializing => return Ok(()), // Don't send message for initialization
};
let channel_id = env::var("DISCORD_CHANNEL_ID")
.expect("Expected DISCORD_CHANNEL_ID in environment")
.parse::<u64>()?;
let embed = CreateEmbed::new()
.title(title)
.description(description)
.color(color)
.thumbnail(thumbnail);
if let Err(why) = ChannelId::new(channel_id).send_message(&client.http, CreateMessage::default().add_embed(embed)).await {
error!("Error sending Discord message: {:?}", why);
return Err(anyhow::anyhow!("Failed to send Discord message: {}", why));
}
Ok(())
}