Skip to content

Commit

Permalink
feat(discord): #62 created basic bot usage
Browse files Browse the repository at this point in the history
- updated dependencies to build slash commands

- made command for `ping` endpoint

- loaded config from environment
  • Loading branch information
miguelcsx committed Oct 1, 2024
1 parent ade7f3e commit 9fa9aa8
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 36 deletions.
7 changes: 2 additions & 5 deletions aura/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from aura.api.endpoints import (
activity,
answer,
basic,
question,
study_session,
user,
Expand All @@ -22,6 +23,7 @@

app.include_router(activity.router)
app.include_router(answer.router)
app.include_router(basic.router)
app.include_router(question.router)
app.include_router(study_session.router)
app.include_router(user.router)
Expand All @@ -35,11 +37,6 @@ def get_session():
db.close()


@app.get("/")
def read_root():
return {"message": "Welcome to AURA"}


def main() -> None:
uvicorn.run(app, host="0.0.0.0", port=8000)

Expand Down
17 changes: 17 additions & 0 deletions aura/api/endpoints/basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# aura/api/endpoints/basic.py

from fastapi import (
APIRouter,
)

router = APIRouter()


@router.get("/")
def read_root():
return {"message": "Welcome to AURA"}


@router.get("/ping")
def ping():
return {"message": "pong"}
18 changes: 11 additions & 7 deletions discord/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
[package]
name = "discord"
name = "aura-discord"
version = "0.1.0"
edition = "2021"

[dependencies]
clap = "4.5.18"
dotenv = "0.15.0"
once_cell = "1.19.0"
reqwest = "0.12.7"
serenity = "0.12.2"
tokio = "1.40.0"
dotenv = "0.15"
reqwest = { version = "0.11", features = ["json"] }
clap = { version = "4.0", features = ["derive"] }
poise = "0.6.1"
tracing = "0.1.40"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
anyhow = "1.0.89"
once_cell = "1.20.1"
serde = "1.0.210"
serde_json = "1.0.128"
3 changes: 3 additions & 0 deletions discord/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// cli/mod.rs

pub mod bot;
3 changes: 3 additions & 0 deletions discord/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// commands/mod.rs

pub mod ping;
20 changes: 20 additions & 0 deletions discord/src/commands/ping.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// commands/ping.rs

use crate::services::api_client;
use crate::types::{Context, Error};
use anyhow::Result;

// Fetch data from the `/ping` endpoint
#[poise::command(slash_command, prefix_command)]
pub async fn ping(ctx: Context<'_>) -> Result<(), Error> {
// Call the API client to make a GET request to `/ping`
match api_client::get("ping").await {
Ok(data) => {
ctx.say(data.to_string()).await?;
}
Err(e) => {
ctx.say(format!("Error: {}", e)).await?;
}
}
Ok(())
}
2 changes: 1 addition & 1 deletion discord/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// discord/src/config/mod.rs

pub mod settings;
pub mod settings;
1 change: 1 addition & 0 deletions discord/src/events/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// events/mod.rs
44 changes: 31 additions & 13 deletions discord/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
// main.rs

mod types;
mod commands;
mod config;
mod services;

use config::settings;
use services::api_client;
use types::Data;
use poise::serenity_prelude as serenity;
use crate::config::settings::{load_config, get_config};

#[tokio::main(flavor = "current_thread")]
async fn main() {
// Load the configuration
settings::load_config();
load_config();
let config = get_config();
let token = &config.discord_token;

// Get the configuration
let config = settings::get_config();
// Set up intents
let intents = serenity::GatewayIntents::non_privileged();

// Print the configuration
println!("API URL: {}", config.api_url);
println!("Discord Token: {}", config.discord_token);
// Define the bot framework
let framework = poise::Framework::builder()
.options(poise::FrameworkOptions {
commands: vec![
commands::ping::ping(),
],
..Default::default()
})
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
Ok(Data {})
})
})
.build();

// Get data from the API
match api_client::get("").await {
Ok(response) => println!("Response: {}", response),
Err(err) => eprintln!("Error: {}", err),
}
let client = serenity::ClientBuilder::new(token, intents)
.framework(framework)
.await;
client.unwrap().start().await.unwrap();
}
32 changes: 22 additions & 10 deletions discord/src/services/api_client.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// discord/src/services/api_client.rs
// services/api_client.rs

use reqwest::Client;
use crate::config::settings::get_config;
use std::error::Error;
use anyhow::{Result, Context};
use serde_json::Value; // Add this import


pub async fn get(endpoint: &str) -> Result<String, Box<dyn Error>> {
pub async fn get(endpoint: &str) -> Result<String> {
// Get the configuration
let config = get_config();

Expand All @@ -16,16 +16,28 @@ pub async fn get(endpoint: &str) -> Result<String, Box<dyn Error>> {
let client = Client::new();

// Send a GET request to the API
let response = client.get(&url)
let response = client
.get(&url)
.header("Authorization", &config.discord_token)
.send()
.await?;
.await
.with_context(|| format!("Failed to send request to {url}"))?;

if response.status().is_success() {
let body = response.text().await?;
Ok(body)
let body = response.text().await
.with_context(|| "Failed to parse response body")?;

// Parse the JSON response
let json: Value = serde_json::from_str(&body)
.with_context(|| "Failed to parse JSON response")?;

// Extract the message
if let Some(message) = json.get("message").and_then(Value::as_str) {
Ok(message.to_string())
} else {
Err(anyhow::anyhow!("No message found in response"))
}
} else {
Err("Failed to get data".into())
Err(anyhow::anyhow!("API request failed with status: {}", response.status()))
}
}

6 changes: 6 additions & 0 deletions discord/src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// types.rs

pub struct Data {}

pub type Error = Box<dyn std::error::Error + Send + Sync>;
pub type Context<'a> = poise::Context<'a, Data, Error>;
2 changes: 2 additions & 0 deletions discord/src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// utils/mod.rs

0 comments on commit 9fa9aa8

Please sign in to comment.