Skip to content

Instantly share code, notes, and snippets.

@lae
Last active June 11, 2018 05:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lae/1913ddb414cef48ef5b6711fb5c5a531 to your computer and use it in GitHub Desktop.
Save lae/1913ddb414cef48ef5b6711fb5c5a531 to your computer and use it in GitHub Desktop.
lootcoin price bot
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"), &current_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);
}
}
access_key = ""
access_sec = ""
con_key = ""
con_sec = ""
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