sign_in problem
hello, can't authorize client via telegram
if !client.is_authorized().await? {
if state.awaiting_phone_number {
if let Some(phone) = msg.text() {
state.phone_number = Some(phone.to_string());
state.awaiting_phone_number = false;
state.awaiting_passcode = true;
let token = client.request_login_code(phone).await?;
state.token = Some(Arc::new(token));
bot.send_message(msg.chat.id, "Phone number received! Please provide the passcode.")
.await?;
}
} else if state.awaiting_passcode {
if let Some(code) = msg.text() {
state.passcode = Some(code.to_string());
state.awaiting_passcode = false;
if let Some(token) = &state.token {
let token = Arc::clone(token); // Clone the Arc
match client.sign_in(&token, code).await {
Ok(_) => {
bot.send_message(msg.chat.id, "Successfully authorized!")
.await?;
}
Err(SignInError::PasswordRequired(password_token)) => {
let hint = password_token.hint().unwrap_or("No hint");
state.awaiting_2fa = true;
state.password_token = Some(password_token.clone());
bot.send_message(msg.chat.id, format!("2FA required. Hint: {}. Please enter your 2FA password.", hint))
.await?;
}
Err(e) => {
bot.send_message(msg.chat.id, format!("Failed to sign in: {}", e))
.await?;
return Err(e.into());
}
}
}
}
} else if state.awaiting_2fa {
if let Some(password) = msg.text() {
if let Some(password_token) = &state.password_token {
match client.check_password(password_token.clone(), password).await {
Ok(_) => {
bot.send_message(msg.chat.id, "Successfully authorized with 2FA!")
.await?;
}
Err(e) => {
bot.send_message(msg.chat.id, format!("Failed to authorize with 2FA: {}", e))
.await?;
return Err(e.into());
}
}
}
}
}
} else {
bot.send_message(msg.chat.id, "Already authorized!")
.await?;
}
I got phone_number from user via telegram bot, then fall into state awaiting passcode, create token:
let token = client.request_login_code(phone).await?;
and then i get passcode from telegram to my cellphone, typing it into bot... and got:
Incomplete login attempt. Dear ***, Telegram blocked an attempt to log into your account from a new device on 16/09/2024 at 22:46:49 UTC.
Device: app_name, 0.6.0, Mac OS 64-bit, Desktop, 14.6.1 Location: ***
Nobody gained access to your chats because the login was not completed. The code was entered correctly, but sign in was not allowed, because this code was previously shared by your account.
Please don't share login codes with others, because they allow anyone to log in to your account and access your chats.
is there any way to authorize this way?
Did you use the library from crates.io, or the git version? If the former, try the git version.
i use following:
grammers = { git = "https://github.com/Lonami/grammers.git", branch = "master" }
grammers-client = { git = "https://github.com/Lonami/grammers.git", package = "grammers-client", branch = "master" }
grammers-session = { git = "https://github.com/Lonami/grammers.git", package = "grammers-session", branch = "master" }
strange thing is that telegram says me: "The code was entered correctly, but sign in was not allowed, because this code was previously shared by your account."
maybe some trouble with storing token in the user states' structures?
#[derive(Default, Clone)]
pub struct AuthStages {
pub awaiting_phone_number: bool,
pub awaiting_passcode: bool,
pub awaiting_2fa: bool,
pub phone_number: Option<String>,
pub passcode: Option<String>,
pub two_fa: Option<String>,
pub client: Option<Client>,
pub token: Option<Arc<LoginToken>>,
pub password_token: Option<PasswordToken>,
}
#[derive(Default)]
pub struct AppState {
pub user_state: Mutex<HashMap<u64, AuthStages>>,
}
If the code is sent in a Telegram message, it will immediately expire.
so how should i transfer it here
client.sign_in(&token, code)
I got the code, sending it via telegram bot, processing this message, and sending code and token to the authorization fn
pub(crate) async fn auth_data_processing(bot: Bot, msg: Message, app_state: Arc<AppState>, mut state: AuthStages) -> anyhow::Result<()> {
let user_id = msg.from.as_ref().map(|user| user.id.0).unwrap_or(0);
// Check and set client
if state.client.is_none() {
let session_file = format!("{}.session", msg.chat.id);
let client = Client::connect(Config {
session: Session::load_file_or_create(session_file.clone())?,
api_id: API_ID,
api_hash: API_HASH.to_string(),
params: Default::default(),
}).await?;
state.client = Some(client.clone());
// client.session().save_to_file(format!("{}.session", msg.chat.id))?;
}
let client = state.client.as_ref().unwrap();
// Handle authorization
if !client.is_authorized().await? {
if state.awaiting_phone_number {
if let Some(phone) = msg.text() {
state.phone_number = Some(phone.to_string());
state.awaiting_phone_number = false;
state.awaiting_passcode = true;
let token = client.request_login_code(phone).await?;
state.token = Some(Arc::new(token));
bot.send_message(msg.chat.id, "Phone number received! Please provide the passcode.")
.await?;
let mut user_states = app_state.user_state.lock().await;
user_states.insert(user_id, state.clone());
}
} else if state.awaiting_passcode {
if let Some(code) = msg.text() {
info!("got code: {}", code);
state.passcode = Some(code.to_string());
state.awaiting_passcode = false;
if let Some(token) = state.token.as_ref() {
// let token = Arc::clone(token); // Clone the Arc
sleep(Dur::from_secs(2)).await;
match client.sign_in(&token, code).await {
Ok(_) => {
bot.send_message(msg.chat.id, "Successfully authorized!")
.await?;
}
Err(SignInError::PasswordRequired(password_token)) => {
let hint = password_token.hint().unwrap_or("No hint");
state.awaiting_2fa = true;
state.password_token = Some(password_token.clone());
bot.send_message(msg.chat.id, format!("2FA required. Hint: {}. Please enter your 2FA password.", hint))
.await?;
}
Err(e) => {
bot.send_message(msg.chat.id, format!("Failed to sign in: {}", e))
.await?;
return Err(e.into());
}
}
}
}
} else if state.awaiting_2fa {
if let Some(password) = msg.text() {
if let Some(password_token) = &state.password_token {
match client.check_password(password_token.clone(), password).await {
Ok(_) => {
bot.send_message(msg.chat.id, "Successfully authorized with 2FA!")
.await?;
}
Err(e) => {
bot.send_message(msg.chat.id, format!("Failed to authorize with 2FA: {}", e))
.await?;
return Err(e.into());
}
}
}
}
}
} else {
bot.send_message(msg.chat.id, "Already authorized!")
.await?;
}
// Update the state in user_states
let mut user_states = app_state.user_state.lock().await;
user_states.insert(user_id, state);
Ok(())
}
in case you would like see the code of the auth fn
sending it via telegram bot
Don't. It expires.