Skip to content

Instantly share code, notes, and snippets.

@samoylovfp
Created May 24, 2017 20:32
Show Gist options
  • Save samoylovfp/a0a4bf7264b3633e1119d869468364f6 to your computer and use it in GitHub Desktop.
Save samoylovfp/a0a4bf7264b3633e1119d869468364f6 to your computer and use it in GitHub Desktop.
extern crate reqwest;
extern crate serde;
extern crate rand;
#[macro_use]
extern crate serde_json;
#[macro_use]
extern crate serde_derive;
use std::{thread, time};
use rand::Rng;
#[derive(Deserialize, Debug)]
struct Chat {
id: i64
}
#[derive(Deserialize, Debug)]
struct Message {
chat: Chat,
text: Option<String>,
message_id: u64
}
#[derive(Deserialize, Debug)]
struct SendMessageResponse {
result: Message
}
#[derive(Deserialize, Debug)]
struct Update {
message: Message,
update_id: u64
}
#[derive(Deserialize, Debug)]
struct UpdatesResponse {
result: Vec<serde_json::Value>
}
fn read_token() -> String {
use std::fs::File;
use std::io::prelude::*;
let mut contents = String::new();
File::open("key.txt").expect("No key file")
.read_to_string(&mut contents).expect("Cant read key");
contents
}
fn method_url(token: &str, method_name: &str) -> String {
format!("https://api.telegram.org/bot{}/{}", token, method_name).into()
}
fn request_updates(offset: &mut Option<u64>, token: &String) -> Vec<Message> {
let mut params = json!({
//"allowed_updates": ["message"],
"timeout": 30
});
if let Some(offset) = *offset {
params.as_object_mut().unwrap().insert(
"offset".into(),
(offset + 1).into());
};
let client = reqwest::Client::new().unwrap();
let response: UpdatesResponse = match
client.post(&method_url(token, "getUpdates"))
.json(&params)
.send().and_then(|mut r|r.json()) {
Ok(response) => response,
Err(e) => {
println!("Error requesting updates:{:?}", e);
return vec![]
}
};
let mut result = vec![];
for update in response.result {
match serde_json::from_value::<Update>(update.clone()) {
Ok(upd) => {
*offset = Some(std::cmp::max(offset.unwrap_or(0), upd.update_id));
result.push(upd.message);
},
Err(e) => {
println!("Error parsing update: {} {}", e, update);
}
}
}
result
}
fn send_message(message: &Message, text: &str, token: &str) -> Option<Message> {
let client = reqwest::Client::new().unwrap();
let response: Result<SendMessageResponse, _> = client.post(&method_url(token, "sendMessage"))
.json(&json!({
"text": text,
"chat_id": message.chat.id,
"parse_mode": "Markdown"
})).send().and_then(|mut r|r.json());
response.ok().map(|r|r.result)
}
fn edit_message(message: &Message, text: &str, token: &str) {
let client = reqwest::Client::new().unwrap();
let result: Result<serde_json::Value, _> = client.post(&method_url(token, "editMessageText"))
.json(&json!({
"text": text,
"chat_id": message.chat.id,
"message_id": message.message_id,
"parse_mode": "Markdown"
})).send().and_then(|mut r|r.json());
println!("Edited message to {}: {:?}", &text, result);
}
fn react(message: &Message, token: &str ) {
let tkn = String::from(token);
if message.text.is_none() {
return;
}
if message.text.as_ref().unwrap().contains("/wink") {
if let Some(sent_message) = send_message(message, "`-_-`", &tkn) {
println!("Sent message: {:?}", sent_message);
thread::spawn(move || {
let mut rng = rand::thread_rng();
loop {
let default_eye = "O";
let eyes = ["0", "o", "O", "()"];
let face;
{
let mut random_eye = || rng.choose(&eyes).unwrap_or(&default_eye);
face = format!("`{}_{}`", random_eye(), random_eye());
}
edit_message(&sent_message, &face, &tkn);
thread::sleep(time::Duration::from_secs(rng.gen_range(1, 10)));
edit_message(&sent_message, "`-_-`", &tkn);
thread::sleep(time::Duration::from_millis(500));
}
});
}
else {
println!("Cound not send message");
return
}
}
}
fn main() {
let mut offset = None;
let token = read_token();
loop {
let messages = request_updates(&mut offset, &token);
println!("Got updates: {:?}", messages);
for message in messages {
react(&message, &token);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment