diff --git a/_migrations/2022-01-26-045730_twitch_channel_points/up.sql b/_migrations/2022-01-26-045730_twitch_channel_points/up.sql index 5e5b02fdcc..a8a23e89ab 100644 --- a/_migrations/2022-01-26-045730_twitch_channel_points/up.sql +++ b/_migrations/2022-01-26-045730_twitch_channel_points/up.sql @@ -34,7 +34,7 @@ CREATE TABLE twitch_channel_point_events ( -- This is the text that the user sends -- This is optional, but we'll coerce null to empty - user_input TEXT NOT NULL, + user_text_input TEXT NOT NULL, -- A UUID for this instance of reward redemption redemption_id VARCHAR(36) NOT NULL, diff --git a/crates/lib/database_queries/src/twitch_pubsub/insert_channel_points.rs b/crates/lib/database_queries/src/twitch_pubsub/insert_channel_points.rs new file mode 100644 index 0000000000..5bae2f0d12 --- /dev/null +++ b/crates/lib/database_queries/src/twitch_pubsub/insert_channel_points.rs @@ -0,0 +1,191 @@ +use anyhow::anyhow; +use chrono::{DateTime, Utc}; +use container_common::anyhow_result::AnyhowResult; +use log::info; +use log::warn; +use sqlx::MySqlPool; + +pub struct TwitchPubsubBitsInsertBuilder { + // ===== Required Fields ===== + + sender_twitch_user_id: Option, + sender_twitch_username: Option, + sender_twitch_username_lowercase: Option, + + destination_channel_id: Option, + destination_channel_name: Option, + + // ===== Optional / Default Fields ===== + + title: String, + prompt: String, + + user_text_input: String, + + redemption_id: String, + reward_id: String, + + reward_cost: u64, + + is_sub_only: bool, + max_per_stream: u64, + max_per_user_per_stream: u64, +} + +impl TwitchPubsubBitsInsertBuilder { + pub fn new() -> Self { + Self { + sender_twitch_user_id: None, + sender_twitch_username: None, + sender_twitch_username_lowercase: None, + destination_channel_id: None, + destination_channel_name: None, + title: "".to_string(), + prompt: "".to_string(), + user_text_input: "".to_string(), + redemption_id: "".to_string(), + reward_id: "".to_string(), + reward_cost: 0, + is_sub_only: false, + max_per_stream: 0, + max_per_user_per_stream: 0, + } + } + + pub fn set_sender_twitch_user_id(mut self, value: Option<&str>) -> Self { + self.sender_twitch_user_id = value.map(|s| s.to_string()); + self + } + + pub fn set_sender_twitch_username(mut self, value: Option<&str>) -> Self { + if let Some(username) = value { + self.sender_twitch_username = Some(username.to_string()); + self.sender_twitch_username_lowercase = Some(username.to_uppercase()); + } else { + self.sender_twitch_username = None; + self.sender_twitch_username_lowercase = None; + } + self + } + + pub fn set_destination_channel_id(mut self, value: Option<&str>) -> Self { + self.destination_channel_id = value.map(|s| s.to_string()); + self + } + + pub fn set_destination_channel_name(mut self, value: Option<&str>) -> Self { + self.destination_channel_name = value.map(|s| s.to_string()); + self + } + + pub fn set_title(mut self, value: &str) -> Self { + self.title = value.to_string(); + self + } + + pub fn set_prompt(mut self, value: &str) -> Self { + self.prompt = value.to_string(); + self + } + + pub fn set_user_tet_input(mut self, value: &str) -> Self { + self.user_text_input = value.to_string(); + self + } + + pub fn set_redemption_id(mut self, value: &str) -> Self { + self.redemption_id = value.to_string(); + self + } + + pub fn set_reward_id(mut self, value: &str) -> Self { + self.reward_id = value.to_string(); + self + } + + pub fn set_is_sub_only(mut self, value: bool) -> Self { + self.is_sub_only = value; + self + } + + pub fn set_max_per_stream(mut self, value: u64) -> Self { + self.max_per_stream = value; + self + } + + pub fn set_max_per_user_per_stream(mut self, value: u64) -> Self { + self.max_per_user_per_stream = value; + self + } + + pub async fn insert(&mut self, mysql_pool: &MySqlPool) -> AnyhowResult<()> { + let sender_twitch_user_id = self.sender_twitch_user_id + .clone() + .ok_or(anyhow!("no sender_twitch_user_id"))?; + + let sender_twitch_username = self.sender_twitch_username + .clone() + .ok_or(anyhow!("no sender_twitch_username"))?; + + let sender_twitch_username_lowercase = self.sender_twitch_username_lowercase + .clone() + .ok_or(anyhow!("no sender_twitch_username_lowercase"))?; + + let destination_channel_id = self.destination_channel_id + .clone() + .ok_or(anyhow!("no destination_channel_id"))?; + + let destination_channel_name = self.destination_channel_name + .clone() + .ok_or(anyhow!("no destination_channel_name"))?; + + let query = sqlx::query!( + r#" +INSERT INTO twitch_channel_point_events +SET + sender_twitch_user_id = ?, + sender_twitch_username = ?, + sender_twitch_username_lowercase = ?, + destination_channel_id = ?, + destination_channel_name = ?, + title = ?, + prompt = ?, + user_text_input = ?, + redemption_id = ?, + reward_id = ?, + reward_cost = ?, + is_sub_only = ?, + max_per_stream = ?, + max_per_user_per_stream = ? + "#, + sender_twitch_user_id, + sender_twitch_username, + sender_twitch_username_lowercase, + destination_channel_id, + destination_channel_name, + self.title.clone(), + self.prompt.clone(), + self.user_text_input.clone(), + self.redemption_id.clone(), + self.reward_id.clone(), + self.reward_cost, + self.is_sub_only, + self.max_per_stream, + self.max_per_user_per_stream, + ); + + let query_result = query.execute(mysql_pool) + .await; + + let _record_id = match query_result { + Ok(res) => { + res.last_insert_id() + }, + Err(err) => { + return Err(anyhow!("Twitch pubsub bits insert DB error: {:?}", err)); + } + }; + + Ok(()) + } +} diff --git a/crates/lib/database_queries/src/twitch_pubsub/mod.rs b/crates/lib/database_queries/src/twitch_pubsub/mod.rs index 0930276ccd..1f8758da1b 100644 --- a/crates/lib/database_queries/src/twitch_pubsub/mod.rs +++ b/crates/lib/database_queries/src/twitch_pubsub/mod.rs @@ -1 +1,2 @@ -pub mod insert_bits; \ No newline at end of file +pub mod insert_bits; +pub mod insert_channel_points; \ No newline at end of file