Compare commits
10 Commits
1b2f0e25ac
...
a9f4240710
Author | SHA1 | Date | |
---|---|---|---|
a9f4240710 | |||
a709598cf6 | |||
52b9b6f968 | |||
8ae9ec821f | |||
0c1e534e19 | |||
f43bfe3a6a | |||
dcedac1128 | |||
0d0d744e33 | |||
4bf5646e28 | |||
48924d4bd9 |
17
Cargo.lock
generated
17
Cargo.lock
generated
@ -3535,6 +3535,15 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_cow"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64e84ce5596a72f0c4c60759a10ff8c22d5eaf227b0dc2789c8746193309058b"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.203"
|
version = "1.0.203"
|
||||||
@ -3635,13 +3644,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serenity"
|
name = "serenity"
|
||||||
version = "0.12.1"
|
version = "0.12.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/serenity-rs/serenity?branch=current#060ee3281b44f7e532f3ea5863c5df57340e1ec9"
|
||||||
checksum = "c64da29158bb55d70677cacd4f4f8eab1acef005fb830d9c3bea411b090e96a9"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
"bitflags 2.5.0",
|
"bitflags 2.5.0",
|
||||||
"bytes",
|
"bytes",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -3655,6 +3663,7 @@ dependencies = [
|
|||||||
"reqwest",
|
"reqwest",
|
||||||
"secrecy",
|
"secrecy",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_cow",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"time",
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -51,6 +51,8 @@ serde_with = "3.8.1"
|
|||||||
tokio-cron = "0.1.3"
|
tokio-cron = "0.1.3"
|
||||||
cron = "0.12.1"
|
cron = "0.12.1"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
serenity = { git = "https://github.com/serenity-rs/serenity", branch = "current" }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "botdiscord"
|
name = "botdiscord"
|
||||||
|
@ -10,7 +10,7 @@ Main lib used : [serenity-rs/serenity](https://github.com/serenity-rs/serenity)
|
|||||||
|
|
||||||
- [DONE] ImageWareHouse (like TestDiscord)
|
- [DONE] ImageWareHouse (like TestDiscord)
|
||||||
- ImageWareHouse V2
|
- ImageWareHouse V2
|
||||||
- Mise en place d'autre source de gif OPT
|
- Mise en place d'autre source de gif comme [Teno](https://developers.google.com/tenor/guides/quickstart?hl=fr)
|
||||||
- SoundBoard (like UnlabeledBot)
|
- SoundBoard (like UnlabeledBot)
|
||||||
- Notification (read an event topic and send the message to the expected chan)
|
- Notification (read an event topic and send the message to the expected chan)
|
||||||
- Some Administration command
|
- Some Administration command
|
||||||
@ -24,9 +24,9 @@ Main lib used : [serenity-rs/serenity](https://github.com/serenity-rs/serenity)
|
|||||||
- Monitor the bot
|
- Monitor the bot
|
||||||
- Authentification Discord
|
- Authentification Discord
|
||||||
- Detecter controle
|
- Detecter controle
|
||||||
- [WIP] Integrate with the Opentelemetry project
|
- [DONE] Integrate with the Opentelemetry project
|
||||||
- The bot has to be able to be deployed on a k8s cluster
|
- [DONE] The bot has to be able to be deployed on a k8s cluster
|
||||||
- The bot has to be OPT-IN (the user has to enable the bot on his server with a command)
|
- [DONE] The bot has to be OPT-IN (the user has to enable the bot on his server with a command)
|
||||||
- Mise en place de metric OpenTelemetry
|
- Mise en place de metric OpenTelemetry
|
||||||
|
|
||||||
## previous project
|
## previous project
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::botv2::{
|
use crate::{
|
||||||
|
botv2::{
|
||||||
domain::concour::{
|
domain::concour::{
|
||||||
check_if_allowed::check_if_allowed,
|
check_if_allowed::check_if_allowed,
|
||||||
set_periode::{set_periode, SetPeriodeConcourError},
|
set_periode::{set_periode, SetPeriodeConcourError},
|
||||||
},
|
},
|
||||||
init::{Context, Error},
|
init::{Context, Error},
|
||||||
|
},
|
||||||
|
db::concour::ConcourStatus,
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use cron::Schedule;
|
use cron::Schedule;
|
||||||
@ -66,7 +69,8 @@ pub async fn period(
|
|||||||
};
|
};
|
||||||
let schedule = match Schedule::from_str(&cron_schedule) {
|
let schedule = match Schedule::from_str(&cron_schedule) {
|
||||||
Ok(schedule) => schedule,
|
Ok(schedule) => schedule,
|
||||||
Err(_) => {
|
Err(err) => {
|
||||||
|
warn!(err = err.to_string(), "Cron format is invalid");
|
||||||
let embed = CreateEmbed::new()
|
let embed = CreateEmbed::new()
|
||||||
.title("Invalid CRON format")
|
.title("Invalid CRON format")
|
||||||
.color(colour::Color::RED)
|
.color(colour::Color::RED)
|
||||||
@ -118,16 +122,55 @@ pub async fn period(
|
|||||||
.color(colour::Color::RED)
|
.color(colour::Color::RED)
|
||||||
} else {
|
} else {
|
||||||
let concour = concour.unwrap();
|
let concour = concour.unwrap();
|
||||||
CreateEmbed::new()
|
let mut output = CreateEmbed::new()
|
||||||
.title(concour.title)
|
.title(concour.title)
|
||||||
.description(concour.description)
|
.description(concour.description)
|
||||||
.field("Start date", concour.start_date.to_string(), false)
|
.field("Start date", concour.start_date.to_string(), false)
|
||||||
.field("Periode", concour.periode.to_string(), false)
|
.field("Periode", concour.periode.to_string(), false);
|
||||||
.field(
|
|
||||||
|
if concour.role_recompense == 0 {
|
||||||
|
output = output.field("Role récompense", "Aucun", false);
|
||||||
|
} else {
|
||||||
|
output = output.field(
|
||||||
"Role récompense",
|
"Role récompense",
|
||||||
RoleId::new(concour.role_recompense).mention().to_string(),
|
RoleId::new(concour.role_recompense).mention().to_string(),
|
||||||
false,
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Restart the cronjob if concour is ongoing
|
||||||
|
if concour.status == ConcourStatus::OnGoing {
|
||||||
|
{
|
||||||
|
let mut scheduler = ctx.data().scheduler.clone();
|
||||||
|
match scheduler
|
||||||
|
.stop_scheduled_job(concour.server_id, concour.channel_id)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => {
|
||||||
|
info!("Cronjob stopped");
|
||||||
|
match scheduler
|
||||||
|
.add_concour_cron_job(
|
||||||
|
concour.server_id,
|
||||||
|
concour.channel_id,
|
||||||
|
concour.periode,
|
||||||
|
ctx.http(),
|
||||||
)
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(_) => {
|
||||||
|
info!("Cronjob restarted");
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
warn!("Error restarting cronjob");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
warn!(err = err.to_string(), "Error stopping cronjob");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
|
@ -83,6 +83,11 @@ pub async fn start(ctx: Context<'_>) -> Result<(), Error> {
|
|||||||
Some(role) => RoleId::new(role).mention().to_string(),
|
Some(role) => RoleId::new(role).mention().to_string(),
|
||||||
None => "".to_string(),
|
None => "".to_string(),
|
||||||
};
|
};
|
||||||
|
let role_recompense = if concour.role_recompense != 0 {
|
||||||
|
RoleId::new(concour.role_recompense).mention().to_string()
|
||||||
|
} else {
|
||||||
|
"(Pas encore définis)".to_string()
|
||||||
|
};
|
||||||
let text = format!("
|
let text = format!("
|
||||||
Bonsoir !
|
Bonsoir !
|
||||||
|
|
||||||
@ -90,14 +95,14 @@ Bonsoir !
|
|||||||
|
|
||||||
📜 ❱ Les règles : Pas de loli, ni de shoota, ni de irl, ni de zoo.
|
📜 ❱ Les règles : Pas de loli, ni de shoota, ni de irl, ni de zoo.
|
||||||
|
|
||||||
Celui ou celle qui a le plus de votes gagne, comme récompense elle aura le rôle @ROLE pour une durée de 48h.
|
Celui ou celle qui a le plus de votes gagne, comme récompense elle aura le rôle {} pour une durée de 48h.
|
||||||
Le concours ce termine dans deux jours.
|
Le concours ce termine dans deux jours.
|
||||||
Ceux qui votent pour leur propre photo, cela ne sera pas pris en compte, une photo par personne.
|
Ceux qui votent pour leur propre photo, cela ne sera pas pris en compte, une photo par personne.
|
||||||
|
|
||||||
À vos photos !
|
À vos photos !
|
||||||
|
|
||||||
{}
|
{}
|
||||||
", keyword.to_string(),ping_concour);
|
", keyword,role_recompense,ping_concour);
|
||||||
let output = CreateEmbed::new()
|
let output = CreateEmbed::new()
|
||||||
.title(format!(
|
.title(format!(
|
||||||
"Concour: {} Jour : {}",
|
"Concour: {} Jour : {}",
|
||||||
|
18
src/botv2/cmd/meme/main.rs
Normal file
18
src/botv2/cmd/meme/main.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use crate::botv2::{
|
||||||
|
cmd::meme::{answer::answer, enable::enable, list::list},
|
||||||
|
init::{Context, Error},
|
||||||
|
};
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
|
/// Handle meme command
|
||||||
|
#[instrument(skip(ctx), level = "info", fields(channel = ctx.channel_id().get(), guild = ?ctx.guild_id().unwrap().get()))]
|
||||||
|
#[poise::command(
|
||||||
|
slash_command,
|
||||||
|
prefix_command,
|
||||||
|
category = "mem",
|
||||||
|
subcommands("answer", "enable", "list"),
|
||||||
|
guild_only = true
|
||||||
|
)]
|
||||||
|
pub async fn meme(ctx: Context<'_>) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
pub mod answer;
|
pub mod answer;
|
||||||
pub mod enable;
|
pub mod enable;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
|
pub mod main;
|
||||||
|
@ -1,121 +1,18 @@
|
|||||||
use super::init::{Data, Error};
|
use super::init::{Data, Error};
|
||||||
use crate::{db::user_image::User, img::config_file::KeyWordItem};
|
|
||||||
use poise::serenity_prelude as serenity;
|
use poise::serenity_prelude as serenity;
|
||||||
use rand::Rng;
|
|
||||||
use serenity::all::{CreateAttachment, CreateMessage};
|
|
||||||
use tokio::fs::File;
|
|
||||||
use tracing::{info, instrument};
|
use tracing::{info, instrument};
|
||||||
|
#[allow(clippy::single_match)]
|
||||||
#[instrument(skip(ctx, _framework, data), err, level = "trace")]
|
#[instrument(skip(_ctx, _framework, _data), err, level = "trace")]
|
||||||
pub async fn event_handler(
|
pub async fn event_handler(
|
||||||
ctx: &serenity::Context,
|
_ctx: &serenity::Context,
|
||||||
event: &serenity::FullEvent,
|
event: &serenity::FullEvent,
|
||||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||||
data: &Data,
|
_data: &Data,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match event {
|
match event {
|
||||||
serenity::FullEvent::Ready { data_about_bot, .. } => {
|
serenity::FullEvent::Ready { data_about_bot, .. } => {
|
||||||
info!("{} is connected !", data_about_bot.user.name);
|
info!("{} is connected !", data_about_bot.user.name);
|
||||||
}
|
}
|
||||||
serenity::FullEvent::Message { new_message } => {
|
|
||||||
if new_message.author.bot
|
|
||||||
|| new_message.content.starts_with(&data.config.prefix.clone())
|
|
||||||
|| new_message.content.is_empty()
|
|
||||||
{
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let config_img = data.config_img.clone();
|
|
||||||
let config = data.config.clone();
|
|
||||||
let guild = match new_message.guild_id {
|
|
||||||
Some(guild) => guild,
|
|
||||||
None => return Ok(()),
|
|
||||||
};
|
|
||||||
let user_in_db =
|
|
||||||
match User::find_by_server_id_user_id(&guild.get(), &new_message.author.id.get())
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(Some(user_in_db)) => user_in_db.clone(),
|
|
||||||
Ok(None) => {
|
|
||||||
let user_in_db =
|
|
||||||
User::new(guild.get(), new_message.author.id.get(), false).unwrap();
|
|
||||||
match user_in_db.create().await {
|
|
||||||
Ok(_) => user_in_db,
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error saving user image: {:?}", e);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error finding user image: {:?}", e);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if !user_in_db.enable {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if config_img.keyword.is_empty() || new_message.content.len() > 50 {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let folder_container = match config_img
|
|
||||||
.keyword
|
|
||||||
.iter()
|
|
||||||
.find(|keyword| keyword.does_value_match(new_message.content.clone()))
|
|
||||||
{
|
|
||||||
Some(keyword_matching) => {
|
|
||||||
println!("{} match {:?}", new_message.content, keyword_matching);
|
|
||||||
let keyword_path = match keyword_matching.path.len() {
|
|
||||||
0 => keyword_matching.path[0].clone(),
|
|
||||||
_ => {
|
|
||||||
let id: usize = {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
rng.gen_range(0..keyword_matching.path.len())
|
|
||||||
};
|
|
||||||
keyword_matching.path[id].clone()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
keyword_path.clone()
|
|
||||||
}
|
|
||||||
None => return Ok(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let path = format!("{}/{}", config.image.path.clone(), folder_container);
|
|
||||||
let file_folder = KeyWordItem::output_folder_content(path.clone());
|
|
||||||
let id_rand: usize = {
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
rng.gen_range(0..file_folder.len())
|
|
||||||
};
|
|
||||||
let filename = match file_folder.get(id_rand) {
|
|
||||||
Some(file) => file.file_name().to_str().unwrap(),
|
|
||||||
None => return Ok(()),
|
|
||||||
};
|
|
||||||
let file_path = format!("{}/{}", path, filename);
|
|
||||||
let file = match File::open(file_path).await {
|
|
||||||
Ok(file) => file,
|
|
||||||
Err(why) => {
|
|
||||||
println!("Error opening file: {:?}", why);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let attachment = match CreateAttachment::file(&file, filename).await {
|
|
||||||
Ok(attachment) => attachment,
|
|
||||||
Err(why) => {
|
|
||||||
println!("Error creating attachment: {:?}", why);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let builder = CreateMessage::new().add_file(attachment);
|
|
||||||
|
|
||||||
if let Err(why) = new_message
|
|
||||||
.channel_id
|
|
||||||
.send_message(&ctx.http, builder)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
println!("Error sending message: {:?}", why);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::botv2::cmd::meme::{answer::answer, enable::enable, list::list};
|
use crate::botv2::cmd::meme::main::meme;
|
||||||
use crate::botv2::cmd::server_config::server::server;
|
use crate::botv2::cmd::server_config::server::server;
|
||||||
use crate::botv2::cmd::{help::help, ping::ping};
|
use crate::botv2::cmd::{help::help, ping::ping};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
@ -9,7 +9,7 @@ use serenity::GatewayIntents;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tracing::{info, instrument};
|
use tracing::info;
|
||||||
|
|
||||||
use super::cmd::concour::main::concour;
|
use super::cmd::concour::main::concour;
|
||||||
|
|
||||||
@ -24,18 +24,6 @@ pub struct Data {
|
|||||||
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
pub type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||||
pub type Context<'a> = poise::Context<'a, Data, Error>;
|
pub type Context<'a> = poise::Context<'a, Data, Error>;
|
||||||
|
|
||||||
#[instrument(skip(ctx), level = "info")]
|
|
||||||
#[poise::command(slash_command, prefix_command)]
|
|
||||||
async fn age(
|
|
||||||
ctx: Context<'_>,
|
|
||||||
#[description = "Selected user"] user: Option<serenity::User>,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
let u = user.as_ref().unwrap_or_else(|| ctx.author());
|
|
||||||
let response = format!("{}'s account was created at {}", u.name, u.created_at());
|
|
||||||
ctx.say(response).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn start_bot(
|
pub async fn start_bot(
|
||||||
config: Config,
|
config: Config,
|
||||||
rx: oneshot::Receiver<()>,
|
rx: oneshot::Receiver<()>,
|
||||||
@ -67,16 +55,7 @@ pub async fn start_bot(
|
|||||||
let prefix = config.prefix.clone();
|
let prefix = config.prefix.clone();
|
||||||
let framework = poise::Framework::builder()
|
let framework = poise::Framework::builder()
|
||||||
.options(poise::FrameworkOptions {
|
.options(poise::FrameworkOptions {
|
||||||
commands: vec![
|
commands: vec![ping(), help(), meme(), server(), concour()],
|
||||||
age(),
|
|
||||||
ping(),
|
|
||||||
help(),
|
|
||||||
list(),
|
|
||||||
enable(),
|
|
||||||
answer(),
|
|
||||||
server(),
|
|
||||||
concour(),
|
|
||||||
],
|
|
||||||
prefix_options: poise::PrefixFrameworkOptions {
|
prefix_options: poise::PrefixFrameworkOptions {
|
||||||
prefix: Some(prefix),
|
prefix: Some(prefix),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use poise::serenity_prelude::{
|
use poise::serenity_prelude::{
|
||||||
Color, CreateEmbed, CreateMessage, Http, Mentionable, MessagePagination,
|
Color, CreateEmbed, CreateMessage, Http, Mentionable, MessagePagination, RoleId,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
@ -291,16 +291,16 @@ impl ScheduleJob {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let embed = CreateEmbed::default()
|
// let embed = CreateEmbed::default()
|
||||||
.title("Winner")
|
// .title("Winner")
|
||||||
.description(format!("The winner is {}", winner.mention()))
|
// .description(format!("The winner is {}", winner.mention()))
|
||||||
.color(Color::DARK_GREEN);
|
// .color(Color::DARK_GREEN);
|
||||||
let reply = CreateMessage::default().embed(embed);
|
// let reply = CreateMessage::default().embed(embed);
|
||||||
if let Err(err) =
|
// if let Err(err) =
|
||||||
http.send_message(channel_id.into(), vec![], &reply).await
|
// http.send_message(channel_id.into(), vec![], &reply).await
|
||||||
{
|
// {
|
||||||
error!("Error sending message: {:?}", err);
|
// error!("Error sending message: {:?}", err);
|
||||||
}
|
// }
|
||||||
let (add, previous) = match concour.winner.last() {
|
let (add, previous) = match concour.winner.last() {
|
||||||
Some(previous_winner) => (
|
Some(previous_winner) => (
|
||||||
previous_winner.user_id != winner.id.get(),
|
previous_winner.user_id != winner.id.get(),
|
||||||
@ -376,6 +376,33 @@ impl ScheduleJob {
|
|||||||
.keywords
|
.keywords
|
||||||
.get(concour.index_keyword as usize)
|
.get(concour.index_keyword as usize)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let ping_role = match concour.ping_concour {
|
||||||
|
Some(role_id) => RoleId::new(role_id).mention().to_string(),
|
||||||
|
None => "".to_string(),
|
||||||
|
};
|
||||||
|
let role_recompense = if concour.role_recompense != 0 {
|
||||||
|
RoleId::new(concour.role_recompense).mention().to_string()
|
||||||
|
} else {
|
||||||
|
"(Pas encore définis)".to_string()
|
||||||
|
};
|
||||||
|
let answer = format!(
|
||||||
|
"Bonsoir !
|
||||||
|
|
||||||
|
🏆 ❱ Bravo à {} pour ses réactions sous son image.
|
||||||
|
|
||||||
|
👹 ❱ Le thème de ce soir est : {}
|
||||||
|
|
||||||
|
📜 ❱ Les règles : Pas de loli, ni de shoota, ni de irl, ni de zoo.
|
||||||
|
|
||||||
|
Celui ou celle qui a le plus de votes gagne, comme récompense elle aura le rôle {} pour une durée de 48h.
|
||||||
|
Le concours ce termine dans deux jours.
|
||||||
|
Ceux qui votent pour leur propre photo, cela ne sera pas pris en compte, une photo par personne.
|
||||||
|
|
||||||
|
À vos photos !
|
||||||
|
|
||||||
|
{}",
|
||||||
|
winner.id.mention(), next_keyword,role_recompense, ping_role
|
||||||
|
);
|
||||||
let output = CreateEmbed::new()
|
let output = CreateEmbed::new()
|
||||||
.title(format!(
|
.title(format!(
|
||||||
"Concour: {} Jour : {}",
|
"Concour: {} Jour : {}",
|
||||||
@ -391,7 +418,12 @@ impl ScheduleJob {
|
|||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
.color(Color::DARK_GREEN);
|
.color(Color::DARK_GREEN);
|
||||||
let reply = CreateMessage::default().embed(output);
|
let mut reply = CreateMessage::default();
|
||||||
|
if !answer.is_empty() {
|
||||||
|
reply = reply.content(answer);
|
||||||
|
}else{
|
||||||
|
reply = reply.embed(output);
|
||||||
|
}
|
||||||
let last_id =
|
let last_id =
|
||||||
match http.send_message(channel_id.into(), vec![], &reply).await {
|
match http.send_message(channel_id.into(), vec![], &reply).await {
|
||||||
Ok(message) => message.id,
|
Ok(message) => message.id,
|
||||||
|
Loading…
Reference in New Issue
Block a user