use std::{env, net::Ipv4Addr, sync::Arc}; use actix_web::{ middleware::Logger, web::{self, Data}, App, HttpServer, }; use anthill_di::*; use anthill_di_derive::constructor; use async_lock::RwLock; use botx_api::{ api::{ context::BotXApiContext, v4::notification::internal::{ api::internal_notification, models::{ InternalNotificationRequestBuilder, InternalNotificationRequest, }, }, }, extensions::botx_api_context::IBotXApiContextExt, }; use botx_api_framework::{ contexts::{BotXApiFrameworkContext, RequestContext}, extensions::actix::IActixHandlersExt, handlers::message::IMessageHandler, results::{CommandOk, CommandResult}, }; use env_logger::Env; use serde::Serialize; #[derive(Serialize, Clone)] pub struct InternalBotMessageData { pub message: String } #[derive(Serialize, Clone)] pub struct InternalBotMessageOption { pub internal_data: String } #[derive(constructor)] pub struct MessageHandler { #[resolve] api: Arc>, } #[async_trait_with_sync::async_trait] impl IMessageHandler for MessageHandler { async fn handle(&mut self, _message: String, request: RequestContext) -> CommandResult { let request: InternalNotificationRequest = InternalNotificationRequestBuilder::default() .with_group_chat_id(request.from.group_chat_id.unwrap()) .with_data(InternalBotMessageData { message: "test message data".to_string() }) .with_opts(InternalBotMessageOption { internal_data: "internal message option".to_string() }) .build() .unwrap(); internal_notification(&self.api, &request).await.unwrap(); Ok(CommandOk::default()) } } #[tokio::main] async fn main() -> anyhow::Result<()> { dotenv::dotenv().ok(); env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); let (ip, port) = get_address(); let ioc_ctx = DependencyContext::new_root(); ioc_ctx .register_type::(LifeCycle::Transient) .await?; ioc_ctx .register_type::(LifeCycle::Transient) .await? .map_as::() .await?; ioc_ctx.register_botx_api_context().await?; HttpServer::new(move || { App::new() .wrap(Logger::default()) .app_data(web::PayloadConfig::new(usize::MAX)) .app_data(web::JsonConfig::default().limit(usize::MAX)) .app_data(Data::new(ioc_ctx.clone())) .add_botx_api_handlers() }) .bind((ip.to_string(), port))? .run() .await?; Ok(()) } const BOT_HOST_ENV: &str = "BOT_HOST"; const BOT_PORT_ENV: &str = "BOT_PORT"; fn get_address() -> (Ipv4Addr, u16) { let ip = env::var(BOT_HOST_ENV) .expect(&*format!("Env {BOT_HOST_ENV} not found")) .parse::() .expect(&*format!("Env {BOT_HOST_ENV} must be valid ipv4")); let port = env::var(BOT_PORT_ENV) .expect(&*format!("Env {BOT_PORT_ENV} not found")) .parse::() .expect(&*format!("Env {BOT_PORT_ENV} must be valid u32")); (ip, port) }