diff --git a/Cargo.lock b/Cargo.lock
index 8698962..e102cab 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -89,6 +89,8 @@ dependencies = [
  "dotenv",
  "pretty_env_logger",
  "reqwest",
+ "serde",
+ "serde_json",
  "sysinfo",
  "tokio",
  "twitch-irc",
diff --git a/Cargo.toml b/Cargo.toml
index 9360878..4b66e1e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,6 +7,8 @@ edition = "2021"
 dotenv = "0.15.0"
 pretty_env_logger = "0.5.0"
 reqwest = { version = "0.12.4", features = ["json"] }
+serde = { version = "1.0.203", features = ["derive"] }
+serde_json = "1.0.117"
 sysinfo = "0.30.12"
 tokio = { version = "1.37.0", features = ["full"] }
 twitch-irc = "5.0.1"
diff --git a/src/commands/lastfm.rs b/src/commands/lastfm.rs
new file mode 100644
index 0000000..c224471
--- /dev/null
+++ b/src/commands/lastfm.rs
@@ -0,0 +1,116 @@
+use crate::client::TwitchClient;
+use dotenv::dotenv;
+use serde::{Deserialize, Serialize};
+use std::env;
+
+use twitch_irc::message::PrivmsgMessage;
+
+#[derive(Debug, Serialize, Deserialize)]
+struct Data {
+    recenttracks: Recenttracks,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct Image {
+    size: String,
+    #[serde(rename = "#text")]
+    text: String,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+struct Registered {
+    unixtime: String,
+    #[serde(rename = "#text")]
+    text: i64,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Recenttracks {
+    track: Vec<Track>,
+    #[serde(rename = "@attr")]
+    attr: Attr,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct Attr {
+    user: String,
+    total_pages: String,
+    page: String,
+    per_page: String,
+    total: String,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Track {
+    artist: Album,
+    streamable: String,
+    image: Vec<Image>,
+    mbid: String,
+    album: Album,
+    name: String,
+    url: String,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Album {
+    mbid: String,
+    #[serde(rename = "#text")]
+    text: String,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Date {
+    uts: String,
+    #[serde(rename = "#text")]
+    text: String,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum Size {
+    Extralarge,
+    Large,
+    Medium,
+    Small,
+}
+
+pub async fn lastfm_command(m: &PrivmsgMessage, c: &TwitchClient) {
+    dotenv().ok();
+
+    let lastfm_api_key = env::var("LASTFM_API_KEY").expect("Failed to load lastfm api key.");
+    let user = "notoh";
+
+    let recent_tracks_url = format!(
+        "http://ws.audioscrobbler.com/2.0/?method=user.getRecentTracks&user={}&api_key={}&format=json&nowplaying=true", user,
+        lastfm_api_key
+    );
+
+    let client = reqwest::Client::new();
+
+    match client.get(recent_tracks_url).send().await {
+        Ok(response) => {
+            if response.status().is_success() {
+                let body = response.text().await.unwrap();
+                match serde_json::from_str::<Data>(&body) {
+                    Ok(payload) => {
+                        if let Some(tracks) = payload.recenttracks.track.first() {
+                            let s = format!(
+                                "Listening to: {} - {} {}",
+                                tracks.name, tracks.artist.text, tracks.url
+                            );
+                            c.twitch_client
+                                .say(m.channel_login.to_owned(), s.to_owned())
+                                .await
+                                .expect("Error sending message to twitch");
+                        }
+                    }
+                    Err(e) => eprintln!("{}", e),
+                }
+            } else {
+                println!("Response error: {}", response.status());
+            }
+        }
+        Err(e) => eprintln!("Error sending request: {}", e),
+    }
+}
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index f458a8d..f88abee 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -1,2 +1,3 @@
+pub mod lastfm;
 pub mod ping;
 pub mod test;
diff --git a/src/main.rs b/src/main.rs
index 82bfbff..188412e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,5 @@
+use commands::lastfm::lastfm_command;
 use commands::ping::ping_command;
-use commands::test::test_command;
 use std::collections::HashMap;
 
 use client::client;
@@ -36,7 +36,7 @@ pub async fn main() {
                     if msg.sender.name == "notohh" {
                         match msg.message_text.as_str() {
                             "*ping" => ping_command(&msg, &client).await,
-                            "*test" => test_command(&msg, &client).await,
+                            "*song" => lastfm_command(&msg, &client).await,
                             _ => {}
                         }
                     }