Migrate (#4)
Reviewed-on: #4
This commit was merged in pull request #4.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
pub const APP_NAME: &str = "sender";
|
||||
|
||||
/// Returns numbers and message paths
|
||||
pub fn get_paths(args: Vec<String>) -> Result<(String, String), std::io::Error> {
|
||||
if args.len() < 2 {
|
||||
Err(std::io::Error::other("Not enough arguments"))
|
||||
} else {
|
||||
let numbers_path = args[1].clone();
|
||||
let message_path = args[2].clone();
|
||||
if !path_exists(&numbers_path) && !path_exists(&message_path) {
|
||||
Err(std::io::Error::other("Paths do not exists"))
|
||||
} else {
|
||||
Ok((numbers_path, message_path))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn path_exists(path: &str) -> bool {
|
||||
let file = std::path::Path::new(path);
|
||||
file.exists()
|
||||
}
|
||||
|
||||
pub async fn parse_config() -> (textsender_models::config::auxiliary::TwilioConfig, bool) {
|
||||
let mut config = textsender_models::config::auxiliary::TwilioConfig {
|
||||
..Default::default()
|
||||
};
|
||||
let auth_sid_var = textsender_models::envy::environment::get_env("AUTH_SID").await;
|
||||
let auth_token_var = textsender_models::envy::environment::get_env("AUTH_TOKEN").await;
|
||||
let phone_number_var = textsender_models::envy::environment::get_env("PHONE_NUMBER").await;
|
||||
let service_sid_var = textsender_models::envy::environment::get_env("SERVICE_SID").await;
|
||||
config.account_sid = auth_sid_var.value;
|
||||
config.auth_token = auth_token_var.value;
|
||||
config.phone_number = phone_number_var.value;
|
||||
config.service_sid = service_sid_var.value;
|
||||
let success = {
|
||||
!config.account_sid.is_empty()
|
||||
&& !config.auth_token.is_empty()
|
||||
&& !config.phone_number.is_empty()
|
||||
&& !config.service_sid.is_empty()
|
||||
};
|
||||
|
||||
(config, success)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_parse_config() {
|
||||
let (config, success) = async_std::task::block_on(super::parse_config());
|
||||
assert!(success, "Config was not parsed");
|
||||
assert_eq!(
|
||||
false,
|
||||
config.account_sid.is_empty(),
|
||||
"Account SID is missing"
|
||||
);
|
||||
assert_eq!(false, config.auth_token.is_empty(), "AUTH TOKEN is missing");
|
||||
assert_eq!(
|
||||
false,
|
||||
config.phone_number.is_empty(),
|
||||
"Phone Number is missing"
|
||||
);
|
||||
assert_eq!(
|
||||
false,
|
||||
config.service_sid.is_empty(),
|
||||
"Service SID is missing"
|
||||
);
|
||||
}
|
||||
}
|
||||
+43
@@ -1,4 +1,47 @@
|
||||
pub mod config;
|
||||
pub mod messaging;
|
||||
pub mod version;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
println!("sender");
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
|
||||
if version::contains_version(&args) {
|
||||
version::print_version();
|
||||
std::process::exit(-1);
|
||||
}
|
||||
|
||||
match config::get_paths(args) {
|
||||
Ok((n_path, m_path)) => {
|
||||
println!("Message path: {m_path:?}");
|
||||
println!("Phone Number path: {n_path:?}");
|
||||
|
||||
let (config, success) = config::parse_config().await;
|
||||
if !success {
|
||||
eprintln!("Error parsing config");
|
||||
} else {
|
||||
let contacts = match messaging::parse_numbers(&n_path) {
|
||||
Ok(contacts) => contacts,
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
std::process::exit(-1);
|
||||
}
|
||||
};
|
||||
let message = match messaging::parse_message(&m_path) {
|
||||
Ok(message) => message,
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
std::process::exit(-1);
|
||||
}
|
||||
};
|
||||
|
||||
println!("Message: {:?}", message.content);
|
||||
messaging::send_messages(&config, &contacts, &message, 5).await;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
use textsender_models::config::auxiliary::TwilioConfig;
|
||||
use textsender_models::contact::Contact;
|
||||
use textsender_models::message::Message;
|
||||
|
||||
pub async fn send_messages(
|
||||
config: &TwilioConfig,
|
||||
contacts: &Vec<Contact>,
|
||||
message: &Message,
|
||||
second_interval: u64,
|
||||
) {
|
||||
let long_sleep_limit: i64 = 5;
|
||||
let mut count: i64 = 0;
|
||||
|
||||
for contact in contacts.iter() {
|
||||
println!("Sending to: {:?}", contact.phone_number);
|
||||
let param = swoosh::twilio::types::Parameters {
|
||||
schedule: false,
|
||||
schedule_at: None,
|
||||
};
|
||||
match swoosh::twilio::api::send_mssage(message, contact, param, config).await {
|
||||
Ok(response) => {
|
||||
println!("Raw response: {response:?}");
|
||||
let val = swoosh::twilio::api::response_to_json(response).await;
|
||||
println!("Response: {val:?}");
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!("Error: {err:?}");
|
||||
}
|
||||
}
|
||||
|
||||
if count % long_sleep_limit == 0 {
|
||||
// Sleep for X seconds
|
||||
let wait_time = second_interval;
|
||||
std::thread::sleep(std::time::Duration::from_secs(wait_time));
|
||||
} else {
|
||||
// Sleep for a second
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_numbers(filepath: &str) -> Result<Vec<Contact>, std::io::Error> {
|
||||
match std::fs::File::open(filepath) {
|
||||
Ok(file) => {
|
||||
let reader = std::io::BufReader::new(file);
|
||||
let contacts: Vec<Contact> = match serde_json::from_reader(reader) {
|
||||
Ok(va) => va,
|
||||
Err(err) => {
|
||||
return Err(std::io::Error::other(err.to_string()));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(contacts)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_message(filepath: &str) -> Result<Message, std::io::Error> {
|
||||
match std::fs::File::open(filepath) {
|
||||
Ok(file) => {
|
||||
let reader = std::io::BufReader::new(file);
|
||||
let message: Message = serde_json::from_reader(reader)?;
|
||||
Ok(message)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_parse_message() {
|
||||
let message_path = String::from("tests/message-0.json");
|
||||
match super::parse_message(&message_path) {
|
||||
Ok(message) => {
|
||||
assert_eq!(false, message.content.is_empty(), "Content is empty");
|
||||
}
|
||||
Err(err) => {
|
||||
assert!(false, "Error: {err:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_numbers() {
|
||||
let numbers_path = String::from("tests/numbers-0.json");
|
||||
match super::parse_numbers(&numbers_path) {
|
||||
Ok(contacts) => {
|
||||
assert_eq!(false, contacts.is_empty(), "Should not be empty");
|
||||
}
|
||||
Err(err) => {
|
||||
assert!(false, "Error: {err:?}");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
pub fn print_version() {
|
||||
let name = env!("CARGO_PKG_NAME");
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
|
||||
println!("{name:?} {version:?}");
|
||||
}
|
||||
|
||||
pub fn contains_version(args: &Vec<String>) -> bool {
|
||||
let valid_flags = vec!["-v", "--version"];
|
||||
|
||||
for arg in args {
|
||||
for valid_flag in &valid_flags {
|
||||
if valid_flag == arg {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
Reference in New Issue
Block a user