Last active
July 25, 2021 13:29
-
-
Save komori-n/f2af10496f220ec89619a6aebb227513 to your computer and use it in GitHub Desktop.
nananiji-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
use anyhow::Context as _; | |
use anyhow::Result; | |
use chrono::{FixedOffset, TimeZone, Utc}; | |
use lambda_runtime::{error::HandlerError, lambda, Context}; | |
use log::info; | |
use reqwest::{blocking::Client, header::CONTENT_TYPE}; | |
use serde::{Deserialize, Serialize}; | |
const NANANIJI_GENERATOR_URL: &'static str = | |
"https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/beta/"; | |
const CONSUMER_TOKEN_KEY: &'static str = "XXXXXXXXXXXXXXX"; | |
const CONSUMER_TOKEN_SECRET: &'static str = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; | |
const ACCESS_KEY: &'static str = "XXXXXXXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXXX"; | |
const ACCESS_SECRET: &'static str = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; | |
// anyhow = "1.0" | |
// clap = "2.33" | |
// log = "0.4" | |
// env_logger = "0.8" | |
// lambda_runtime = "0.2" | |
// serde = {version = "1.0", features = ["derive"]} | |
// serde_json = "1.0" | |
// chrono = "0.4" | |
// reqwest = { version = "0.11", default-features = false, features = ["rustls-tls", "blocking"]} | |
// egg-mode = { version = "0.16", features = ["rustls"], default-features = false } | |
// tokio = {version = "1.8", features = ["full"]} | |
#[derive(Serialize, Deserialize, Clone, Copy, Debug)] | |
#[serde(tag = "name", content = "split", rename_all = "lowercase")] | |
enum ListName { | |
Nananiji, | |
Hanshin(bool), | |
Kyojin(bool), | |
} | |
#[derive(Serialize, Deserialize, Clone, Debug)] | |
struct CalculationRequest { | |
value: String, | |
list_name: ListName, | |
} | |
#[derive(Deserialize, Clone)] | |
struct RequestResult { | |
expr: String, | |
} | |
#[derive(Deserialize, Clone, Debug)] | |
struct Request {} | |
fn main() -> Result<()> { | |
env_logger::init(); | |
lambda!(move |_: Request, _ctx: Context| handler()); | |
Ok(()) | |
} | |
fn handler() -> Result<(), HandlerError> { | |
// todo log req | |
let num = date_number() | |
.with_context(|| "Could not parse date number") | |
.unwrap(); | |
let calc_req = CalculationRequest { | |
value: num.clone(), | |
list_name: ListName::Nananiji, | |
}; | |
let decomposite_ans = calculate(&calc_req) | |
.with_context(|| "Could not calculate") | |
.unwrap(); | |
info!("ans: {}", decomposite_ans); | |
let tweet_text = format!("{} \n={} #nananiji_generator", num, decomposite_ans); | |
info!("tweet_text: {}", tweet_text); | |
tweet(tweet_text); | |
Ok(()) | |
} | |
fn date_number() -> Result<String> { | |
let utc_time = Utc::now(); | |
let japan_date = FixedOffset::east(9 * 3600) | |
.from_utc_datetime(&utc_time.naive_utc()) | |
.date(); | |
let ret = japan_date.format("%Y%m%d").to_string(); | |
Ok(ret) | |
} | |
fn calculate(req: &CalculationRequest) -> Result<String> { | |
let client = Client::new(); | |
let res = client | |
.post(NANANIJI_GENERATOR_URL) | |
.body(serde_json::to_string(req)?) | |
.header(CONTENT_TYPE, "application/json") | |
.send()?; | |
let ans: RequestResult = serde_json::from_str(&res.text()?)?; | |
Ok(ans.expr) | |
} | |
fn tweet(tweet_str: String) { | |
tokio::runtime::Builder::new_multi_thread() | |
.enable_all() | |
.build() | |
.unwrap() | |
.block_on(async { | |
let con_token = egg_mode::KeyPair::new(CONSUMER_TOKEN_KEY, CONSUMER_TOKEN_SECRET); | |
let access = egg_mode::KeyPair::new(ACCESS_KEY, ACCESS_SECRET); | |
let access_token = egg_mode::auth::Token::Access { | |
consumer: con_token, | |
access, | |
}; | |
// Because `DraftTweet` struct requires a static-lifetime reference (I'm not sure of the reason), | |
// leak the storage intentionally. This operation might be dangerous. | |
let static_str: &'static str = Box::leak(tweet_str.into_boxed_str()); | |
egg_mode::tweet::DraftTweet::new(static_str) | |
.send(&access_token) | |
.await | |
.unwrap(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment