mirror of
https://github.com/supleed2/nanobot.git
synced 2024-12-22 06:05:50 +00:00
Update to Poise v0.6
This commit is contained in:
parent
54a93953bf
commit
a44f0ede7e
533
Cargo.lock
generated
533
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
18
Cargo.toml
18
Cargo.toml
|
@ -11,21 +11,21 @@ publish = false
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.75"
|
||||
axum = "0.7.2"
|
||||
anyhow = "1.0.79"
|
||||
axum = "0.7.4"
|
||||
indoc = "2.0.4"
|
||||
poise = "0.5.7"
|
||||
reqwest = { version = "0.11.22", features = ["json"] }
|
||||
serde = { version = "1.0.193", features = ["derive"] }
|
||||
shuttle-runtime = { version = "0.35.0", default-features = false }
|
||||
shuttle-secrets = "0.35.0"
|
||||
shuttle-shared-db = { version = "0.35.0", features = ["postgres"] }
|
||||
poise = "0.6.1"
|
||||
reqwest = { version = "0.11.23", features = ["json"] }
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
shuttle-runtime = { version = "0.36.0", default-features = false }
|
||||
shuttle-secrets = "0.36.0"
|
||||
shuttle-shared-db = { version = "0.36.0", features = ["postgres"] }
|
||||
sqlx = { version = "0.7.3", features = [
|
||||
"macros",
|
||||
"postgres",
|
||||
"runtime-tokio-native-tls",
|
||||
] }
|
||||
tokio = "1.34.0"
|
||||
tokio = "1.35.1"
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["time"] }
|
||||
url = "2.5.0"
|
||||
|
|
|
@ -97,7 +97,7 @@ pub(crate) async fn refresh_non_members(ctx: ACtx<'_>) -> Result<(), Error> {
|
|||
ctx.defer().await?;
|
||||
let mut members = ctx.data().server.members_iter(ctx.http()).boxed();
|
||||
let mut cnt = 0;
|
||||
while let Some(Ok(mut m)) = members.next().await {
|
||||
while let Some(Ok(m)) = members.next().await {
|
||||
if m.roles.is_empty() {
|
||||
m.add_role(ctx.http(), ctx.data().non_member).await?;
|
||||
cnt += 1;
|
||||
|
@ -122,7 +122,7 @@ pub(crate) async fn set_members_non_fresher(ctx: ACtx<'_>) -> Result<(), Error>
|
|||
ctx.say(format!("{updated} updated to non-fresher, removing roles"))
|
||||
.await?;
|
||||
let mut members = ctx.data().server.members_iter(ctx.http()).boxed();
|
||||
while let Some(Ok(mut m)) = members.next().await {
|
||||
while let Some(Ok(m)) = members.next().await {
|
||||
let _ = m.remove_role(ctx.http(), ctx.data().fresher).await;
|
||||
}
|
||||
ctx.say("Roles removed").await?;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use crate::{db, ACtx, Error, Gaijin};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::Modal;
|
||||
use poise::{
|
||||
serenity_prelude::{self as serenity, CreateAttachment, CreateMessage},
|
||||
Modal,
|
||||
};
|
||||
use std::fmt::Write;
|
||||
|
||||
/// Get the number of entries in the gaijin table
|
||||
|
@ -57,9 +59,11 @@ pub(crate) async fn get_all_gaijin(ctx: ACtx<'_>) -> Result<(), Error> {
|
|||
ctx.say("Sending gaijin db data in followup message")
|
||||
.await?;
|
||||
ctx.channel_id()
|
||||
.send_files(&ctx.http(), vec!["gaijin.rs"], |cm| {
|
||||
cm.content("File: gaijin db")
|
||||
})
|
||||
.send_files(
|
||||
&ctx.http(),
|
||||
vec![CreateAttachment::path("gaijin.rs").await?],
|
||||
CreateMessage::new().content("File: gaijin db"),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{db, ACtx, Error, ManualMember};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{self as serenity, CreateAttachment, CreateMessage};
|
||||
use poise::Modal;
|
||||
|
||||
/// Get the number of manual members in the manual table
|
||||
|
@ -49,9 +49,11 @@ pub(crate) async fn get_all_manual(ctx: ACtx<'_>) -> Result<(), Error> {
|
|||
ctx.say("Sending manual db data in followup message")
|
||||
.await?;
|
||||
ctx.channel_id()
|
||||
.send_files(&ctx.http(), vec!["manual.rs"], |cm| {
|
||||
cm.content("File: manual db")
|
||||
})
|
||||
.send_files(
|
||||
&ctx.http(),
|
||||
vec![CreateAttachment::path("manual.rs").await?],
|
||||
CreateMessage::new().content("File: manual db"),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{db, ACtx, Error, Member};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{self as serenity, CreateAttachment, CreateMessage};
|
||||
use poise::Modal;
|
||||
|
||||
/// Get the number of members in the members table
|
||||
|
@ -57,9 +57,11 @@ pub(crate) async fn get_all_members(ctx: ACtx<'_>) -> Result<(), Error> {
|
|||
ctx.say("Sending members db data in followup message")
|
||||
.await?;
|
||||
ctx.channel_id()
|
||||
.send_files(&ctx.http(), vec!["members.rs"], |cm| {
|
||||
cm.content("File: members db")
|
||||
})
|
||||
.send_files(
|
||||
&ctx.http(),
|
||||
vec![CreateAttachment::path("members.rs").await?],
|
||||
CreateMessage::new().content("File: members db"),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{ACtx, Data, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{self as serenity, CreateActionRow, CreateButton, CreateMessage};
|
||||
use poise::Modal;
|
||||
|
||||
pub(crate) mod members;
|
||||
|
@ -67,24 +67,21 @@ pub(crate) async fn setup(
|
|||
.await?;
|
||||
let emoji = emoji.unwrap_or_default().chars().next().unwrap_or('🚀');
|
||||
channel
|
||||
.send_message(ctx.http(), |m| {
|
||||
m.content(message).components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji('📖')
|
||||
.label("More info")
|
||||
.custom_id("info")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji(emoji)
|
||||
.label(text.unwrap_or("Begin".to_string()))
|
||||
.custom_id("start")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.send_message(
|
||||
ctx.http(),
|
||||
CreateMessage::new()
|
||||
.content(message)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("info")
|
||||
.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji('📖')
|
||||
.label("More info"),
|
||||
CreateButton::new("start")
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji(emoji)
|
||||
.label(text.unwrap_or("Begin".to_string())),
|
||||
])]),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
ctx.say("Modal timed out, try again...").await?;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{db, ACtx, Error, PendingMember};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{self as serenity, CreateAttachment, CreateMessage};
|
||||
use poise::Modal;
|
||||
|
||||
/// Get the number of pending members in the pending table
|
||||
|
@ -49,9 +49,11 @@ pub(crate) async fn get_all_pending(ctx: ACtx<'_>) -> Result<(), Error> {
|
|||
ctx.say("Sending pending db data in followup message")
|
||||
.await?;
|
||||
ctx.channel_id()
|
||||
.send_files(&ctx.http(), vec!["pending.rs"], |cm| {
|
||||
cm.content("File: pending db")
|
||||
})
|
||||
.send_files(
|
||||
&ctx.http(),
|
||||
vec![CreateAttachment::path("pending.rs").await?],
|
||||
CreateMessage::new().content("File: pending db"),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Err(e) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{db, ACtx, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::{serenity_prelude as serenity, CreateReply};
|
||||
use std::fmt::Write;
|
||||
|
||||
/// Unreachable, used to create whois command folder
|
||||
|
@ -19,14 +19,19 @@ pub(crate) async fn whois_by_id(ctx: ACtx<'_>, id: serenity::Member) -> Result<(
|
|||
tracing::info!("{} {}", ctx.author().name, id.user.name);
|
||||
match db::get_member_by_id(&ctx.data().db, id.user.id.into()).await? {
|
||||
Some(m) => {
|
||||
ctx.send(|c| c.content(format!("{id}: {}", m.nickname)).ephemeral(true))
|
||||
.await?
|
||||
ctx.send(
|
||||
CreateReply::default()
|
||||
.content(format!("{id}: {}", m.nickname))
|
||||
.ephemeral(true),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
None => {
|
||||
ctx.send(|c| {
|
||||
c.content(format!("No member entry found for {id}"))
|
||||
.ephemeral(true)
|
||||
})
|
||||
ctx.send(
|
||||
CreateReply::default()
|
||||
.content(format!("No member entry found for {id}"))
|
||||
.ephemeral(true),
|
||||
)
|
||||
.await?
|
||||
}
|
||||
};
|
||||
|
@ -39,29 +44,29 @@ pub(crate) async fn whois_by_id(ctx: ACtx<'_>, id: serenity::Member) -> Result<(
|
|||
pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result<(), Error> {
|
||||
tracing::info!("{} {nickname}", ctx.author().name);
|
||||
if let Some(m) = db::get_member_by_nickname(&ctx.data().db, &nickname).await? {
|
||||
ctx.send(|c| {
|
||||
c.content(format!("{nickname}: <@{}>", m.discord_id))
|
||||
.ephemeral(true)
|
||||
})
|
||||
ctx.send(
|
||||
CreateReply::default()
|
||||
.content(format!("{nickname}: <@{}>", m.discord_id))
|
||||
.ephemeral(true),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
let members = db::get_member_by_nickname_fuzzy(&ctx.data().db, &nickname, 3).await?;
|
||||
if members.is_empty() {
|
||||
ctx.send(|c| {
|
||||
c.content(format!("No member entry found for nickname {nickname}"))
|
||||
.ephemeral(true)
|
||||
})
|
||||
ctx.send(
|
||||
CreateReply::default()
|
||||
.content(format!("No member entry found for nickname {nickname}"))
|
||||
.ephemeral(true),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
ctx.send(|c| {
|
||||
c.ephemeral(true).content(format!(
|
||||
"Possible matches for {nickname}: {}",
|
||||
members.iter().fold(String::new(), |mut s, g| {
|
||||
write!(s, " <@{}>", g.discord_id).expect("String write! is infallible");
|
||||
s
|
||||
})
|
||||
))
|
||||
})
|
||||
ctx.send(CreateReply::default().ephemeral(true).content(format!(
|
||||
"Possible matches for {nickname}: {}",
|
||||
members.iter().fold(String::new(), |mut s, g| {
|
||||
write!(s, " <@{}>", g.discord_id).expect("String write! is infallible");
|
||||
s
|
||||
})
|
||||
)))
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
@ -74,29 +79,29 @@ pub(crate) async fn whois_by_nickname(ctx: ACtx<'_>, nickname: String) -> Result
|
|||
pub(crate) async fn whois_by_realname(ctx: ACtx<'_>, realname: String) -> Result<(), Error> {
|
||||
tracing::info!("{} {realname}", ctx.author().name);
|
||||
if let Some(m) = db::get_member_by_realname(&ctx.data().db, &realname).await? {
|
||||
ctx.send(|c| {
|
||||
c.content(format!("{realname}: <@{}>", m.discord_id))
|
||||
.ephemeral(true)
|
||||
})
|
||||
ctx.send(
|
||||
CreateReply::default()
|
||||
.content(format!("{realname}: <@{}>", m.discord_id))
|
||||
.ephemeral(true),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
let members = db::get_member_by_realname_fuzzy(&ctx.data().db, &realname, 3).await?;
|
||||
if members.is_empty() {
|
||||
ctx.send(|c| {
|
||||
c.content(format!("No member entry found for realname {realname}"))
|
||||
.ephemeral(true)
|
||||
})
|
||||
ctx.send(
|
||||
CreateReply::default()
|
||||
.content(format!("No member entry found for realname {realname}"))
|
||||
.ephemeral(true),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
ctx.send(|c| {
|
||||
c.ephemeral(true).content(format!(
|
||||
"Possible matches for {realname}: {}",
|
||||
members.iter().fold(String::new(), |mut s, g| {
|
||||
write!(s, " <@{}>", g.discord_id).expect("String write! is infallible");
|
||||
s
|
||||
})
|
||||
))
|
||||
})
|
||||
ctx.send(CreateReply::default().ephemeral(true).content(format!(
|
||||
"Possible matches for {realname}: {}",
|
||||
members.iter().fold(String::new(), |mut s, g| {
|
||||
write!(s, " <@{}>", g.discord_id).expect("String write! is infallible");
|
||||
s
|
||||
})
|
||||
)))
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
|
|
121
src/main.rs
121
src/main.rs
|
@ -1,6 +1,6 @@
|
|||
#![warn(clippy::pedantic)]
|
||||
use anyhow::Context as _;
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{self as serenity, FullEvent};
|
||||
|
||||
mod cmds;
|
||||
mod db;
|
||||
|
@ -59,14 +59,24 @@ struct Gaijin {
|
|||
university: String,
|
||||
}
|
||||
|
||||
macro_rules! secret {
|
||||
($s: literal, $ss: ident) => {
|
||||
$ss.get($s).context(format!("{} not found", $s))?
|
||||
};
|
||||
($s: literal, $ss: ident, $t: ty) => {
|
||||
secret!($s, $ss)
|
||||
.parse::<$t>()
|
||||
.context(format!("{} not valid {}", $s, stringify!($t)))?
|
||||
};
|
||||
}
|
||||
|
||||
#[shuttle_runtime::main]
|
||||
async fn poise(
|
||||
async fn nanobot(
|
||||
#[shuttle_secrets::Secrets] secret_store: shuttle_secrets::SecretStore,
|
||||
#[shuttle_shared_db::Postgres] pool: sqlx::PgPool,
|
||||
) -> Result<service::NanoBot, shuttle_runtime::Error> {
|
||||
// Set Up Tracing Subscriber
|
||||
init_tracing_subscriber();
|
||||
tracing::info!("Tracing Subscriber Set Up");
|
||||
|
||||
// Run SQLx Migrations
|
||||
sqlx::migrate!()
|
||||
|
@ -74,58 +84,8 @@ async fn poise(
|
|||
.await
|
||||
.map_err(shuttle_runtime::CustomError::new)?;
|
||||
|
||||
// Load secrets
|
||||
let au_ch_id = secret_store
|
||||
.get("AU_CHANNEL_ID")
|
||||
.expect("AU_CHANNEL_ID not found")
|
||||
.parse()
|
||||
.expect("AU_CHANNEL_ID not valid u64");
|
||||
let ea_key = secret_store
|
||||
.get("EA_API_KEY")
|
||||
.expect("EA_API_KEY not found");
|
||||
let ea_url = secret_store
|
||||
.get("EA_API_URL")
|
||||
.expect("EA_API_URL not found");
|
||||
let token = secret_store
|
||||
.get("DISCORD_TOKEN")
|
||||
.expect("DISCORD_TOKEN not found");
|
||||
let fresher = secret_store
|
||||
.get("FRESHER_ID")
|
||||
.expect("FRESHER_ID not found")
|
||||
.parse()
|
||||
.expect("FRESHER_ID not valid u64");
|
||||
let gaijin = secret_store
|
||||
.get("GAIJIN_ID")
|
||||
.expect("GAIJIN_ID not found")
|
||||
.parse()
|
||||
.expect("GAIJIN_ID not valid u64");
|
||||
let gn_ch_id = secret_store
|
||||
.get("GN_CHANNEL_ID")
|
||||
.expect("GN_CHANNEL_ID not found")
|
||||
.parse()
|
||||
.expect("GN_CHANNEL_ID not valid u64");
|
||||
let member = secret_store
|
||||
.get("MEMBER_ID")
|
||||
.expect("MEMBER_ID not found")
|
||||
.parse()
|
||||
.expect("MEMBER_ID not valid u64");
|
||||
let non_member = secret_store
|
||||
.get("NON_MEMBER_ID")
|
||||
.expect("NON_MEMBER_ID not found")
|
||||
.parse()
|
||||
.expect("NON_MEMBER_ID not valid u64");
|
||||
let old_member = secret_store
|
||||
.get("OLD_MEMBER_ID")
|
||||
.expect("OLD_MEMBER_ID not found")
|
||||
.parse()
|
||||
.expect("OLD_MEMBER_ID not valid u64");
|
||||
let server = secret_store
|
||||
.get("SERVER_ID")
|
||||
.expect("SERVER_ID not found")
|
||||
.parse::<u64>()
|
||||
.expect("SERVER_ID not valid u64")
|
||||
.into();
|
||||
tracing::info!("Secrets loaded");
|
||||
// Load token
|
||||
let token = secret!("DISCORD_TOKEN", secret_store);
|
||||
|
||||
// Build Axum Router
|
||||
let router = axum::Router::new()
|
||||
|
@ -142,33 +102,40 @@ async fn poise(
|
|||
);
|
||||
|
||||
// Build Poise Instance
|
||||
let discord = poise::Framework::builder()
|
||||
let framework = poise::Framework::builder()
|
||||
.options(poise::FrameworkOptions {
|
||||
commands: all_commands(),
|
||||
event_handler: { |c, e, f, d| Box::pin(event_handler(c, e, f, d)) },
|
||||
..Default::default()
|
||||
})
|
||||
.token(token)
|
||||
.intents(serenity::GatewayIntents::non_privileged())
|
||||
.setup(move |ctx, _, _| {
|
||||
Box::pin(async move {
|
||||
ctx.set_activity(serenity::Activity::competing("autoverification"))
|
||||
.await;
|
||||
ctx.set_activity(Some(serenity::ActivityData::custom(
|
||||
"Verifying members since 2023",
|
||||
)));
|
||||
Ok(Data {
|
||||
au_ch_id,
|
||||
au_ch_id: secret!("AU_CHANNEL_ID", secret_store, _),
|
||||
db: pool,
|
||||
ea_key,
|
||||
ea_url,
|
||||
fresher,
|
||||
gaijin,
|
||||
gn_ch_id,
|
||||
member,
|
||||
non_member,
|
||||
old_member,
|
||||
server,
|
||||
ea_key: secret!("EA_API_KEY", secret_store),
|
||||
ea_url: secret!("EA_API_URL", secret_store),
|
||||
fresher: secret!("FRESHER_ID", secret_store, _),
|
||||
gaijin: secret!("GAIJIN_ID", secret_store, _),
|
||||
gn_ch_id: secret!("GN_CHANNEL_ID", secret_store, _),
|
||||
member: secret!("MEMBER_ID", secret_store, _),
|
||||
non_member: secret!("NON_MEMBER_ID", secret_store, _),
|
||||
old_member: secret!("OLD_MEMBER_ID", secret_store, _),
|
||||
server: secret!("SERVER_ID", secret_store, _),
|
||||
})
|
||||
})
|
||||
});
|
||||
})
|
||||
.build();
|
||||
|
||||
// Build Discord struct
|
||||
let discord = service::Discord {
|
||||
framework,
|
||||
token,
|
||||
intents: serenity::GatewayIntents::non_privileged(),
|
||||
};
|
||||
|
||||
// Return NanoBot
|
||||
Ok(service::NanoBot { discord, router })
|
||||
|
@ -176,16 +143,16 @@ async fn poise(
|
|||
|
||||
async fn event_handler(
|
||||
ctx: &serenity::Context,
|
||||
event: &poise::Event<'_>,
|
||||
event: &FullEvent,
|
||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||
data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
match event {
|
||||
poise::Event::GuildMemberAddition { new_member } => {
|
||||
FullEvent::GuildMemberAddition { new_member } => {
|
||||
tracing::info!("Member joined: {}", new_member.user.name);
|
||||
}
|
||||
poise::Event::InteractionCreate {
|
||||
interaction: serenity::Interaction::MessageComponent(m),
|
||||
FullEvent::InteractionCreate {
|
||||
interaction: serenity::Interaction::Component(m),
|
||||
} => {
|
||||
tracing::info!("Interaction: {} by {}", m.data.custom_id, m.user.name);
|
||||
match m.data.custom_id.as_str() {
|
||||
|
@ -214,8 +181,8 @@ async fn event_handler(
|
|||
}
|
||||
}
|
||||
}
|
||||
poise::Event::InteractionCreate {
|
||||
interaction: serenity::Interaction::ModalSubmit(m),
|
||||
FullEvent::InteractionCreate {
|
||||
interaction: serenity::Interaction::Modal(m),
|
||||
} => {
|
||||
tracing::info!("Modal submit: {} by {}", m.data.custom_id, m.user.name);
|
||||
match m.data.custom_id.as_str() {
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
use crate::{Data, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
|
||||
pub(crate) struct NanoBot {
|
||||
pub discord: poise::FrameworkBuilder<Data, Error>,
|
||||
pub discord: Discord,
|
||||
pub router: axum::Router,
|
||||
}
|
||||
|
||||
pub(crate) struct Discord {
|
||||
pub framework: poise::Framework<Data, Error>,
|
||||
pub token: String,
|
||||
pub intents: serenity::GatewayIntents,
|
||||
}
|
||||
|
||||
#[shuttle_runtime::async_trait]
|
||||
impl shuttle_runtime::Service for NanoBot {
|
||||
async fn bind(mut self, addr: std::net::SocketAddr) -> Result<(), shuttle_runtime::Error> {
|
||||
|
@ -18,8 +25,13 @@ impl shuttle_runtime::Service for NanoBot {
|
|||
)
|
||||
.into_future();
|
||||
|
||||
let mut client = serenity::ClientBuilder::new(self.discord.token, self.discord.intents)
|
||||
.framework(self.discord.framework)
|
||||
.await
|
||||
.map_err(shuttle_runtime::CustomError::new)?;
|
||||
|
||||
tokio::select! {
|
||||
_ = self.discord.run_autosharded() => {},
|
||||
_ = client.start_autosharded() => {},
|
||||
_ = serve => {},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{Data, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{
|
||||
self as serenity, CreateActionRow, CreateButton, CreateEmbed, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, CreateMessage,
|
||||
};
|
||||
use poise::Modal;
|
||||
|
||||
const LOGIN_INTRO: &str = indoc::indoc! {"
|
||||
|
@ -14,34 +17,28 @@ const LOGIN_INTRO: &str = indoc::indoc! {"
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn login_1(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(LOGIN_INTRO).components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙')
|
||||
.custom_id("restart")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Link)
|
||||
.emoji('🚀')
|
||||
.label("Login Here")
|
||||
.url(format!("https://icas.8bitsqu.id/verify?id={}", m.user.id.0))
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji('👉')
|
||||
.label("Then continue")
|
||||
.custom_id("login_2")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
let verify_url = format!("https://icas.8bitsqu.id/verify?id={}", m.user.id.get());
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(LOGIN_INTRO)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("restart")
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙'),
|
||||
CreateButton::new_link(verify_url)
|
||||
.emoji('🚀')
|
||||
.label("Login Here"),
|
||||
CreateButton::new("login_2")
|
||||
.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji('👉')
|
||||
.label("Then continue"),
|
||||
])]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -55,52 +52,50 @@ const LOGIN_FORM: &str = indoc::indoc! {"
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn login_2(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
match crate::db::get_pending_by_id(&data.db, m.user.id.into()).await {
|
||||
Err(e) => {
|
||||
tracing::error!("{e}");
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(None) => {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Error, have you completed login verification via the link?")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Error, have you completed login verification via the link?")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(Some(_)) => {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(LOGIN_FORM).components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙')
|
||||
.custom_id("login_1")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('📑')
|
||||
.label("Form")
|
||||
.custom_id("login_3")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(LOGIN_FORM)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("login_1")
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙'),
|
||||
CreateButton::new("login_3")
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('📑')
|
||||
.label("Form"),
|
||||
])]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
|
@ -110,34 +105,28 @@ pub(crate) async fn login_2(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn login_3(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Are you a fresher?").components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙')
|
||||
.custom_id("login_2")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Fresher")
|
||||
.custom_id("login_4f")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('❌')
|
||||
.label("Non-fresher")
|
||||
.custom_id("login_4n")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Are you a fresher?")
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("login_2")
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙'),
|
||||
CreateButton::new("login_4f")
|
||||
.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Fresher"),
|
||||
CreateButton::new("login_4n")
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('❌')
|
||||
.label("Non-fresher"),
|
||||
])]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -145,30 +134,25 @@ pub(crate) async fn login_3(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn login_4(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("And a preferred name for Nano whois commands")
|
||||
.components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙')
|
||||
.custom_id("login_3")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('💬')
|
||||
.label("Name")
|
||||
.custom_id(if fresher { "login_5f" } else { "login_5n" })
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("And a preferred name for Nano whois commands")
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("login_3")
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙'),
|
||||
CreateButton::new(if fresher { "login_5f" } else { "login_5n" })
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('💬')
|
||||
.label("Name"),
|
||||
])]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -184,20 +168,20 @@ struct Nickname {
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn login_5(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
*i = Nickname::create(
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
Nickname::create(
|
||||
None,
|
||||
if fresher {
|
||||
"login_6f".to_string()
|
||||
} else {
|
||||
"login_6n".to_string()
|
||||
},
|
||||
);
|
||||
i
|
||||
})
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -205,7 +189,7 @@ pub(crate) async fn login_5(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn login_6(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::ModalSubmitInteraction,
|
||||
m: &serenity::ModalInteraction,
|
||||
data: &Data,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -234,34 +218,38 @@ pub(crate) async fn login_6(
|
|||
if fresher {
|
||||
crate::verify::apply_role(ctx, &mut mm, data.fresher).await?;
|
||||
}
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(if fresher {
|
||||
"Congratulations, you have completed verification and now \
|
||||
have access to the ICAS Discord and freshers thread"
|
||||
} else {
|
||||
"Congratulations, you have completed verification and now \
|
||||
have access to the ICAS Discord"
|
||||
})
|
||||
.components(|c| c)
|
||||
})
|
||||
})
|
||||
let msg = if fresher {
|
||||
"Congratulations, you have completed verification and now \
|
||||
have access to the ICAS Discord and freshers thread"
|
||||
} else {
|
||||
"Congratulations, you have completed verification and now \
|
||||
have access to the ICAS Discord"
|
||||
};
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(msg)
|
||||
.components(vec![]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
data.au_ch_id
|
||||
.send_message(&ctx.http, |cm| {
|
||||
cm.add_embed(|e| {
|
||||
e.thumbnail(
|
||||
m.user.avatar_url().unwrap_or(super::AVATAR.to_string()),
|
||||
)
|
||||
.title("Member verified via login")
|
||||
.description(&m.user)
|
||||
.field("Fresher", fresher, true)
|
||||
.field("Nickname", nickname, true)
|
||||
.field("Name", p.realname, true)
|
||||
.timestamp(serenity::Timestamp::now())
|
||||
})
|
||||
})
|
||||
.send_message(
|
||||
&ctx.http,
|
||||
CreateMessage::new().embed(
|
||||
CreateEmbed::new()
|
||||
.thumbnail(
|
||||
m.user.avatar_url().unwrap_or(super::AVATAR.to_string()),
|
||||
)
|
||||
.title("Member verified via login")
|
||||
.description(m.user.to_string())
|
||||
.field("Fresher", fresher.to_string(), true)
|
||||
.field("Nickname", nickname, true)
|
||||
.field("Name", p.realname, true)
|
||||
.timestamp(serenity::Timestamp::now()),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
let _ = mm.remove_role(&ctx.http, data.non_member).await;
|
||||
if mm.roles.contains(&data.old_member) {
|
||||
|
@ -273,13 +261,14 @@ pub(crate) async fn login_6(
|
|||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error: {e}");
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{Data, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{
|
||||
self as serenity, CreateActionRow, CreateButton, CreateEmbed, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, CreateMessage,
|
||||
};
|
||||
use poise::Modal;
|
||||
|
||||
const MANUAL_INTRO: &str = indoc::indoc! {"
|
||||
|
@ -19,34 +22,28 @@ const MANUAL_INTRO: &str = indoc::indoc! {"
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn manual_1(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(MANUAL_INTRO).components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙')
|
||||
.custom_id("restart")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Fresher")
|
||||
.custom_id("manual_2f")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('❌')
|
||||
.label("Non-fresher")
|
||||
.custom_id("manual_2n")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(MANUAL_INTRO)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("restart")
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙'),
|
||||
CreateButton::new("manual_2f")
|
||||
.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Fresher"),
|
||||
CreateButton::new("manual_2n")
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('❌')
|
||||
.label("Non-fresher"),
|
||||
])]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -72,24 +69,24 @@ struct Manual {
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn manual_2(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
data: &Data,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
// Delete from manual if exists
|
||||
let _ = crate::db::delete_manual_by_id(&data.db, m.user.id.into()).await;
|
||||
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
*i = Manual::create(
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
Manual::create(
|
||||
None,
|
||||
if fresher {
|
||||
"manual_3f".to_string()
|
||||
} else {
|
||||
"manual_3n".to_string()
|
||||
},
|
||||
);
|
||||
i
|
||||
})
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -97,7 +94,7 @@ pub(crate) async fn manual_2(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn manual_3(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::ModalSubmitInteraction,
|
||||
m: &serenity::ModalInteraction,
|
||||
data: &Data,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -109,13 +106,14 @@ pub(crate) async fn manual_3(
|
|||
nickname,
|
||||
}) => {
|
||||
if ::url::Url::parse(&url).is_err() {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("The url provided is invalid, please try again")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("The url provided is invalid, please try again")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -125,36 +123,33 @@ pub(crate) async fn manual_3(
|
|||
|
||||
let prompt_sent = data
|
||||
.au_ch_id
|
||||
.send_message(&ctx.http, |cm| {
|
||||
cm.add_embed(|e| {
|
||||
e.title("New verification request from")
|
||||
.thumbnail(m.user.avatar_url().unwrap_or(super::AVATAR.to_string()))
|
||||
.description(&m.user)
|
||||
.field("Real Name (To be checked)", &realname, true)
|
||||
.field("Imperial Shortcode (To be checked", &shortcode, true)
|
||||
.field("Fresher (To be checked)", fresher, true)
|
||||
.field("Nickname (Nano whois commands)", &nickname, true)
|
||||
.field("Verification URL (Also displayed below)", &url, true)
|
||||
.image(&url)
|
||||
.timestamp(serenity::Timestamp::now())
|
||||
})
|
||||
.components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Accept")
|
||||
.custom_id(format!("verify-y-{}", m.user.id))
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('❎')
|
||||
.label("Deny")
|
||||
.custom_id(format!("verify-n-{}", m.user.id))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
.send_message(
|
||||
&ctx.http,
|
||||
CreateMessage::new()
|
||||
.embed(
|
||||
CreateEmbed::new()
|
||||
.title("New verification request from")
|
||||
.thumbnail(m.user.avatar_url().unwrap_or(super::AVATAR.to_string()))
|
||||
.description(m.user.to_string())
|
||||
.field("Real Name (To be checked)", &realname, true)
|
||||
.field("Imperial Shortcode (To be checked", &shortcode, true)
|
||||
.field("Fresher (To be checked)", fresher.to_string(), true)
|
||||
.field("Nickname (Nano whois commands)", &nickname, true)
|
||||
.field("Verification URL (Also displayed below)", &url, true)
|
||||
.image(&url)
|
||||
.timestamp(serenity::Timestamp::now()),
|
||||
)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new(format!("verify-y-{}", m.user.id))
|
||||
.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Accept"),
|
||||
CreateButton::new(format!("verify-n-{}", m.user.id))
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('❎')
|
||||
.label("Deny"),
|
||||
])]),
|
||||
)
|
||||
.await
|
||||
.is_ok();
|
||||
|
||||
|
@ -181,22 +176,27 @@ pub(crate) async fn manual_3(
|
|||
"Sending your verification request failed, please try again."
|
||||
};
|
||||
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| d.content(msg).components(|c| c))
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(msg)
|
||||
.components(vec![]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
};
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -204,7 +204,7 @@ pub(crate) async fn manual_3(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn manual_4(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
data: &Data,
|
||||
id: &str,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -214,7 +214,7 @@ pub(crate) async fn manual_4(
|
|||
.skip(9)
|
||||
.collect::<String>()
|
||||
.parse::<u64>()
|
||||
.map(serenity::UserId)
|
||||
.map(serenity::UserId::new)
|
||||
.unwrap_or_default()
|
||||
.to_user(ctx)
|
||||
.await
|
||||
|
@ -239,20 +239,25 @@ pub(crate) async fn manual_4(
|
|||
if fresher {
|
||||
crate::verify::apply_role(ctx, &mut member, data.fresher).await?;
|
||||
}
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.components(|c| c).embed(|e| {
|
||||
e.thumbnail(user.avatar_url().unwrap_or(super::AVATAR.to_string()))
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.components(vec![])
|
||||
.embed(
|
||||
CreateEmbed::new()
|
||||
.thumbnail(
|
||||
user.avatar_url().unwrap_or(super::AVATAR.to_string()),
|
||||
)
|
||||
.title("Member verified via manual")
|
||||
.description(&user)
|
||||
.field("Fresher", fresher, true)
|
||||
.description(user.to_string())
|
||||
.field("Fresher", fresher.to_string(), true)
|
||||
.field("Nickname", mm.nickname, true)
|
||||
.field("Name", mm.realname, true)
|
||||
.timestamp(serenity::Timestamp::now())
|
||||
})
|
||||
})
|
||||
})
|
||||
.timestamp(serenity::Timestamp::now()),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
let _ = member.remove_role(&ctx.http, data.non_member).await;
|
||||
if member.roles.contains(&data.old_member) {
|
||||
|
@ -263,29 +268,33 @@ pub(crate) async fn manual_4(
|
|||
}
|
||||
Err(e) => {
|
||||
tracing::error!("{e}");
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(format!("Failed to add user {user} to member database"))
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(format!("Failed to add user {user} to member database")),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
crate::db::delete_manual_by_id(&data.db, user.id.into()).await?;
|
||||
tracing::info!("{} ({}) denied via manual", user.name, user.id);
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.components(|c| c).embed(|e| {
|
||||
e.title("Member denied via manual")
|
||||
.description(&user)
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.components(vec![])
|
||||
.embed(
|
||||
CreateEmbed::new()
|
||||
.title("Member denied via manual")
|
||||
.description(user.to_string())
|
||||
.thumbnail(user.avatar_url().unwrap_or(super::AVATAR.to_string()))
|
||||
.timestamp(serenity::Timestamp::now())
|
||||
})
|
||||
})
|
||||
})
|
||||
.timestamp(serenity::Timestamp::now()),
|
||||
),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{Data, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{
|
||||
self as serenity, CreateActionRow, CreateButton, CreateEmbed, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, CreateMessage,
|
||||
};
|
||||
use poise::Modal;
|
||||
|
||||
const MEMBERSHIP_INTRO: &str = indoc::indoc! {"
|
||||
|
@ -17,34 +20,28 @@ const MEMBERSHIP_INTRO: &str = indoc::indoc! {"
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn membership_1(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(MEMBERSHIP_INTRO).components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙')
|
||||
.custom_id("restart")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Fresher")
|
||||
.custom_id("membership_2f")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('❌')
|
||||
.label("Non-fresher")
|
||||
.custom_id("membership_2n")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(MEMBERSHIP_INTRO)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("restart")
|
||||
.style(serenity::ButtonStyle::Danger)
|
||||
.emoji('🔙'),
|
||||
CreateButton::new("membership_2f")
|
||||
.style(serenity::ButtonStyle::Success)
|
||||
.emoji('✅')
|
||||
.label("Fresher"),
|
||||
CreateButton::new("membership_2n")
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('❌')
|
||||
.label("Non-fresher"),
|
||||
])]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -66,7 +63,7 @@ struct Membership {
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn membership_2(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
data: &Data,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -76,17 +73,17 @@ pub(crate) async fn membership_2(
|
|||
// Delete from manual if exists
|
||||
let _ = crate::db::delete_manual_by_id(&data.db, m.user.id.into()).await;
|
||||
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
*i = Membership::create(
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
Membership::create(
|
||||
None,
|
||||
if fresher {
|
||||
"membership_3f".to_string()
|
||||
} else {
|
||||
"membership_3n".to_string()
|
||||
},
|
||||
);
|
||||
i
|
||||
})
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -94,7 +91,7 @@ pub(crate) async fn membership_2(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn membership_3(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::ModalSubmitInteraction,
|
||||
m: &serenity::ModalInteraction,
|
||||
data: &Data,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -108,13 +105,14 @@ pub(crate) async fn membership_3(
|
|||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
tracing::error!("{e}");
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Sorry, getting membership data failed. Please try again")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Sorry, getting membership data failed. Please try again")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -123,12 +121,16 @@ pub(crate) async fn membership_3(
|
|||
((member.login.is_empty() && member.cid == shortcode) || member.login == shortcode)
|
||||
&& member.order_no.to_string() == order
|
||||
}) else {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
let msg = "Sorry, your order was not found, please check the \
|
||||
order number and that it is for your current year's membership";
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| d.content(msg).ephemeral(true))
|
||||
})
|
||||
let msg = "Sorry, your order was not found, please check the \
|
||||
order number and that it is for your current year's membership";
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(msg)
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
return Ok(());
|
||||
};
|
||||
|
@ -157,32 +159,35 @@ pub(crate) async fn membership_3(
|
|||
if fresher {
|
||||
crate::verify::apply_role(ctx, &mut mm, data.fresher).await?;
|
||||
}
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::UpdateMessage)
|
||||
.interaction_response_data(|d| {
|
||||
d.content(if fresher {
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::UpdateMessage(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(if fresher {
|
||||
"Congratulations, you have completed verification and now \
|
||||
have access to the ICAS Discord and freshers thread"
|
||||
} else {
|
||||
"Congratulations, you have completed verification and now \
|
||||
have access to the ICAS Discord"
|
||||
})
|
||||
.components(|c| c)
|
||||
})
|
||||
})
|
||||
.components(vec![]),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
data.au_ch_id
|
||||
.send_message(&ctx.http, |cm| {
|
||||
cm.add_embed(|e| {
|
||||
e.thumbnail(m.user.avatar_url().unwrap_or(super::AVATAR.to_string()))
|
||||
.send_message(
|
||||
&ctx.http,
|
||||
CreateMessage::new().embed(
|
||||
CreateEmbed::new()
|
||||
.thumbnail(m.user.avatar_url().unwrap_or(super::AVATAR.to_string()))
|
||||
.title("Member verified via membership")
|
||||
.description(&m.user)
|
||||
.field("Fresher", fresher, true)
|
||||
.description(m.user.to_string())
|
||||
.field("Fresher", fresher.to_string(), true)
|
||||
.field("Nickname", nickname, true)
|
||||
.field("Name", realname, true)
|
||||
.timestamp(serenity::Timestamp::now())
|
||||
})
|
||||
})
|
||||
.timestamp(serenity::Timestamp::now()),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
let _ = mm.remove_role(&ctx.http, data.non_member).await;
|
||||
if mm.roles.contains(&data.old_member) {
|
||||
|
@ -196,13 +201,14 @@ pub(crate) async fn membership_3(
|
|||
}
|
||||
Err(e) => tracing::error!("{e}"),
|
||||
};
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Sorry, something went wrong. Please try again")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
use crate::{Data, Error};
|
||||
use poise::serenity_prelude as serenity;
|
||||
use poise::serenity_prelude::{
|
||||
self as serenity, CacheHttp, CreateActionRow, CreateButton, CreateInteractionResponse,
|
||||
CreateInteractionResponseMessage, CreateMessage,
|
||||
};
|
||||
|
||||
pub(crate) mod login;
|
||||
pub(crate) use login::*;
|
||||
|
@ -23,12 +26,16 @@ const INFO_MSG: &str = indoc::indoc! {"
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn info(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| d.content(INFO_MSG).ephemeral(true))
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(INFO_MSG)
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -36,15 +43,19 @@ pub(crate) async fn info(
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn unknown(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
) -> Result<(), Error> {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Sorry, something went wrong. Please try again or message <@99217900254035968> for help")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content(
|
||||
"Sorry, something went wrong. Please try again \
|
||||
or message <@99217900254035968> for help",
|
||||
)
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -59,7 +70,7 @@ const START_MSG: &str = indoc::indoc! {"
|
|||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn start(
|
||||
ctx: &serenity::Context,
|
||||
m: &serenity::MessageComponentInteraction,
|
||||
m: &serenity::ComponentInteraction,
|
||||
data: &Data,
|
||||
init: bool,
|
||||
) -> Result<(), Error> {
|
||||
|
@ -70,46 +81,41 @@ pub(crate) async fn start(
|
|||
if member.fresher {
|
||||
apply_role(ctx, &mut mm, data.fresher).await?;
|
||||
}
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(serenity::InteractionResponseType::ChannelMessageWithSource)
|
||||
.interaction_response_data(|d| {
|
||||
d.content("Welcome, you're already verified, re-applied your roles!")
|
||||
.ephemeral(true)
|
||||
})
|
||||
})
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
CreateInteractionResponse::Message(
|
||||
CreateInteractionResponseMessage::new()
|
||||
.content("Welcome, you're already verified, re-applied your roles!")
|
||||
.ephemeral(true),
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
} else {
|
||||
m.create_interaction_response(&ctx.http, |i| {
|
||||
i.kind(if init {
|
||||
serenity::InteractionResponseType::ChannelMessageWithSource
|
||||
let irm = CreateInteractionResponseMessage::new()
|
||||
.content(START_MSG)
|
||||
.ephemeral(true)
|
||||
.components(vec![CreateActionRow::Buttons(vec![
|
||||
CreateButton::new("login_1")
|
||||
.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('🚀')
|
||||
.label("Login"),
|
||||
CreateButton::new("membership_1")
|
||||
.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji(serenity::ReactionType::Unicode("✈️".to_string()))
|
||||
.label("Membership"),
|
||||
CreateButton::new("manual_1")
|
||||
.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji('🚗')
|
||||
.label("Manual"),
|
||||
])]);
|
||||
m.create_response(
|
||||
&ctx.http,
|
||||
if init {
|
||||
CreateInteractionResponse::Message(irm)
|
||||
} else {
|
||||
serenity::InteractionResponseType::UpdateMessage
|
||||
})
|
||||
.interaction_response_data(|d| {
|
||||
d.content(START_MSG).ephemeral(true).components(|c| {
|
||||
c.create_action_row(|a| {
|
||||
a.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Primary)
|
||||
.emoji('🚀')
|
||||
.label("Login")
|
||||
.custom_id("login_1")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji(serenity::ReactionType::Unicode("✈️".to_string()))
|
||||
.label("Membership")
|
||||
.custom_id("membership_1")
|
||||
})
|
||||
.create_button(|b| {
|
||||
b.style(serenity::ButtonStyle::Secondary)
|
||||
.emoji('🚗')
|
||||
.label("Manual")
|
||||
.custom_id("manual_1")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
CreateInteractionResponse::UpdateMessage(irm)
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
};
|
||||
Ok(())
|
||||
|
@ -135,14 +141,15 @@ pub(crate) async fn remove_role(
|
|||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn welcome_user(
|
||||
http: impl AsRef<serenity::http::Http>,
|
||||
http: impl CacheHttp,
|
||||
channel: &serenity::ChannelId,
|
||||
user: &serenity::User,
|
||||
fresher: bool,
|
||||
) -> Result<(), Error> {
|
||||
channel
|
||||
.send_message(http, |m| {
|
||||
m.content(format!(
|
||||
.send_message(
|
||||
http,
|
||||
CreateMessage::new().content(format!(
|
||||
"Welcome to ICAS {user}, if you have any questions, \
|
||||
feel free to ping a committee member{}!",
|
||||
if fresher {
|
||||
|
@ -150,8 +157,8 @@ pub(crate) async fn welcome_user(
|
|||
} else {
|
||||
""
|
||||
}
|
||||
))
|
||||
})
|
||||
)),
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue