Compare commits

..

31 commits
1.0.0 ... main

Author SHA1 Message Date
ecb0e2af30
Merge pull request #14
Add more details to profiles
2023-07-13 15:17:27 -04:00
27f5fa50d0
Add more detail to player profiles 2023-07-13 15:12:13 -04:00
b002eb4be6
Merge pull request #13 from ethanrusz/dependabot/cargo/openssl-0.10.55
Bump openssl from 0.10.51 to 0.10.55
2023-07-06 21:09:02 -04:00
dependabot[bot]
56d30336fa
Bump openssl from 0.10.51 to 0.10.55
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.51 to 0.10.55.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.51...openssl-v0.10.55)

---
updated-dependencies:
- dependency-name: openssl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-21 22:56:36 +00:00
9777234d9e
Merge pull request #10 from ethanrusz/dependabot/cargo/tokio-1.24.2
Bump tokio from 1.24.1 to 1.24.2
2023-04-23 14:52:47 -04:00
fc501b5945
Merge pull request #11 from ethanrusz/dependabot/cargo/h2-0.3.18
Bump h2 from 0.3.15 to 0.3.18
2023-04-23 14:52:38 -04:00
530743a0b2
Merge pull request #12 from ethanrusz/dependabot/cargo/openssl-0.10.51
Bump openssl from 0.10.45 to 0.10.51
2023-04-23 14:52:19 -04:00
dependabot[bot]
55a8117d3c
Bump openssl from 0.10.45 to 0.10.51
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.45 to 0.10.51.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.45...openssl-v0.10.51)

---
updated-dependencies:
- dependency-name: openssl
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-23 18:35:05 +00:00
dependabot[bot]
d7d1aa928e
Bump h2 from 0.3.15 to 0.3.18
Bumps [h2](https://github.com/hyperium/h2) from 0.3.15 to 0.3.18.
- [Release notes](https://github.com/hyperium/h2/releases)
- [Changelog](https://github.com/hyperium/h2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/h2/compare/v0.3.15...v0.3.18)

---
updated-dependencies:
- dependency-name: h2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-23 18:35:02 +00:00
dependabot[bot]
2fdd0e54dd
Bump tokio from 1.24.1 to 1.24.2
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.24.1 to 1.24.2.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/commits)

---
updated-dependencies:
- dependency-name: tokio
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-23 18:35:01 +00:00
8b8441aaf5
Merge pull request #9 from ethanrusz/pog
Format pog command
2023-03-14 13:59:58 -04:00
664f92e9ba
Format pog command 2023-03-14 13:59:27 -04:00
f4889fadc4
Merge pull request #8 from ethanrusz/pog
Add pog command
2023-03-14 13:52:43 -04:00
1fabf2c76f
Add pog command 2023-03-14 13:48:35 -04:00
d788e77012
Merge pull request #7 from ethanrusz/session-handling
Add ping command
2023-03-08 13:36:08 -05:00
b68bac5e10
Add ping command 2023-03-08 13:35:07 -05:00
7d360ab091
Merge pull request #6 from ethanrusz/session-handling
Bot cleanup
2023-03-08 13:28:33 -05:00
46608062f4
Update README.md 2023-03-08 13:28:20 -05:00
205c806369
Removed code and phrases that Discord didn't like 2023-03-08 13:25:50 -05:00
832c78a603
Code cleanup 2023-02-13 15:37:52 -05:00
e943135d2e
Merge pull request #5
Switch to global command registration
2023-02-07 17:51:48 -05:00
59fd486e12
Formatting cleanup and command registration changes 2023-02-07 17:49:48 -05:00
584d4ef62c
Merge pull request #3 from ethanrusz/random-god
Pick a random god from Smite API!
2023-01-31 22:20:05 -05:00
f8bbb22d37
Connect to Smite API and pick random gods 2023-01-31 22:15:31 -05:00
54e351186a
Remove crate from pub mod elements 2023-01-31 19:25:10 -05:00
0fabaa7ca4
Merge pull request #2
Update activity status on ready
2023-01-27 14:29:05 -05:00
4ca472471a
Add prefix to ping command 2023-01-27 14:27:17 -05:00
a7599f55e1
Set activity status and fix command reg 2023-01-27 14:26:58 -05:00
c9a2a6ca8d
Update formatting 2023-01-27 12:09:46 -05:00
c3a98c4431
Update formatting 2023-01-21 19:49:39 -05:00
b349263fd0
Update team random setup 2023-01-21 19:46:49 -05:00
14 changed files with 369 additions and 120 deletions

1
.gitignore vendored
View file

@ -14,3 +14,4 @@ Cargo.lock
/target /target
/.idea/ /.idea/
/quotes.txt

17
Cargo.lock generated
View file

@ -451,9 +451,9 @@ dependencies = [
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.15" version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21"
dependencies = [ dependencies = [
"bytes", "bytes",
"fnv", "fnv",
@ -800,9 +800,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
[[package]] [[package]]
name = "openssl" name = "openssl"
version = "0.10.45" version = "0.10.55"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cfg-if", "cfg-if",
@ -832,11 +832,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]] [[package]]
name = "openssl-sys" name = "openssl-sys"
version = "0.9.80" version = "0.9.90"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6"
dependencies = [ dependencies = [
"autocfg",
"cc", "cc",
"libc", "libc",
"pkg-config", "pkg-config",
@ -1405,9 +1404,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.24.1" version = "1.24.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d9f76183f91ecfb55e1d7d5602bd1d979e38a3a522fe900241cf195624d67ae" checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"bytes", "bytes",

View file

@ -7,7 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
poise = "0.5.2" poise = "0.5.2"
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.24.2", features = ["macros", "rt-multi-thread"] }
rand = "0.8.5" rand = "0.8.5"
chrono = "0.4.23" chrono = "0.4.23"
md5 = "0.7.0" md5 = "0.7.0"

View file

@ -1,6 +1,6 @@
# echbot # echbot
A trash bot for Smite fun. A helper bot for Smite fun.
## Environment ## Environment
@ -13,8 +13,3 @@ environment:
- DEV_ID=your_hi-rez_dev_id - DEV_ID=your_hi-rez_dev_id
- AUTH_KEY=your_hi-rez_auth_key - AUTH_KEY=your_hi-rez_auth_key
``` ```
## Quotes
A `quotes.txt` file must be present in the root directory for the ping command to function. The format is one quote per
line.

118
src/commands/api.rs Normal file
View file

@ -0,0 +1,118 @@
use md5::Digest;
use rand::seq::SliceRandom;
use reqwest::{Error, Response};
use serde::Deserialize;
#[derive(Deserialize, Debug)]
#[allow(dead_code)]
struct Session {
ret_msg: String,
session_id: String,
timestamp: String,
}
#[derive(Deserialize, Debug)]
#[allow(dead_code)]
pub struct God {
#[serde(rename = "Name")]
name: String,
ret_msg: Option<String>,
}
#[derive(Deserialize, Debug)]
#[allow(dead_code)]
pub struct Profile {
#[serde(rename = "Name")]
pub name: Option<String>,
#[serde(rename = "Personal_Status_Message")]
pub personal_status_message: Option<String>,
pub hz_player_name: Option<String>,
#[serde(rename = "HoursPlayed")]
pub hours_played: i32,
#[serde(rename = "Losses")]
pub losses: i32,
#[serde(rename = "Wins")]
pub wins: i32,
#[serde(rename = "Team_Name")]
pub clan: Option<String>,
#[serde(rename = "Level")]
pub level: i32,
#[serde(rename = "Platform")]
pub platform: Option<String>,
#[serde(rename = "Leaves")]
pub leaves: i32,
pub ret_msg: Option<String>,
}
async fn get_utc_timestamp() -> String {
chrono::Utc::now().format("%Y%m%d%H%M%S").to_string()
}
async fn get_signature(
dev_id: &String,
method: &str,
auth_key: &String,
timestamp: &String,
) -> String {
let hash: Digest = md5::compute(format!("{dev_id}{method}{auth_key}{timestamp}"));
format!("{:x}", hash)
}
async fn create_session() -> Result<Session, Error> {
let dev_id: String = std::env::var("DEV_ID").expect("Missing DEV_ID");
let auth_key: String = std::env::var("AUTH_KEY").expect("Missing AUTH_KEY");
let timestamp: String = get_utc_timestamp().await;
let signature: String = get_signature(&dev_id, "createsession", &auth_key, &timestamp).await;
let request: String = format!(
"https://api.smitegame.com/smiteapi.svc/createsessionJson/{dev_id}/{signature}/{timestamp}"
);
let response: Response = reqwest::get(&request).await?;
let session: Session = response.json().await?;
Ok(session)
}
async fn get_gods() -> Result<Vec<God>, Error> {
let dev_id: String = std::env::var("DEV_ID").expect("Missing DEV_ID");
let auth_key: String = std::env::var("AUTH_KEY").expect("Missing AUTH_KEY");
let session_id: String = create_session().await?.session_id;
let timestamp: String = get_utc_timestamp().await;
let signature: String = get_signature(&dev_id, "getgods", &auth_key, &timestamp).await;
let request: String = format!(
"https://api.smitegame.com/smiteapi.svc/getgodsJson/{dev_id}/{signature}/{session_id}/{timestamp}/1"
);
let response: Response = reqwest::get(&request).await?;
let gods: Vec<God> = response.json().await?;
Ok(gods)
}
pub async fn get_random_god() -> Result<String, Error> {
let gods: Vec<God> = get_gods().await?;
let god: &God = gods.choose(&mut rand::thread_rng()).unwrap();
let name: String = god.name.clone();
Ok(name)
}
pub async fn get_player(player: String) -> Result<Vec<Profile>, Error> {
let dev_id: String = std::env::var("DEV_ID").expect("Missing DEV_ID");
let auth_key: String = std::env::var("AUTH_KEY").expect("Missing AUTH_KEY");
let session_id: String = create_session().await?.session_id;
let timestamp: String = get_utc_timestamp().await;
let signature: String = get_signature(&dev_id, "getplayer", &auth_key, &timestamp).await;
let request: String = format!(
"https://api.smitegame.com/smiteapi.svc/getplayerJson/{dev_id}/{signature}/{session_id}/{timestamp}/{player}"
);
let response: Response = reqwest::get(&request).await?;
let profiles: Vec<Profile> = response.json().await?;
Ok(profiles)
}

View file

@ -1,3 +1,8 @@
// Group all commands for registration // Group all commands for registration
pub(crate) mod slur; mod api;
pub(crate) mod team; pub mod ping;
pub mod pog;
pub mod profile;
pub mod random;
pub mod register;
pub mod team;

8
src/commands/ping.rs Normal file
View file

@ -0,0 +1,8 @@
use crate::{Context, Error};
/// Replies with a pong
#[poise::command(slash_command, prefix_command)]
pub async fn ping(ctx: Context<'_>) -> Result<(), Error> {
ctx.say("Pong! 🏓").await?;
Ok(())
}

35
src/commands/pog.rs Normal file
View file

@ -0,0 +1,35 @@
use crate::serenity;
use crate::{Context, Error};
#[poise::command(slash_command, subcommands("up", "down"))]
pub async fn pog(_ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
/// Increases the pogs
#[poise::command(slash_command)]
pub async fn up(ctx: Context<'_>) -> Result<(), Error> {
ctx.send(|f| {
f.embed(|f| {
f.title("Pog Status")
.description("The pog level has been increased.")
.color(serenity::Colour::DARK_GREEN)
})
})
.await?;
Ok(())
}
/// Decreases the pogs
#[poise::command(slash_command)]
pub async fn down(ctx: Context<'_>) -> Result<(), Error> {
ctx.send(|f| {
f.embed(|f| {
f.title("Pog Status")
.description("The pog level has been decreased.")
.color(serenity::Colour::RED)
})
})
.await?;
Ok(())
}

59
src/commands/profile.rs Normal file
View file

@ -0,0 +1,59 @@
use crate::commands::api::get_player;
use crate::serenity;
use crate::{Context, Error};
/// Looks up a player's profile
#[poise::command(slash_command)]
pub async fn profile(
ctx: Context<'_>,
#[rename = "player"] player_name: String,
) -> Result<(), Error> {
let profiles = get_player(player_name).await?;
let profile = profiles.first().unwrap();
if profile.name.is_none() {
ctx.send(|f| {
f.embed(|f| {
f.title("Hidden")
.description("This profile is hidden.")
.color(serenity::Colour::RED)
})
})
.await?;
return Ok(());
}
let winrate = (profile.wins as f32 / (profile.wins as f32 + profile.losses as f32)) * 100f32;
ctx.send(|f| {
f.embed(|f| {
f.title(format!("{}", profile.name.as_ref().unwrap()))
.description(format!(
"{}'s statistics.",
profile.hz_player_name.as_ref().unwrap()
))
.field(
"Clan Name",
format!("{}", profile.clan.as_ref().unwrap_or(&String::from(""))),
true,
)
.field(
"Status Message",
format!("{}", profile.personal_status_message.as_ref().unwrap()),
false,
)
.field("Level", format!("{}", profile.level), true)
.field("Hours Played", format!("{}", profile.hours_played), true)
.field("Leaves", format!("{}", profile.leaves), true)
.field(
"Platform",
format!("{}", profile.platform.as_ref().unwrap()),
false,
)
.field("Wins", format!("{}", profile.wins), true)
.field("Losses", format!("{}", profile.losses), true)
.field("Winrate", format!("{:.2}%", winrate), true)
.color(serenity::Colour::BLURPLE)
})
})
.await?;
Ok(())
}

24
src/commands/random.rs Normal file
View file

@ -0,0 +1,24 @@
use crate::commands::api::get_random_god;
use crate::serenity;
use crate::{Context, Error};
/// Picks a random something
#[poise::command(slash_command, subcommands("god"))]
pub async fn random(_ctx: Context<'_>) -> Result<(), Error> {
Ok(())
}
/// Picks a random god
#[poise::command(slash_command)]
pub async fn god(ctx: Context<'_>) -> Result<(), Error> {
let god: String = get_random_god().await?;
ctx.send(|f| {
f.embed(|f| {
f.title("Random God")
.description(format!("Your random god is **{god}**!"))
.color(serenity::Colour::BLUE)
})
})
.await?;
Ok(())
}

7
src/commands/register.rs Normal file
View file

@ -0,0 +1,7 @@
use crate::{Context, Error};
#[poise::command(prefix_command, owners_only)]
pub async fn register(ctx: Context<'_>) -> Result<(), Error> {
poise::builtins::register_application_commands_buttons(ctx).await?;
Ok(())
}

View file

@ -1,29 +0,0 @@
use crate::{Context, Error};
use crate::serenity;
use rand::seq::IteratorRandom;
use std::{
fs::File,
io::{BufRead, BufReader},
};
/// Basically a ping command
#[poise::command(slash_command)]
pub(crate) async fn slur(
ctx: Context<'_>,
) -> Result<(), Error> {
let file = File::open("quotes.txt")
.unwrap_or_else(|_e| panic!("Quote file missing.")); // Open the quotes file
let file = BufReader::new(file); // Read the quotes file
let quotes = file.lines()
.map(|res| res.expect("Failed to read line."));
let quote = quotes.choose(&mut rand::thread_rng())
.expect("No lines in file."); // Pick a random quote
ctx.send(|f| f
.embed(|f| f
.title("DMBrandon Sez:")
.description(format!("\"{}\"", quote))
.color(serenity::Colour::GOLD)
)).await?; // Send embed with team picks
Ok(())
}

View file

@ -1,91 +1,120 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{Context, Error};
use crate::serenity;
use poise::serenity_prelude::{Guild, Member, UserId, VoiceState};
use rand::seq::SliceRandom;
use std::string::String; use std::string::String;
/// Return a string of pingable IDs from a slice of UserIds use poise::serenity_prelude::{Guild, Member, UserId, VoiceState};
fn team_to_ping(team: &[&&UserId]) -> String { use rand::seq::SliceRandom;
return team.iter().map(|o| format!("<@{}>", o.to_string())).collect::<Vec<String>>().join(", ");
use crate::serenity;
use crate::{Context, Error};
/// Return a string of pingable IDs from a slice of string UserIds
fn team_to_ping(team: &[&String]) -> String {
team.iter()
.map(|o| format!("<@{o}>"))
.collect::<Vec<String>>()
.join(", ")
} }
/// Splits up players for custom matches /// Splits up players for custom matches
#[poise::command(slash_command)] #[poise::command(slash_command)]
pub(crate) async fn team( pub async fn team(
ctx: Context<'_>, ctx: Context<'_>,
#[description = "Your order voice channel"] #[description = "Your order voice channel"]
#[rename = "order"] #[rename = "order"]
#[channel_types("Voice")] order_channel: serenity::Channel, // Channel to pick all members from #[channel_types("Voice")]
order_channel: serenity::Channel, // Channel to pick all members from
#[description = "Your chaos voice channel"] #[description = "Your chaos voice channel"]
#[rename = "chaos"] #[rename = "chaos"]
#[channel_types("Voice")] chaos_channel: serenity::Channel, // Channel to move chaos team members into #[channel_types("Voice")]
chaos_channel: serenity::Channel, // Channel to move chaos team members into
#[description = "Team size"] #[description = "Team size"]
#[min = 1] size: u8, // Number of members on each team #[min = 1]
size: u8, // Number of members on each team
) -> Result<(), Error> { ) -> Result<(), Error> {
let mut voice_states: HashMap<UserId, VoiceState> = ctx.guild().unwrap().voice_states; // Get hashmap of users' voice states within the guild let mut voice_states: HashMap<UserId, VoiceState> = ctx.guild().unwrap().voice_states; // Get hashmap of users' voice states within the guild
voice_states.retain(|_, state: &mut VoiceState| state.channel_id == Some(order_channel.id())); // Drop users not active in requested voice channel from hashmap voice_states.retain(|_, state: &mut VoiceState| state.channel_id == Some(order_channel.id())); // Drop users not active in requested voice channel from hashmap
if voice_states.keys().len() < size as usize * 2 { // Make sure there are enough members in the voice channel if voice_states.keys().len() < size as usize * 2 {
ctx.send(|f| f // Make sure there are enough members in the voice channel
.embed(|f| f ctx.send(|f| {
.title(format!("Custom {}v{} Teams", size, size)) f.embed(|f| {
.description("You don't have enough friends for that, idiot.") f.title(format!("Custom {size}v{size} Teams"))
.color(serenity::Colour::RED) .description("There are not enough members in the call!")
)).await?; // Insult the user for not having enough friends .color(serenity::Colour::RED)
})
})
.await?;
return Ok(()); // Break out early if there are not enough members return Ok(()); // Break out early if there are not enough members
} }
let uuid_team: u64 = ctx.id(); // Grab context ID for action row let uuid_team: u64 = ctx.id(); // Grab context ID for action row
let users: Vec<&UserId> = Vec::from_iter(voice_states.keys()); // Get vec of PIDs let users: Vec<String> = Vec::from_iter(voice_states.keys().map(|u| u.to_string())); // Get vec of PIDs
let players: Vec<&&UserId> = users.choose_multiple( let players: Vec<&String> = users
&mut rand::thread_rng(), size as usize * 2).collect(); // Pick players randomly into slice .choose_multiple(&mut rand::thread_rng(), size as usize * 2)
.collect(); // Pick players randomly into slice
let (order, chaos) = players.split_at(players.len() / 2); // Split slice into two teams let (order, chaos) = players.split_at(players.len() / 2); // Split slice into two teams
ctx.send(|f| f ctx.send(|f| {
.embed(|f| f f.embed(|f| {
.title(format!("Custom {}v{} Teams", size, size)) f.title(format!("Custom {size}v{size} Teams"))
.description("VER") .description("Click the button below to move the Chaos players.")
.field("Order", team_to_ping(order), false) .field("Order", team_to_ping(order), false)
.field("Chaos", team_to_ping(chaos), false) .field("Chaos", team_to_ping(chaos), false)
.color(serenity::Colour::DARK_GREEN) .color(serenity::Colour::DARK_GREEN)
).components(|c| c // Create an action row with button })
.create_action_row(|a| a .components(|c| {
.create_button(|b| b c.create_action_row(|a| {
.style(serenity::ButtonStyle::Primary) // Create an action row with button
.label("Swap Channels") a.create_button(
.custom_id(uuid_team) // Use the context ID as button ID |b| {
) b.style(serenity::ButtonStyle::Primary)
) .label("Swap Channels")
)).await?; // Send embed with team picks .custom_id(uuid_team)
}, // Use the context ID as button ID
)
})
})
})
.await?; // Send embed with team picks
while let Some(mci) = serenity::CollectComponentInteraction::new(ctx) // Handle the interaction while let Some(mci) = serenity::CollectComponentInteraction::new(ctx) // Handle the interaction
.await { .await
let guild: Guild = ctx.guild().unwrap(); {
let guild: Guild = ctx.guild().unwrap(); // Grab guild from context
for user in chaos { for user in chaos {
let member: Member = guild.member(ctx, UserId(*user.as_u64())).await?; // Get the member in the correct guild let member: Member = guild.member(ctx, UserId(user.parse()?)).await?; // Get the member in the correct guild
member.move_to_voice_channel(ctx, chaos_channel.id()).await?; // Move the member to the correct voice channel member
.move_to_voice_channel(ctx, chaos_channel.id())
.await?; // Move the member to the correct voice channel
} }
mci.create_interaction_response(ctx, |ir| { // Update embed mci.create_interaction_response(ctx, |ir| {
ir.kind(serenity::InteractionResponseType::UpdateMessage).interaction_response_data(|f| f // Edit embed
.embed(|f| f ir.kind(serenity::InteractionResponseType::UpdateMessage)
.title(format!("Custom {}v{} Teams", size, size)) .interaction_response_data(|f| {
.description("VVGO VVW VVX") f.embed(|f| {
.field("Order", team_to_ping(order), false) f.title(format!("Custom {size}v{size} Teams"))
.field("Chaos", team_to_ping(chaos), false) .description("Good luck! Have fun!")
.color(serenity::Colour::DARK_GREEN) .field("Order", team_to_ping(order), false)
).components(|c| c // Create an action row with button .field("Chaos", team_to_ping(chaos), false)
.create_action_row(|a| a .color(serenity::Colour::DARK_GREEN)
.create_button(|b| b })
.disabled(true) // with disabled button .components(|c| {
.style(serenity::ButtonStyle::Primary) c.create_action_row(|a| {
.label("Quit Sibelius") // and new text // Create an action row with button
.custom_id(uuid_team) // Use the context ID as button ID a.create_button(
) |b| {
) b
)) .disabled(true) // with disabled button
}).await?; .style(serenity::ButtonStyle::Primary)
.label("Quit Sibelius") // and new text
}, // Use the context ID as button ID
)
})
})
})
})
.await?;
} }
Ok(()) Ok(())
} }

View file

@ -1,8 +1,8 @@
mod commands;
use poise::serenity_prelude as serenity; use poise::serenity_prelude as serenity;
struct Data {} mod commands;
pub struct Data {}
type Error = Box<dyn std::error::Error + Send + Sync>; type Error = Box<dyn std::error::Error + Send + Sync>;
type Context<'a> = poise::Context<'a, Data, Error>; type Context<'a> = poise::Context<'a, Data, Error>;
@ -12,25 +12,23 @@ async fn main() {
let framework = poise::Framework::builder() let framework = poise::Framework::builder()
.options(poise::FrameworkOptions { .options(poise::FrameworkOptions {
commands: vec![ commands: vec![
commands::slur::slur(), commands::ping::ping(),
commands::team::team(), commands::team::team(),
commands::random::random(),
commands::register::register(),
commands::profile::profile(),
commands::pog::pog(),
], // IntelliJ doesn't like this, but it's fine. ], // IntelliJ doesn't like this, but it's fine.
..Default::default() ..Default::default()
}) })
.token(std::env::var("DISCORD_TOKEN") .token(std::env::var("DISCORD_TOKEN").expect("Missing DISCORD_TOKEN"))
.expect("Missing DISCORD_TOKEN"))
.intents(serenity::GatewayIntents::non_privileged()) // Set intents for Discord dev portal .intents(serenity::GatewayIntents::non_privileged()) // Set intents for Discord dev portal
.setup(|ctx, _ready, framework| { .setup(|ctx, _ready, framework| {
Box::pin(async move { Box::pin(async move {
poise::builtins::register_in_guild( poise::builtins::register_globally(ctx, &framework.options().commands).await?; // Update slash commands
ctx, ctx.set_activity(serenity::Activity::playing("SMITE")).await;
&framework.options().commands,
serenity::GuildId(std::env::var("GUILD_ID")
.expect("Missing GUILD_ID") // Get GID from env and parse
.parse::<u64>().unwrap())).await?; // Update slash commands in GID
Ok(Data {}) Ok(Data {})
}) })
}); });
framework.run().await.unwrap(); framework.run().await.unwrap();
} }