forked from rust-lang-by/rust-bot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrust_mention_handler.rs
113 lines (102 loc) · 3.57 KB
/
rust_mention_handler.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use chrono::{DateTime, Duration, NaiveDateTime, TimeZone, Utc};
use log::{error, info};
use sqlx::PgPool;
use teloxide::prelude::*;
use teloxide::types::MessageKind::Common;
use teloxide::types::{InputFile, MessageCommon, MessageId, User};
use crate::mention_repository;
const STICKERS: &[&str; 5] = &[
"CAACAgEAAx0CTdy33AAD3mQO6sc3rzklybqG4MMI4MLXpXJIAAKCAQACaXoxBT0NGBN6KJNELwQ",
"CAACAgEAAx0CTdy33AACAQFkF6KoodtDg4KfcPHlUk_7SRFN7QACkQEAAml6MQW86C1JCZcTkS8E",
"CAACAgEAAx0CTdy33AACAQxkF6Mu7nPaIs9rmMBfXs71BBPxfgACnAEAAml6MQVkU_PxsG8GmS8E",
"CAACAgEAAx0CTdy33AACARFkF6RG5xa8L2rn6ENe3NsMktY7GgACaQEAAml6MQWdvTv0FuDgLC8E",
"CAACAgEAAx0CTdy33AACARNkF6SmiAABryW7RcGozvQDCys7JNUAAlcBAAJpejEFk0uf6g86yKAvBA",
];
const HOURS_PER_DAY: i64 = 24;
const MINUTES_PER_HOUR: i64 = 60;
pub async fn handle_rust_matched_mention(
bot: Bot,
message: Message,
db_pool: PgPool,
req_time_diff: Duration,
) {
let message_date = message.date.timestamp();
let curr_native_date = NaiveDateTime::from_timestamp_opt(message_date, 0).unwrap();
let curr_date: DateTime<Utc> = DateTime::from_utc(curr_native_date, Utc);
info!("mention time: {}", curr_date);
if let Common(MessageCommon {
from:
Some(User {
id: user_id,
username: Some(username),
..
}),
..
}) = message.kind
{
// pool the latest mention time from db
let last_mention_time =
mention_repository::lead_earliest_mention_time(&db_pool, message.chat.id.0).await;
let last_update_time = Utc.from_utc_datetime(&last_mention_time);
info!("latest update time: {}", last_update_time);
let time_diff = curr_date.signed_duration_since(last_update_time);
if time_diff > req_time_diff {
let message_ids = (message.id, message.chat.id, message.thread_id.unwrap_or(0));
send_rust_mention_response(bot, message_ids, time_diff, &username).await;
}
mention_repository::insert_mention(
&db_pool,
user_id.0 as i64,
&username,
message
.thread_id
.map_or_else(|| message.chat.id.0, |id| id as i64),
)
.await;
}
}
async fn send_rust_mention_response(
bot: Bot,
message_ids: (MessageId, ChatId, i32),
time_diff: Duration,
username: &str,
) {
bot.send_message(
message_ids.1,
format!(
"Hi, {}! You just wrote smth about Rust! \nBe careful, \
{}d:{}h:{}m since last incident.",
username,
time_diff.num_days(),
time_diff.num_hours() % HOURS_PER_DAY,
time_diff.num_minutes() % MINUTES_PER_HOUR
),
)
.message_thread_id(message_ids.2)
.reply_to_message_id(message_ids.0)
.await
.map_err(|err| error!("Can't send reply: {:?}", err))
.ok();
bot.send_sticker(
message_ids.1,
InputFile::file_id(fetch_sticker_id(time_diff)),
)
.message_thread_id(message_ids.2)
.await
.map_err(|err| error!("Can't send a sticker: {:?}", err))
.ok();
}
pub fn fetch_sticker_id(time_diff: Duration) -> &'static str {
let sticker_index = time_diff.num_minutes().rem_euclid(STICKERS.len() as i64) as usize;
STICKERS[sticker_index]
}
#[cfg(test)]
mod tests {
use crate::rust_mention_handler::{fetch_sticker_id, STICKERS};
use chrono::Duration;
#[test]
fn test_fetch_sticker_id() {
let sticker_id = fetch_sticker_id(Duration::minutes(7));
assert_eq!(sticker_id, STICKERS[2]);
}
}