Compare commits
8 Commits
403e06f542
...
03e42c9108
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03e42c9108 | ||
|
|
a905325a52 | ||
|
|
4bf7c214b9 | ||
|
|
345ea66f8e | ||
|
|
82045a39a9 | ||
|
|
b318e3ec8e | ||
|
|
09f7e76d96 | ||
|
|
29acb02a97 |
@ -83,7 +83,7 @@ pub async fn secret_command_handler(
|
|||||||
.await?;
|
.await?;
|
||||||
} else if pass == admin_password {
|
} else if pass == admin_password {
|
||||||
db.set_admin(user.id, true).await;
|
db.set_admin(user.id, true).await;
|
||||||
bot.send_message(msg.from.unwrap().id, "You are admin now!")
|
bot.send_message(msg.from.unwrap().id, "You are an admin now!")
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -4,11 +4,7 @@ use enum_stringify::EnumStringify;
|
|||||||
use futures::stream::{StreamExt, TryStreamExt};
|
use futures::stream::{StreamExt, TryStreamExt};
|
||||||
|
|
||||||
use mongodb::options::IndexOptions;
|
use mongodb::options::IndexOptions;
|
||||||
use mongodb::{
|
use mongodb::{bson::doc, options::ClientOptions, Client};
|
||||||
bson::doc,
|
|
||||||
options::{ClientOptions, ResolverConfig},
|
|
||||||
Client,
|
|
||||||
};
|
|
||||||
use mongodb::{Database, IndexModel};
|
use mongodb::{Database, IndexModel};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -39,6 +35,36 @@ pub struct User {
|
|||||||
pub language_code: Option<String>,
|
pub language_code: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! query_call {
|
||||||
|
($func_name:ident, $self:ident, $db:ident, $return_type:ty, $body:block) => {
|
||||||
|
pub async fn $func_name<D: CallDB>(&$self, $db: &mut D)
|
||||||
|
-> Result<$return_type, Box<dyn std::error::Error>> $body
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl User {
|
||||||
|
query_call!(update_user, self, db, (), {
|
||||||
|
let db_collection = db.get_database().await.collection::<Self>("users");
|
||||||
|
|
||||||
|
db_collection
|
||||||
|
.update_one(
|
||||||
|
doc! { "_id": self._id },
|
||||||
|
doc! {
|
||||||
|
"$set": {
|
||||||
|
"first_name": &self.first_name,
|
||||||
|
"last_name": &self.last_name,
|
||||||
|
"username": &self.username,
|
||||||
|
"language_code": &self.language_code,
|
||||||
|
"is_admin": &self.is_admin,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Message {
|
pub struct Message {
|
||||||
pub _id: bson::oid::ObjectId,
|
pub _id: bson::oid::ObjectId,
|
||||||
@ -94,6 +120,13 @@ impl DB {
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn init<S: Into<String>>(db_url: S) -> Result<Self, mongodb::error::Error> {
|
||||||
|
let mut db = Self::new(db_url).await;
|
||||||
|
db.migrate().await?;
|
||||||
|
|
||||||
|
Ok(db)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
42
src/main.rs
42
src/main.rs
@ -28,7 +28,7 @@ use teloxide::{
|
|||||||
type BotDialogue = Dialogue<State, MongodbStorage<Json>>;
|
type BotDialogue = Dialogue<State, MongodbStorage<Json>>;
|
||||||
|
|
||||||
#[derive(Envconfig)]
|
#[derive(Envconfig)]
|
||||||
struct Config {
|
pub struct Config {
|
||||||
#[envconfig(from = "BOT_TOKEN")]
|
#[envconfig(from = "BOT_TOKEN")]
|
||||||
pub bot_token: String,
|
pub bot_token: String,
|
||||||
#[envconfig(from = "DATABASE_URL")]
|
#[envconfig(from = "DATABASE_URL")]
|
||||||
@ -68,16 +68,27 @@ pub enum State {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct BotController {
|
||||||
|
pub bot: Bot,
|
||||||
|
pub db: DB,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotController {
|
||||||
|
pub async fn new(config: &Config) -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
|
let bot = Bot::new(&config.bot_token);
|
||||||
|
let db = DB::init(&config.db_url).await?;
|
||||||
|
|
||||||
|
Ok(Self { bot, db })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
dotenvy::dotenv()?;
|
dotenvy::dotenv()?;
|
||||||
let config = Config::init_from_env()?;
|
let config = Config::init_from_env()?;
|
||||||
|
|
||||||
let bot = Bot::new(&config.bot_token);
|
let mut bc = BotController::new(&config).await?;
|
||||||
let mut db = DB::new(&config.db_url).await;
|
let state_mgr = MongodbStorage::open(config.db_url.clone().as_ref(), "gongbot", Json).await?;
|
||||||
db.migrate().await.unwrap();
|
|
||||||
let db_url2 = config.db_url.clone();
|
|
||||||
let state_mgr = MongodbStorage::open(&db_url2, "gongbot", Json).await?;
|
|
||||||
|
|
||||||
// TODO: delete this in production
|
// TODO: delete this in production
|
||||||
let events: Vec<DateTime<Utc>> = vec!["2025-04-09T18:00:00+04:00", "2025-04-11T16:00:00+04:00"]
|
let events: Vec<DateTime<Utc>> = vec!["2025-04-09T18:00:00+04:00", "2025-04-11T16:00:00+04:00"]
|
||||||
@ -86,7 +97,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for event in events {
|
for event in events {
|
||||||
match db.clone().create_event(event).await {
|
match bc.db.create_event(event).await {
|
||||||
Ok(e) => println!("Created event {}", e._id),
|
Ok(e) => println!("Created event {}", e._id),
|
||||||
Err(err) => println!("Failed to create event, error: {}", err),
|
Err(err) => println!("Failed to create event, error: {}", err),
|
||||||
}
|
}
|
||||||
@ -127,8 +138,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
)
|
)
|
||||||
.branch(Update::filter_message().endpoint(echo));
|
.branch(Update::filter_message().endpoint(echo));
|
||||||
|
|
||||||
Dispatcher::builder(bot, handler)
|
Dispatcher::builder(bc.bot, handler)
|
||||||
.dependencies(dptree::deps![db, state_mgr])
|
.dependencies(dptree::deps![bc.db, state_mgr])
|
||||||
.enable_ctrlc_handler()
|
.enable_ctrlc_handler()
|
||||||
.build()
|
.build()
|
||||||
.dispatch()
|
.dispatch()
|
||||||
@ -231,6 +242,7 @@ async fn edit_msg_handler(
|
|||||||
|
|
||||||
match msg.media_kind {
|
match msg.media_kind {
|
||||||
MediaKind::Text(text) => {
|
MediaKind::Text(text) => {
|
||||||
|
db.drop_media(&literal).await.unwrap();
|
||||||
if is_caption_set {
|
if is_caption_set {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
@ -395,6 +407,8 @@ async fn user_command_handler(
|
|||||||
let user = db
|
let user = db
|
||||||
.get_or_init_user(tguser.id.0 as i64, &tguser.first_name)
|
.get_or_init_user(tguser.id.0 as i64, &tguser.first_name)
|
||||||
.await;
|
.await;
|
||||||
|
let user = update_user_tg(user, msg.from.as_ref().unwrap());
|
||||||
|
user.update_user(&mut db).await.unwrap();
|
||||||
println!("MSG: {}", msg.html_text().unwrap());
|
println!("MSG: {}", msg.html_text().unwrap());
|
||||||
match cmd {
|
match cmd {
|
||||||
UserCommands::Start => {
|
UserCommands::Start => {
|
||||||
@ -575,3 +589,13 @@ async fn echo(bot: Bot, msg: Message) -> Result<(), teloxide::RequestError> {
|
|||||||
.await?;
|
.await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_user_tg(user: db::User, tguser: &teloxide::types::User) -> db::User {
|
||||||
|
db::User {
|
||||||
|
first_name: tguser.first_name.clone(),
|
||||||
|
last_name: tguser.last_name.clone(),
|
||||||
|
username: tguser.username.clone(),
|
||||||
|
language_code: tguser.language_code.clone(),
|
||||||
|
..user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user