feat: add basic lastfm command

This commit is contained in:
notohh 2024-06-16 07:15:54 -04:00
parent 7c1578e99a
commit 30eb512aca
Signed by: notohh
GPG key ID: BD47506D475EE86D
5 changed files with 123 additions and 2 deletions

2
Cargo.lock generated
View file

@ -89,6 +89,8 @@ dependencies = [
"dotenv", "dotenv",
"pretty_env_logger", "pretty_env_logger",
"reqwest", "reqwest",
"serde",
"serde_json",
"sysinfo", "sysinfo",
"tokio", "tokio",
"twitch-irc", "twitch-irc",

View file

@ -7,6 +7,8 @@ edition = "2021"
dotenv = "0.15.0" dotenv = "0.15.0"
pretty_env_logger = "0.5.0" pretty_env_logger = "0.5.0"
reqwest = { version = "0.12.4", features = ["json"] } reqwest = { version = "0.12.4", features = ["json"] }
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
sysinfo = "0.30.12" sysinfo = "0.30.12"
tokio = { version = "1.37.0", features = ["full"] } tokio = { version = "1.37.0", features = ["full"] }
twitch-irc = "5.0.1" twitch-irc = "5.0.1"

116
src/commands/lastfm.rs Normal file
View file

@ -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),
}
}

View file

@ -1,2 +1,3 @@
pub mod lastfm;
pub mod ping; pub mod ping;
pub mod test; pub mod test;

View file

@ -1,5 +1,5 @@
use commands::lastfm::lastfm_command;
use commands::ping::ping_command; use commands::ping::ping_command;
use commands::test::test_command;
use std::collections::HashMap; use std::collections::HashMap;
use client::client; use client::client;
@ -36,7 +36,7 @@ pub async fn main() {
if msg.sender.name == "notohh" { if msg.sender.name == "notohh" {
match msg.message_text.as_str() { match msg.message_text.as_str() {
"*ping" => ping_command(&msg, &client).await, "*ping" => ping_command(&msg, &client).await,
"*test" => test_command(&msg, &client).await, "*song" => lastfm_command(&msg, &client).await,
_ => {} _ => {}
} }
} }