diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c49ce9b26740d535da19b67423e7dcae18927daf
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,17 @@
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
+Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
+
+#exclude the config file
+config.json
diff --git a/Cargo.toml b/Cargo.toml
index 47a92ae04b5441c3cf25744cbe98e8e9a603f359..3ec3e0c6e5e2310e266d7f76f9162c5d308e2573 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,10 @@ edition = "2021"
 
 [dependencies]
 fantoccini = "0.18.0"
-scraper = "0.12.0"
+penguin-config = "0.1.1"
+serde = "1.0.136"
 tokio = { version = "1", features = ["full"] }
-lettre = "0.9"
-lettre_email = "0.9"
+lettre = { version = "0.10.0-rc.4", features = [
+  "smtp-transport",
+  "native-tls",
+] }
diff --git a/config.json.defaut b/config.json.defaut
new file mode 100644
index 0000000000000000000000000000000000000000..20d9b502c4b2fc1a8b5ab45e0b73d200eb463e4e
--- /dev/null
+++ b/config.json.defaut
@@ -0,0 +1 @@
+{"smtp_host":"","smtp_user":"","smtp_pass":"","smtp_from":"","filters":[],"recipients":[]}
diff --git a/src/main.rs b/src/main.rs
index 94ab335196c40e734f2c256b569c1b591745cafc..65329c9226df03438a1174e49658a82d2f3427df 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,41 +1,62 @@
 use fantoccini::error::CmdError;
 use fantoccini::{ClientBuilder, Locator};
+use lettre::transport::smtp::authentication::{Credentials, Mechanism};
+use lettre::{Message, SmtpTransport, Transport};
+use penguin_config::*;
+use std::process::Command;
+
+struct Product {
+    name: String,
+    price: String,
+    available: bool,
+}
+
+#[derive(Deserialize, PenguinConfigFile, Default)]
+#[penguin_config(path = "config.json")]
+struct Config {
+    smtp_host: String,
+    smtp_user: String,
+    smtp_pass: String,
+    smtp_from: String,
+    filters: Vec<String>,
+    recipients: Vec<String>,
+}
 
 #[tokio::main]
 async fn main() {
-    let filters = vec!["RX 6800", "RX 6700"];
-
-    loop {
-        let products = get_html_products().await.unwrap();
-
-        let filtered: Vec<Product> = products
-            .into_iter()
-            .filter(|el| {
-                for s in &filters {
-                    if el.name.contains(s) {
-                        return el.available;
-                    }
+    let config = Config::read_config();
+    let filters = config.filters;
+
+    let products = get_html_products().await.unwrap();
+
+    let filtered: Vec<Product> = products
+        .into_iter()
+        .filter(|el| {
+            for s in &filters {
+                if el.name.contains(s) {
+                    return el.available;
                 }
-                false
-            })
-            .collect();
-
-        if filtered.len() > 0 {
-            println!("The following products are available");
-        } else {
-            println!("Sorry, all products are out of stock. :/");
-        }
-    }
-}
+            }
+            false
+        })
+        .collect();
 
-#[derive(Debug)]
-pub struct Product {
-    name: String,
-    price: String,
-    available: bool,
+    if filtered.len() > 0 {
+        println!("Found {} products.\nSending mail.", filtered.len());
+        send_email(filtered);
+    } else {
+        println!("Sorry, all products are out of stock. :/");
+    }
 }
 
 async fn get_html_products() -> Result<Vec<Product>, CmdError> {
+    // start the geckodriver
+    let mut geckodriver = Command::new("sh")
+        .arg("-c")
+        .arg("./geckodriver")
+        .spawn()
+        .expect("sh command failed to start geckodriver");
+
     // navigate to amd-site
     let mut webc = ClientBuilder::native()
         .connect("http://localhost:4444")
@@ -71,5 +92,43 @@ async fn get_html_products() -> Result<Vec<Product>, CmdError> {
     webc.close()
         .await
         .expect("Failed to terminate webdriver sessions");
+
+    // stop the geckodriver
+    geckodriver.kill().expect("Failed to kill geckodriver!");
     return Ok(products);
 }
+
+fn send_email(config: Config, products: Vec<Product>) -> () {
+    let mut message = String::from(
+        "The following products are available at: https://www.amd.com/de/direct-buy \n\n",
+    );
+    for product in products {
+        message.push_str(format!(" - {}, Price: {}\n", product.name, product.price).as_str());
+    }
+
+    for recipient in config.recipients {
+        let mail = Message::builder()
+            .from(
+                config
+                    .smtp_from
+                    .parse()
+                    .expect(format!("From address: {} is invalid", config.smtp_from).as_str()),
+            )
+            .to(recipient
+                .parse()
+                .expect(format!("To adress: {} is invalid", recipient).as_str()))
+            .subject("Products are available at the AMD website")
+            .body(message)
+            .expect("Failed to construct email message");
+
+        let creds = Credentials::new(config.smtp_user, config.smtp_pass);
+        let mailer = SmtpTransport::relay(&config.smtp_host)
+            .expect("Failed to connect to mailerver")
+            .credentials(creds)
+            .authentication(vec![Mechanism::Plain])
+            .build();
+
+        mailer.send(&mail).expect("Error sending mail");
+        println!("Mail was send to {}.", recipient);
+    }
+}