Last active
June 11, 2018 05:56
-
-
Save lae/1913ddb414cef48ef5b6711fb5c5a531 to your computer and use it in GitHub Desktop.
lootcoin price bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern crate reqwest; | |
extern crate scraper; | |
extern crate egg_mode; | |
#[macro_use] | |
extern crate serde_derive; | |
extern crate serde; | |
extern crate toml; | |
extern crate tokio_core; | |
extern crate chrono; | |
use std::{thread, time}; | |
use egg_mode::{KeyPair, Token, tweet}; | |
use tokio_core::reactor::Core; | |
use chrono::prelude::*; | |
use scraper::{Selector, Html}; | |
mod util; | |
use util::Auth; | |
fn main() { | |
let auth; | |
match Auth::from_file("twitter_config.toml") { | |
Ok(a) => auth = a, | |
Err(e) => { | |
println!("Couldn't import auth credentials."); | |
println!("{:?}", e); | |
std::process::exit(1); | |
} | |
} | |
// Authenticate with Twitter | |
let access_token = KeyPair::new(auth.access_key, auth.access_sec); | |
let con_token = KeyPair::new(auth.con_key, auth.con_sec); | |
let token = Token::Access { | |
consumer: con_token, | |
access: access_token, | |
}; | |
let mut core = Core::new().unwrap(); | |
let handle = core.handle(); | |
let a_minute = time::Duration::from_secs(60); | |
loop { | |
let body = reqwest::get("http://devolverdigital.limitedrun.com/products/619738/").unwrap().text().unwrap(); | |
let selector = Selector::parse(r#"select[id="cart_variation_id_for_619738"] option"#).unwrap(); | |
let document = Html::parse_document(&body); | |
let option = document.select(&selector).next().unwrap(); | |
let text = option.text().collect::<Vec<_>>()[0]; | |
// split at spaces and get last "word" in the option content | |
let current_price = text.rsplit(' ').collect::<Vec<_>>()[0]; | |
let dt = Local::now(); | |
let message = format!("{} - Lootbox Coin Price is now {}.", dt.format("%Y.%m.%d %H:%M"), ¤t_price); | |
// get last tweet from our account | |
let user = tweet::user_timeline(1006033366401945600, true, true, &token, | |
&handle).with_page_size(1); | |
let (_user, feed) = core.run(user.start()).unwrap(); | |
// parse out the last price from that tweet | |
let mut last_price = feed[0].text.rsplit(' ').collect::<Vec<_>>()[0].to_string(); | |
last_price.pop(); // remove trailing period | |
// post new tweet if price differs | |
if current_price != last_price { | |
let _ = core.run(tweet::DraftTweet::new(&message).send(&token, &handle)).unwrap(); | |
println!(r#"Posted new tweet "{}""#, &message); | |
} | |
thread::sleep(a_minute); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
access_key = "" | |
access_sec = "" | |
con_key = "" | |
con_sec = "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::io; | |
use std::fs::File; | |
use toml; | |
#[derive(Deserialize, Debug)] | |
pub struct Auth { | |
pub access_key: String, | |
pub access_sec: String, | |
pub con_key: String, | |
pub con_sec: String, | |
} | |
impl Auth { | |
/// Parse twitter auth credentials from toml file | |
pub fn from_file(path: &str) -> Result<Auth, Error> { | |
use std::io::prelude::*; | |
let mut file = File::open(path)?; | |
let mut buf = String::with_capacity(200); | |
file.read_to_string(&mut buf)?; | |
let auth: Self = toml::from_str(&buf)?; | |
Ok(auth) | |
} | |
} | |
#[derive(Debug)] | |
pub enum Error { | |
IoError(io::Error), | |
ParseError(toml::de::Error), | |
} | |
impl From<io::Error> for Error { | |
fn from(err: io::Error) -> Error { | |
Error::IoError(err) | |
} | |
} | |
impl From<toml::de::Error> for Error { | |
fn from(err: toml::de::Error) -> Error { | |
Error::ParseError(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment