stat_summoner/module/followgames/utils.rs
1use crate::embed::schedule_message_deletion;
2use crate::embed::{create_embed_error, create_embed_success};
3use crate::models::data::{Data, SummonerFollowedData};
4use crate::models::error::Error;
5use crate::models::modal::FollowGamesModal;
6use mongodb::bson::doc;
7
8/// ⚙️ **Function**: Adds a summoner to the database for game follow-up if they are not already being followed.
9///
10/// This asynchronous function checks if a summoner is already being followed by querying the MongoDB collection using their `puuid`.
11/// If they are not followed yet, it adds the summoner's data to the database and returns a success message. If the summoner is already followed, an error message is returned.
12///
13/// # Parameters:
14/// - `collection`: A MongoDB collection (`mongodb::Collection<SummonerFollowedData>`) where the summoner's follow data is stored.
15/// - `ctx`: The `poise::ApplicationContext` provides the context for the Discord interaction, including the ability to send responses.
16/// - `modal_data`: A `FollowGamesModal` struct containing the user's input data from the modal (game name, tag line, etc.).
17/// - `region_str`: A string representing the summoner's region (e.g., "NA", "EUW").
18/// - `puuid`: A string containing the summoner's unique PUUID (player unique identifier from Riot's API).
19/// - `guild_id`: An integer representing the ID of the Discord guild.
20/// - `summoner_id`: A string containing the summoner's unique Summoner ID from Riot's API.
21/// - `match_id`: A string representing the summoner's latest match ID.
22/// - `time_end_follow`: A string representing the timestamp for when the follow period ends.
23///
24/// # Returns:
25/// - `Result<(), Error>`: Returns an empty result if the operation is successful, or an error if any part of the process fails.
26///
27/// # Example:
28/// This function is used internally to add a summoner to the follow list after a successful interaction with the `/followgames` command:
29///
30/// ```rust
31/// check_and_add_in_db(collection, ctx, modal_data, region_str, puuid, summoner_id, match_id, time_end_follow).await?;
32/// ```
33///
34/// # Notes:
35/// - If the user is already being followed, an error message is sent to the Discord channel using `create_embed_error`.
36/// - If the user is successfully added to the database, a success message is sent using `create_embed_success`.
37/// - The function makes sure to handle errors from both MongoDB operations and Discord message sending by logging appropriate error messages.
38pub async fn check_and_add_in_db(
39 collection: mongodb::Collection<SummonerFollowedData>,
40 ctx: poise::ApplicationContext<'_, Data, Error>,
41 modal_data: FollowGamesModal,
42 region_str: String,
43 puuid: String,
44 match_id: String,
45 time_end_follow: String,
46) -> Result<(), Error> {
47 match collection.find_one(doc! { "puuid": puuid.clone() }).await {
48 Ok(Some(_followed_summoner)) => {
49 let guild_id = ctx.guild_id().map(|id| id.get()).unwrap_or(0).to_string();
50 if _followed_summoner.guild_id == guild_id {
51 match collection
52 .update_one(
53 doc! { "puuid": puuid.clone(), "guild_id": guild_id },
54 doc! { "$set": { "time_end_follow": time_end_follow.clone() } },
55 )
56 .await
57 {
58 Ok(_) => {
59 let success_message = "Success, tracking time has been updated.";
60 let reply = ctx.send(create_embed_success(&success_message)).await?;
61 schedule_message_deletion(reply, ctx).await?;
62 return Ok(());
63 }
64 Err(_) => {
65 let error_message = "Error, failed to update tracking time.";
66 let reply = ctx.send(create_embed_error(&error_message)).await?;
67 schedule_message_deletion(reply, ctx).await?;
68 return Ok(());
69 }
70 }
71 } else {
72 let guild_id = ctx.guild_id().map(|id| id.get()).unwrap_or(0).to_string();
73 let channel_id = ctx.channel_id().get();
74 let new_followed_summoner = SummonerFollowedData {
75 puuid: puuid.clone(),
76 name: modal_data.game_name.clone(),
77 tag: modal_data.tag_line.clone(),
78 region: region_str.to_string(),
79 last_match_id: match_id.clone(),
80 time_end_follow: time_end_follow.clone(),
81 channel_id: channel_id,
82 guild_id: guild_id,
83 };
84 match collection.insert_one(new_followed_summoner).await {
85 Ok(_) => {
86 let success_message = "User has been followed.";
87 let reply = ctx.send(create_embed_success(&success_message)).await?;
88 schedule_message_deletion(reply, ctx).await?;
89 return Ok(());
90 }
91 Err(e) => {
92 let error_message = format!("Error inserting user to MongoDB: {}", e);
93 let reply = ctx.send(create_embed_error(&error_message)).await?;
94 schedule_message_deletion(reply, ctx).await?;
95 return Ok(());
96 }
97 }
98 }
99 }
100 Ok(None) => {
101 let guild_id = ctx.guild_id().map(|id| id.get()).unwrap_or(0).to_string();
102 let channel_id = ctx.channel_id().get();
103 let new_followed_summoner = SummonerFollowedData {
104 puuid: puuid.clone(),
105 name: modal_data.game_name.clone(),
106 tag: modal_data.tag_line.clone(),
107 region: region_str.to_string(),
108 last_match_id: match_id.clone(),
109 time_end_follow: time_end_follow.clone(),
110 channel_id: channel_id,
111 guild_id: guild_id,
112 };
113 match collection.insert_one(new_followed_summoner).await {
114 Ok(_) => {
115 let success_message = "User has been followed.";
116 let reply = ctx.send(create_embed_success(&success_message)).await?;
117 schedule_message_deletion(reply, ctx).await?;
118 return Ok(());
119 }
120 Err(e) => {
121 let error_message = format!("Error inserting user to MongoDB: {}", e);
122 let reply = ctx.send(create_embed_error(&error_message)).await?;
123 schedule_message_deletion(reply, ctx).await?;
124 return Ok(());
125 }
126 }
127 }
128 Err(e) => {
129 let error_message = format!("Error collecting informations from MongoDB: {}", e);
130 let reply = ctx.send(create_embed_error(&error_message)).await?;
131 schedule_message_deletion(reply, ctx).await?;
132 return Ok(());
133 }
134 }
135}