70 %
Chris Biscardi

Processing realtime tweets from twitter in Rust

We're going to follow the #100DaysofProjects hashtag on twitter so we can keep up with all the cool projects people are working on.

We need to use egg_mode, futures, and the tokio runtime.

async main

egg_mode uses streams and futures to pull in the tweets so we need to make our main function an async one. Note that when we do this Rust won't be able to find our main, so we also need to make use of Tokio's main macro.

rust
#[tokio::main]
async fn main() {
...
}

envy

We'll also take advantage of envy to handle environment variable configuration using a derive macro on our struct of env vars:

rust
#[derive(Deserialize, Debug)]
struct Config {
consumer_key: String,
consumer_secret: String,
access_token: String,
access_token_secret: String,
}

and the actual envy call, which panics if we can't get the env vars.

rust
let config = match envy::from_env::<Config>() {
Ok(config) => config,
Err(error) => panic!("{:#?}", error),
};

Full Program

rust
use egg_mode::error::Result;
use egg_mode::stream::{filter, StreamMessage};
use futures::TryStreamExt;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Config {
consumer_key: String,
consumer_secret: String,
access_token: String,
access_token_secret: String,
}
#[tokio::main]
async fn main() {
let config = match envy::from_env::<Config>() {
Ok(config) => config,
Err(error) => panic!("{:#?}", error),
};
let con_token = egg_mode::KeyPair::new(config.consumer_key, config.consumer_secret);
let access_token = egg_mode::KeyPair::new(config.access_token, config.access_token_secret);
let token = egg_mode::Token::Access {
consumer: con_token,
access: access_token,
};
let stream = filter()
.track(&["100daysofprojects"])
.start(&token);
let mut i = 0;
stream
.try_for_each(|m| {
if let StreamMessage::Tweet(tweet) = m {
i = i + 1;
println!(
"------------------------------------\n{} @{} {} {} {}",
i,
tweet.user.unwrap().screen_name,
tweet.id,
tweet.created_at,
tweet.text
);
}
futures::future::ok(())
})
.await
.expect("Stream error");
}