feat: initial version
features: - add, new, choose commands - index message and weekend messages generation on the fly - loading/saving index from data.json file - basic conversation
This commit is contained in:
parent
fa17f8bb1c
commit
9253a14fa2
|
@ -1,3 +1,6 @@
|
||||||
|
.env
|
||||||
|
data.json
|
||||||
|
|
||||||
# ---> Rust
|
# ---> Rust
|
||||||
# Generated by Cargo
|
# Generated by Cargo
|
||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
|
@ -10,3 +13,8 @@ Cargo.lock
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Added by cargo
|
||||||
|
|
||||||
|
/target
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
[package]
|
||||||
|
name = "index_bot"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
teloxide = { version = "0.12", features = ["macros"] }
|
||||||
|
tokio = { version = "1.8", features = ["rt-multi-thread", "macros"] }
|
||||||
|
url = "2.3"
|
||||||
|
chrono = { version = "0.4.31", features = ["serde"] }
|
||||||
|
serde = "1.0.193"
|
||||||
|
serde_with = "3.4.0"
|
||||||
|
serde_json = "1.0.108"
|
||||||
|
dotenv = "0.15.0"
|
||||||
|
dotenv_codegen = "0.15.0"
|
10
README.md
10
README.md
|
@ -1,2 +1,12 @@
|
||||||
# index_bot
|
# index_bot
|
||||||
|
|
||||||
|
Telegram bot to index messages for events of any kind and post them in a telegram channel.
|
||||||
|
|
||||||
|
⚠️ This software erases any content in `data.json` file in the folder it's ran. This file is used for storage.
|
||||||
|
|
||||||
|
please populate `.env` file as follow:
|
||||||
|
```
|
||||||
|
BOT_API_TOKEN=123456789:abcdefghijklmnopqrstuvwxyz
|
||||||
|
CHANNEL_ID=-100123456789
|
||||||
|
ADMIN_ID=123456789
|
||||||
|
```
|
|
@ -0,0 +1,482 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate dotenv_codegen;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::fmt;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fs::{OpenOptions, File};
|
||||||
|
use std::io::{BufWriter, Write, BufReader};
|
||||||
|
use serde::{ Serialize, Deserialize };
|
||||||
|
use serde_with::serde_as;
|
||||||
|
use serde_json;
|
||||||
|
use chrono::{ NaiveDate, Weekday, Datelike, Days };
|
||||||
|
use chrono::offset::Local;
|
||||||
|
use url::Url;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use teloxide::{prelude::*, types::MessageEntity, types::MessageId};
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
enum Kind {
|
||||||
|
None,
|
||||||
|
Text,
|
||||||
|
Fly,
|
||||||
|
TextFly,
|
||||||
|
_Gps,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
enum State {
|
||||||
|
Base,
|
||||||
|
New,
|
||||||
|
Add,
|
||||||
|
_Del
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Kind {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Kind::None => write!(f, "💀 error 💀"),
|
||||||
|
Kind::Text => write!(f, "ℹ info ℹ️"),
|
||||||
|
Kind::Fly => write!(f, "🖼️ fly 🖼️"),
|
||||||
|
Kind::TextFly => write!(f, "😳 fly+info 😳"),
|
||||||
|
Kind::_Gps => write!(f, "🛰️ gps 🛰️"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
struct Event {
|
||||||
|
kind: Vec<Kind>,
|
||||||
|
urls: Vec<Url>,
|
||||||
|
ids: Vec<MessageId>,
|
||||||
|
name: String,
|
||||||
|
date: NaiveDate,
|
||||||
|
loca: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
struct Weekend {
|
||||||
|
url: Option<Url>,
|
||||||
|
id: Option<MessageId>,
|
||||||
|
date: NaiveDate,
|
||||||
|
events: Vec<Event>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[serde_as]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct Index {
|
||||||
|
#[serde_as(as = "Vec<(_, _)>")]
|
||||||
|
hashmap: HashMap<NaiveDate, Weekend>,
|
||||||
|
url: Url,
|
||||||
|
id: MessageId,
|
||||||
|
state: State,
|
||||||
|
ram: Option<(NaiveDate, Message)>,
|
||||||
|
admin_id: ChatId,
|
||||||
|
channel_id: ChatId,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn telegram_len(str: &str) -> usize {
|
||||||
|
str.encode_utf16().collect::<Vec<_>>().len()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This function takes a day and a month, create a date with current or next year and quantize to nearest Saturday
|
||||||
|
fn get_weekend_date(day: u32, month: u32) -> Option<NaiveDate> {
|
||||||
|
let now = Local::now();
|
||||||
|
let current_year = now.year();
|
||||||
|
let date = NaiveDate::from_ymd_opt(current_year, month, day);
|
||||||
|
if let None = date {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let mut date = date.unwrap();
|
||||||
|
if std::cmp::max(date, now.date_naive()) != date {
|
||||||
|
date = NaiveDate::from_ymd_opt(current_year + 1, month, day).unwrap();
|
||||||
|
}
|
||||||
|
date = match date.weekday() {
|
||||||
|
Weekday::Mon => date.checked_sub_days(Days::new(2)).unwrap(),
|
||||||
|
Weekday::Tue => date.checked_sub_days(Days::new(3)).unwrap(),
|
||||||
|
Weekday::Wed => date.checked_add_days(Days::new(3)).unwrap(),
|
||||||
|
Weekday::Thu => date.checked_add_days(Days::new(2)).unwrap(),
|
||||||
|
Weekday::Fri => date.checked_add_days(Days::new(1)).unwrap(),
|
||||||
|
Weekday::Sat => date.checked_add_days(Days::new(0)).unwrap(),
|
||||||
|
Weekday::Sun => date.checked_sub_days(Days::new(1)).unwrap(),
|
||||||
|
};
|
||||||
|
Some(date)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_date(string: &str) -> Result<(u32, u32), &'static str> {
|
||||||
|
match string.split('/').collect::<Vec<_>>().as_slice() {
|
||||||
|
[day, month] =>
|
||||||
|
Ok((day.parse().unwrap_or_default(), month.parse().unwrap_or_default())),
|
||||||
|
_ => Err("usage: add DD/MM"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::get_weekend_date;
|
||||||
|
use crate::parse_date;
|
||||||
|
use chrono::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn weekend_date() {
|
||||||
|
let date = get_weekend_date(30, 11).unwrap();
|
||||||
|
assert_eq!(date.day(), 2);
|
||||||
|
assert_eq!(date.month(), 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse() {
|
||||||
|
assert_eq!(parse_date("30/11"), Ok((30, 11)));
|
||||||
|
assert_eq!(parse_date("04/11"), Ok((4, 11)));
|
||||||
|
assert_eq!(parse_date("30/04"), Ok((30, 4)));
|
||||||
|
assert_eq!(parse_date("04/04"), Ok((4, 4)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_and_we() {
|
||||||
|
let date = parse_date("04/11").unwrap();
|
||||||
|
let date = get_weekend_date(date.0, date.1).unwrap();
|
||||||
|
assert_eq!(date.day(), 2);
|
||||||
|
assert_eq!(date.month(), 11);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_weekend_msg(events: Vec<Event>) -> (String, Vec<MessageEntity>) {
|
||||||
|
let mut entities = vec![];
|
||||||
|
let mut str = String::from(format!("🔅INDEX {}/{}🔅\n", events[0].date.day0() + 1, events[0].date.month0() + 1));
|
||||||
|
|
||||||
|
for event in events.iter() {
|
||||||
|
let mut event_str = format!("🍃 {} ", event.name);
|
||||||
|
for j in 0..event.urls.len() {
|
||||||
|
let entity_str = format!("{} ", event.kind[j]);
|
||||||
|
entities.push(MessageEntity {
|
||||||
|
kind: teloxide::types::MessageEntityKind::TextLink {
|
||||||
|
url: event.urls[j].clone()
|
||||||
|
},
|
||||||
|
offset: telegram_len(&str) + telegram_len(&event_str) + 1,
|
||||||
|
length: telegram_len(&entity_str) - 1
|
||||||
|
});
|
||||||
|
event_str = format!("{}{}", event_str, entity_str);
|
||||||
|
}
|
||||||
|
str = format!("{}\n{}(area {})", str, event_str, event.loca);
|
||||||
|
}
|
||||||
|
|
||||||
|
(str, entities)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_event(msg: &Message, sent_msg: Message, date: NaiveDate, kind: Kind) -> Event {
|
||||||
|
let mut name = msg.text().unwrap().split(" ").collect::<Vec<_>>();
|
||||||
|
let loca = name.pop().unwrap().to_string();
|
||||||
|
name.remove(0);
|
||||||
|
let name = name.join(" ");
|
||||||
|
|
||||||
|
Event {
|
||||||
|
kind: vec![kind],
|
||||||
|
urls: vec![sent_msg.url().unwrap()],
|
||||||
|
ids: vec![sent_msg.id],
|
||||||
|
name,
|
||||||
|
loca,
|
||||||
|
date,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_new_weekend(date: NaiveDate) -> Weekend {
|
||||||
|
Weekend {
|
||||||
|
url: None,
|
||||||
|
id: None,
|
||||||
|
date,
|
||||||
|
events: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_index_msg(index: HashMap<NaiveDate, Weekend>) -> (String, Vec<MessageEntity>) {
|
||||||
|
let mut msg = format!("Index à jour\n\n");
|
||||||
|
let mut entities = vec![];
|
||||||
|
for (key, value) in index {
|
||||||
|
let line_str = format!("Index du {}\n", key);
|
||||||
|
entities.push(MessageEntity {
|
||||||
|
kind: teloxide::types::MessageEntityKind::TextLink {
|
||||||
|
url: value.url.unwrap().clone()
|
||||||
|
},
|
||||||
|
offset: telegram_len(&msg),
|
||||||
|
length: telegram_len(&line_str) - 1
|
||||||
|
});
|
||||||
|
msg = format!("{}{}", msg, line_str);
|
||||||
|
|
||||||
|
}
|
||||||
|
(msg, entities)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn new_command_logic(bot: Bot, index: &Arc<Mutex<Index>>, msg: Message) -> ResponseResult<()> {
|
||||||
|
let index = index.clone();
|
||||||
|
let mut index = index.lock().await;
|
||||||
|
if index.state == State::Add || index.state == State::New {
|
||||||
|
index.state = State::Base;
|
||||||
|
let date = index.ram.clone().unwrap().0;
|
||||||
|
let info = index.ram.clone().unwrap().1;
|
||||||
|
|
||||||
|
let mut kind = match info.text() {
|
||||||
|
Some(_) => Kind::Text,
|
||||||
|
None => Kind::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
kind = match (info.photo(), info.caption(), &kind) {
|
||||||
|
(Some(_), Some(_), _) => Kind::TextFly,
|
||||||
|
(Some(_), None, _) => Kind::Fly,
|
||||||
|
(None, _, _) => kind,
|
||||||
|
};
|
||||||
|
|
||||||
|
let event = create_event(&msg, info, date, kind);
|
||||||
|
match index.hashmap.get_mut(&date) {
|
||||||
|
Some(weekend) => {
|
||||||
|
weekend.events.push(event);
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
index.hashmap.insert(date, create_new_weekend(date));
|
||||||
|
let new_index_msg = bot.send_message(index.channel_id, "Index en cours de chargement... 🤪").await?;
|
||||||
|
index.hashmap.get_mut(&date).unwrap().url = Some(new_index_msg.url().unwrap());
|
||||||
|
index.hashmap.get_mut(&date).unwrap().id = Some(new_index_msg.id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let weekend = index.hashmap.get(&date).unwrap();
|
||||||
|
let weekend_msg = create_weekend_msg(weekend.events.clone());
|
||||||
|
bot.edit_message_text(index.channel_id, weekend.id.unwrap(), weekend_msg.0).entities(weekend_msg.1).await?;
|
||||||
|
let index_msg = create_index_msg(index.hashmap.clone());
|
||||||
|
bot.edit_message_text(index.channel_id, index.id, index_msg.0).entities(index_msg.1).await?;
|
||||||
|
} else {
|
||||||
|
bot.send_message(index.admin_id, "error: you must be in Add or New state to use new command").await?;
|
||||||
|
}
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn new_command(bot: Bot, index: &Arc<Mutex<Index>>, msg: Message) -> ResponseResult<()> {
|
||||||
|
if msg.text().unwrap().split(" ").collect::<Vec<_>>().len() >= 3 {
|
||||||
|
new_command_logic(bot, index, msg).await?;
|
||||||
|
} else {
|
||||||
|
let index = index.clone();
|
||||||
|
let index = index.lock().await;
|
||||||
|
bot.send_message(index.admin_id, "usage: new <name with spaces> <locaWithoutSpaces>").await?;
|
||||||
|
}
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn choose_command_logic(bot: Bot, index: &Arc<Mutex<Index>>, event_number: usize) -> ResponseResult<()> {
|
||||||
|
let index = index.clone();
|
||||||
|
let mut index = index.lock().await;
|
||||||
|
let channel_id = index.channel_id;
|
||||||
|
if index.state == State::Add {
|
||||||
|
let date = index.ram.clone().unwrap().0;
|
||||||
|
let info = index.ram.clone().unwrap().1;
|
||||||
|
|
||||||
|
if let Some(weekend) = index.hashmap.get_mut(&date) {
|
||||||
|
if weekend.events.len() >= event_number && event_number > 0 {
|
||||||
|
let mut kind = match info.text() {
|
||||||
|
Some(_) => Kind::Text,
|
||||||
|
None => Kind::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
kind = match (info.photo(), &kind) {
|
||||||
|
(Some(_), Kind::Text) => Kind::TextFly,
|
||||||
|
(Some(_), Kind::None) => Kind::Fly,
|
||||||
|
(Some(_), _) => unreachable!(),
|
||||||
|
(None, _) => kind,
|
||||||
|
};
|
||||||
|
weekend.events[event_number - 1].kind.push(kind);
|
||||||
|
weekend.events[event_number - 1].urls.push(info.url().unwrap());
|
||||||
|
weekend.events[event_number - 1].ids.push(info.id);
|
||||||
|
let weekend_msg = create_weekend_msg(weekend.events.clone());
|
||||||
|
bot.edit_message_text(channel_id, weekend.id.unwrap(), weekend_msg.0).entities(weekend_msg.1).await?;
|
||||||
|
let index_msg = create_index_msg(index.hashmap.clone());
|
||||||
|
bot.edit_message_text(channel_id, index.id, index_msg.0).entities(index_msg.1).await?;
|
||||||
|
index.state = State::Base;
|
||||||
|
} else {
|
||||||
|
bot.send_message(index.admin_id, "error: invalid number, please retry choose or new").await?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
bot.send_message(index.admin_id, "error: you must be in Add state to use choose command").await?;
|
||||||
|
}
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn choose_command(bot: Bot, index: &Arc<Mutex<Index>>, msg: Message) -> ResponseResult<()> {
|
||||||
|
if msg.text().unwrap().split(" ").collect::<Vec<_>>().len() == 2 {
|
||||||
|
match msg.text().unwrap().split(" ").collect::<Vec<_>>()[1].parse::<usize>() {
|
||||||
|
Ok(event_number) => DateReturn::Void(choose_command_logic(bot, index, event_number).await?),
|
||||||
|
Err(e) => {
|
||||||
|
let index = index.clone();
|
||||||
|
let index = index.lock().await;
|
||||||
|
DateReturn::Message(bot.send_message(index.admin_id, e.to_string()).await?)
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
let index = index.clone();
|
||||||
|
let index = index.lock().await;
|
||||||
|
bot.send_message(index.admin_id, "usage: choose <u32>").await?;
|
||||||
|
}
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_choose_message(events: Vec<Event>) -> String {
|
||||||
|
let mut msg = String::from("entered add state successfully\nusage:\nchoose <number>\nOR\nnew <name> <loca>\n\n");
|
||||||
|
|
||||||
|
for (i, elem) in events.iter().enumerate() {
|
||||||
|
msg = format!("{msg} [{}] {} (area {})\n", i + 1, elem.name, elem.loca);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn add_command_logic(bot: Bot, index: &Arc<Mutex<Index>>, msg: Message, date: NaiveDate) -> ResponseResult<()> {
|
||||||
|
let index = index.clone();
|
||||||
|
let mut index = index.lock().await;
|
||||||
|
let channel_id = index.channel_id;
|
||||||
|
if index.state == State::Base {
|
||||||
|
let mut state = State::New;
|
||||||
|
let info_admin_dm = msg.reply_to_message().unwrap();
|
||||||
|
let info = bot.forward_message(index.channel_id, index.admin_id, info_admin_dm.id).await?;
|
||||||
|
index.ram = Some((date, info));
|
||||||
|
match index.hashmap.get_mut(&date) {
|
||||||
|
Some(weekend) => {
|
||||||
|
state = State::Add;
|
||||||
|
let choose_msg = create_choose_message(weekend.events.clone());
|
||||||
|
bot.send_message(index.admin_id, choose_msg).await?;
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
index.hashmap.insert(date, create_new_weekend(date));
|
||||||
|
let weekend = index.hashmap.get_mut(&date).unwrap();
|
||||||
|
let new_index_msg = bot.send_message(channel_id, "Index en cours de chargement... 🤪").await?;
|
||||||
|
weekend.url = Some(new_index_msg.url().unwrap());
|
||||||
|
weekend.id = Some(new_index_msg.id);
|
||||||
|
bot.send_message(index.admin_id, "entered add state successfully\nusage:\nnew <name> <loca>\n").await?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
index.state = state;
|
||||||
|
} else {
|
||||||
|
bot.send_message(index.admin_id, "error: you must be in Base state to use add command").await?;
|
||||||
|
}
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
enum DateReturn {
|
||||||
|
DateReturn(Box<DateReturn>),
|
||||||
|
Message(Message),
|
||||||
|
Void(()),
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn add_command(bot: Bot, index: &Arc<Mutex<Index>>, msg: Message) -> ResponseResult<()> {
|
||||||
|
let admin_id = index.clone();
|
||||||
|
let lock = admin_id.lock().await;
|
||||||
|
let admin_id = lock.admin_id;
|
||||||
|
drop(lock);
|
||||||
|
if let Some(_) = msg.reply_to_message() {
|
||||||
|
if let Some(arg) = msg.text().unwrap().split(" ").last() {
|
||||||
|
match parse_date(arg) {
|
||||||
|
Ok((day, month)) => DateReturn::DateReturn(Box::new(match get_weekend_date(day, month) {
|
||||||
|
Some(date) => DateReturn::Void(add_command_logic(bot, index, msg.clone(), date).await?),
|
||||||
|
None => DateReturn::Message(bot.send_message(admin_id, "error: date is not valid").await?)
|
||||||
|
})),
|
||||||
|
Err(e) => DateReturn::Message(bot.send_message(admin_id, e).await?),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
bot.send_message(admin_id, "usage: add DD/MM").await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bot.send_message(admin_id, "error: You must reply to an info for the add command to work").await?;
|
||||||
|
}
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn default_command(bot: Bot, admin_id: ChatId) -> ResponseResult<()> {
|
||||||
|
bot.send_message(admin_id, "info/fly detecte, help pour la liste des commandes").await?;
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn handler(bot: Bot, index: Arc<Mutex<Index>>, msg: Message) -> ResponseResult<()> {
|
||||||
|
let admin_id = index.clone();
|
||||||
|
let lock = admin_id.lock().await;
|
||||||
|
let admin_id = lock.admin_id;
|
||||||
|
drop(lock);
|
||||||
|
if msg.chat.id == admin_id {
|
||||||
|
if let Some(msg_content) = msg.text() {
|
||||||
|
if let Some(command) = msg_content.split(" ").next() {
|
||||||
|
match command {
|
||||||
|
"add" => add_command(bot, &index, msg).await?,
|
||||||
|
"choose" => choose_command(bot, &index, msg).await?,
|
||||||
|
"new" => new_command(bot, &index, msg).await?,
|
||||||
|
_ => default_command(bot, admin_id).await?,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let index = index.clone();
|
||||||
|
let index = index.lock().await;
|
||||||
|
let index = Index {
|
||||||
|
hashmap: index.hashmap.clone(),
|
||||||
|
url: index.url.clone(),
|
||||||
|
id: index.id,
|
||||||
|
state: index.state.clone(),
|
||||||
|
ram: index.ram.clone(),
|
||||||
|
admin_id: index.admin_id,
|
||||||
|
channel_id: index.channel_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
let file = OpenOptions::new().write(true).create(true).truncate(true).open("data.json").unwrap();
|
||||||
|
let mut writer = BufWriter::new(file);
|
||||||
|
let _ = serde_json::to_writer(&mut writer, &index);
|
||||||
|
writer.flush()?;
|
||||||
|
|
||||||
|
|
||||||
|
respond(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let bot = Bot::new(dotenv!("BOT_API_TOKEN"));
|
||||||
|
let index;
|
||||||
|
let channel_id = ChatId(dotenv!("CHANNEL_ID").parse::<i64>().unwrap_or_else(|_| 0));
|
||||||
|
let admin_id = ChatId(dotenv!("ADMIN_ID").parse::<i64>().unwrap_or_else(|_| 0));
|
||||||
|
let file = File::open("data.json");
|
||||||
|
match file {
|
||||||
|
Ok(file) => {
|
||||||
|
let reader = BufReader::new(file);
|
||||||
|
index = Arc::new(Mutex::new(serde_json::from_reader(reader)?));
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
let index_msg = bot.send_message(channel_id, "INDEX AUTOMATISE\n").await?;
|
||||||
|
bot.pin_chat_message(channel_id, index_msg.id).await?;
|
||||||
|
index = Arc::new(Mutex::new(Index {
|
||||||
|
hashmap: HashMap::<NaiveDate, Weekend>::new(),
|
||||||
|
url: index_msg.url().unwrap(),
|
||||||
|
id: index_msg.id,
|
||||||
|
state: State::Base,
|
||||||
|
ram: None,
|
||||||
|
admin_id: admin_id,
|
||||||
|
channel_id: channel_id
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.send_message(admin_id, "THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.").await?;
|
||||||
|
bot.send_message(admin_id, "info: l'app vient de se lancer\n").await?;
|
||||||
|
|
||||||
|
let handler = Update::filter_message().endpoint(
|
||||||
|
|bot: Bot, index: Arc<Mutex<Index>>, msg: Message| async move {
|
||||||
|
handler(bot, index, msg).await
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Dispatcher::builder(bot, handler)
|
||||||
|
// Pass the shared state to the handler as a dependency.
|
||||||
|
.dependencies(dptree::deps![index])
|
||||||
|
.enable_ctrlc_handler()
|
||||||
|
.build()
|
||||||
|
.dispatch()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue