Skip to content

Commit

Permalink
Add bitcoin command
Browse files Browse the repository at this point in the history
  • Loading branch information
MedAouadhi committed Feb 5, 2024
1 parent a4dfc2a commit 7b99f4c
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 10 deletions.
13 changes: 12 additions & 1 deletion src/bot_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@ use bot_commands_macro::{bot_commands, handler};
pub mod commands {

use super::*;
use polybot::services::coinmarketcap::Coinmarket;
use polybot::services::llm::{Agent, OpenAiModel};
use polybot::services::openmeteo::OpenMeteo;
use polybot::types::{BotUserActions, WeatherProvider};
use polybot::utils::{get_affirmation, get_ip};
use polybot::utils::{get_affirmation, get_config, get_ip};
use rand::Rng;
use std::io::Cursor;

#[handler(cmd = "/bitcoin")]
async fn get_bitcoin(_user_tx: impl BotUserActions, _: String) -> String {
let config = get_config("config.toml").await.unwrap();
let market = Coinmarket::new(config.bot.coinmarket_token);
if let Ok(price) = market.get_bitcoin_price().await {
return format!("{:.3} €", price);
}
"Error getting the bitcoin price".to_string()
}

#[handler(cmd = "/ip")]
async fn ip(_user_tx: impl BotUserActions, _: String) -> String {
if let Ok(ip) = get_ip().await {
Expand Down
1 change: 1 addition & 0 deletions src/lib/polybot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use tokio::select;
use tokio::sync::Notify;
use tracing::{debug, error, info};


pub struct Polybot<B: Bot> {
bot: Arc<B>,
config: Config,
Expand Down
121 changes: 121 additions & 0 deletions src/lib/services/coinmarketcap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use anyhow::Ok;
use chrono::{DateTime, Utc};
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT};
use serde::Deserialize;

#[allow(unused)]
#[derive(Deserialize, Debug)]
struct Status {
timestamp: DateTime<Utc>,
error_code: u32,
error_message: Option<String>,
elapsed: u32,
credit_count: u32,
notice: Option<String>,
}

#[allow(unused)]
#[derive(Deserialize, Debug)]
struct CurrencyQuote {
price: f64,
volume_24h: f64,
volume_24h_reported: f64,
volume_7d: f64,
volume_7d_reported: f64,
volume_30d: f64,
volume_30d_reported: f64,
volume_change_24h: f64,
percent_change_1h: f64,
percent_change_24h: f64,
percent_change_7d: f64,
percent_change_30d: f64,
percent_change_60d: f64,
percent_change_90d: f64,
market_cap: f64,
market_cap_dominance: f64,
fully_diluted_market_cap: f64,
tvl: Option<String>,
last_updated: DateTime<Utc>,
}

#[allow(unused)]
#[derive(Deserialize, Debug)]
struct Currencies {
#[serde(rename(deserialize = "EUR"))]
currency: CurrencyQuote,
}

#[allow(unused)]
#[derive(Deserialize, Debug)]
struct Data {
id: u32,
name: String,
symbol: String,
slug: String,
date_added: DateTime<Utc>,
circulating_supply: u32,
infinite_supply: bool,
self_reported_circulating_supply: Option<u32>,
self_reported_market_cap: Option<f64>,
tvl_ratio: Option<f64>,
last_updated: DateTime<Utc>,
quote: Currencies,
}

#[allow(unused)]
#[derive(Deserialize, Debug)]
struct CoinEntry {
#[serde(rename(deserialize = "BTC"))]
symbol: Vec<Data>,
}

#[allow(unused)]
#[derive(Deserialize, Debug)]
struct BitcoinData {
status: Status,
data: CoinEntry,
}

/// BitcoinRequest
pub struct Coinmarket {
api_key: String,
client: reqwest::Client,
}

impl Coinmarket {
pub fn new(api_key: String) -> Self {
Self {
api_key,
client: reqwest::Client::new(),
}
}

pub async fn get_bitcoin_price(&self) -> anyhow::Result<f64> {
let mut headers = HeaderMap::new();
headers.insert("X-CMC_PRO_API_KEY", HeaderValue::from_str(&self.api_key)?);
headers.insert(ACCEPT, HeaderValue::from_static("application/json"));

// Define the query parameters
let params = [
("symbol", "BTC"),
("convert", "EUR"),
("aux", "date_added,circulating_supply,volume_24h_reported,volume_7d,volume_7d_reported,volume_30d,volume_30d_reported"),
];

let resp = self
.client
.get("https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest")
.headers(headers)
.query(&params)
.send()
.await?
.text()
.await?;

let data: BitcoinData =
serde_json::from_str(&resp).expect("problem with getting bitcoin data");

tracing::debug!("bitcoin data: {:#?}", data);
Ok(data.data.symbol[0].quote.currency.price)
}
}
1 change: 1 addition & 0 deletions src/lib/services/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod coinmarketcap;
pub mod llm;
pub mod openmeteo;
1 change: 1 addition & 0 deletions src/lib/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct BotConfig {
pub token: String,
pub chat_id: String,
pub db_token: String,
pub coinmarket_token: String,
}

#[derive(Deserialize, Debug, Clone)]
Expand Down
21 changes: 12 additions & 9 deletions src/lib/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,18 @@ mod tests {
let dir = tempdir().unwrap();
let config_path = dir.path().join("config.toml");
let data = toml::toml! {
[bot]
name = "dummy"
token = "dummytoken"

[server]
ip = "0.0.0.0"
port = 4443
privkeyfile = "YOURPRIVATE.key"
pubkeyfile = "YOURPUBLIC.pem"
[bot]
name = "dummy"
token = "tokendummy"
chat_id = "122433"
db_token = "tokendb"
coinmarket_token = "cointoken"

[server]
ip = "0.0.0.0"
port = 4443
privkeyfile = "YOURPRIVATE.key"
pubkeyfile = "YOURPUBLIC.pem"
};

fs::write(&config_path, data.to_string()).await.unwrap();
Expand Down

0 comments on commit 7b99f4c

Please sign in to comment.