
    PiH                     *   U d Z ddlZddlZddlmZmZ ddlmZ ddlm	Z	 ddl
Z
	 ddlmZ ddlmZmZmZmZmZmZ dZ e
j.                  e      Z e	       Zi aeeef   ed
<   i aeeej>                  f   ed<    ej>                         Z ddee   dee   dee   fdZ!	 	 	 dde"de"dee"   dee   dee   de#e$ee"   f   fdZ%ddee   dee   de$fdZ&dededee   fdZ'dede"dedee   fdZ(ddee   fdZ)y# e$ r d	ZdZeZeZeZeZeZeZY w xY w)u   
Telegram Client API (MTProto) service для отправки сообщений без /start
Использует Pyrogram для подключения через пользовательский аккаунт
Поддерживает несколько аккаунтов из БД
    N)OptionalDict)Session)get_settings)Client)	FloodWaitUserNotParticipantChatWriteForbiddenPeerIdInvalidUsernameNotOccupiedUsernameInvalidTF_telegram_clients_client_locks
account_iddbreturnc                   K   t         st        j                  d       y| r
|rddlm} |j                  |      j                  |j                  | k(  |j                  dk(        j                         }|st        j                  d|  d       yt        4 d{    | t        vrt        j                         t        | <   t        |    }ddd      d{    | t        v r3t        |    }|j                  r	 |j!                          d{   }|r|S 	 4 d{    | t        v r-t        |    j                  rt        |    cddd      d{    S 	 ddlm}  ||j*                        }	|	s*t        j-                  d|         	 ddd      d{    yt.        j0                  j3                  t/        j4                         t6        j8                        }
t/        j:                  |
d       d|  }t=        ||j>                  |	|j@                  |
      }	 |jC                          d{    |j!                          d{   }|sDt        j                  d|  d       	 |j%                          d{    	 ddd      d{    y	 |j!                          d{   }|r:|jD                  |jD                  k7  r!|jD                  |_"        |jG                          |t        | <   t        jI                  d|  d|r|jD                  nd        |cddd      d{    S t6        jJ                  r t6        jL                  rt6        jN                  st        j                  d       yd}t        4 d{    |t        vrt        j                         t        |<   t        |   }ddd      d{    |t        v r3t        |   }|j                  r	 |j!                          d{   }|r|S 	 4 d{    |t        v r-t        |   j                  rt        |   cddd      d{    S 	 t.        j0                  j3                  t/        j4                         t6        j8                        }t/        j:                  |d       d}t=        |t6        jJ                  t6        jL                  t6        jN                  |      }|jC                          d{    |t        |<   t        jI                  d|jP                  r|jP                  jD                  nd        |cddd      d{    S 7 7 i# 1 d{  7  sw Y   zxY w7 L# t"        $ r}t        j                  d|  d	| d
       4 d{  7   | t        v r0	 t        |    j%                          d{  7   n#  Y nxY wt        | = ddd      d{  7   n# 1 d{  7  sw Y   nxY wY d}~d}~ww xY w7 7 7 j7 7 7 #  Y xY w7 # t"        $ rX}t        j                  d|  d	|        	 |j%                          d{  7   n#  Y nxY wY d}~ddd      d{  7   yd}~ww xY w7 7 W# t"        $ r8}t        j-                  d|  d	| d       Y d}~ddd      d{  7   yd}~ww xY w# 1 d{  7  sw Y   xY w7 \7 ## 1 d{  7  sw Y   4xY w7 # t"        $ r}t        j                  d|        4 d{  7   |t        v r0	 t        |   j%                          d{  7   n#  Y nxY wt        |= ddd      d{  7   n# 1 d{  7  sw Y   nxY wY d}~d}~ww xY w7 7 b7 7 f# t"        $ r3}t        j-                  d|        Y d}~ddd      d{  7   yd}~ww xY w# 1 d{  7  sw Y   yxY ww)u  
    Получить или создать Telegram Client для аккаунта
    
    Args:
        account_id: ID аккаунта из БД. Если None, используется аккаунт из env (legacy)
        db: Database session для загрузки аккаунта
    
    Returns:
        Client: Pyrogram клиент или None если не настроен
    W   Pyrogram не установлен. Установите: pip install pyrogram tgcryptoNr   TelegramMtprotoAccountactive   MTProto аккаунт u-    не найден или не активенu-   Ошибка проверки клиента : u   , пересоздаем)decrypt_tokenuN   Не удалось расшифровать API hash для аккаунта T)exist_okmtproto_)nameapi_idapi_hashphone_numberworkdiru   Клиент u5    подключен, но не авторизованuB   Требуется авторизация для аккаунта u    подключен: @zN/AuM   Ошибка создания MTProto клиента для аккаунта exc_infou   Telegram Client API не настроен: отсутствуют настройки в env или аккаунт не указанu5   Ошибка проверки legacy клиента: legacy_sessionu0   Legacy MTProto клиент подключен: u=   Ошибка создания legacy MTProto клиента: ))PYROGRAM_AVAILABLEloggerwarningapp.db.modelsr   queryfilteridstatusfirst_clients_lockr   asyncioLockr   is_connectedget_me	Exceptionstopapp.utils.encryptionr   api_hash_encerrorospathjoingetcwd	_settingsTELEGRAM_SESSION_PATHmakedirsr   r   phonestartusernamecommitinfoTELEGRAM_API_IDTELEGRAM_API_HASHTELEGRAM_PHONEme)r   r   r   accountaccount_lockclientrG   er   r   session_base_pathsession_namelegacy_account_idlegacy_locksession_paths                  7/var/www/notifications/app/services/telegram_mtproto.pyget_telegram_clientrR   -   se     pq
 b8((1299"%%3"))X5
 %' 	
 NN4ZL@mno ! 	5 	5.,3LLNj)(4L	5 	5 **&z2F"">%}}.B%    B	 B	..3DZ3P3]3](4B	 B	 B	
=>()=)=>LL#qr|q}!~B	 B	 B	  %'GGLLi>]>]$^!-=!)*6
  %">>%!(-  ,,.((%}}.BzlBw'xy!"(++-//  $WB	 B	 B	J $ "==?*"++)9)99'){{G$IIK06!*-5j\AWgiXZXcXcotWuvw}B	 B	 B	J $$I,G,GyOgOg  ]  	^  7 7M1/6||~M+,#$567 7
 --"#45A!==?*!M     116GHY6Z6g6g$%67  	77<<		Y5T5TULKKt4+L! 00"44&55$F ,,.  39/0KKJagajaj699K]K]puJvwx)  s	5 	5 	5 	5 	5 / ! >NN%RS]R^^`ab`cc{#|}+ > >%)::%&7
&C&H&H&J J J% $ 1* => > > > >>B	 B	 B	D ). 0! UB	X !   NN%ghrgssuvwux#yz$kkm++iB	 B	 B	X  +oB	@  lmwlxxz{|z}~  JN  OEB	 B	 B	@AB	 B	 B	V7 7 7 7 7 +  A!VWXVYZ[& A A(,==!"34E"F"K"K"MMM! -.?@A A A A AA " !#,  	LLXYZX[\]1  ,	-  s  B_3T<_3-U_3T?!_39U UU _3W9_3 $[_3W<_32Z 
_3W?_3B Z X/X0XXX(X;X<X_3X_3Z &Y:'A3Z _3&Y='A_3>[?_3-[ /_3:[;!_3[9 0[61[9 8_3 ^_3$_(_34^5_3;B&^!^"A^*_36^7_3?_3UU	U_3U 	W6$"W1V	W1	WV6/V20V65W6V:8WW1WW1W(	WW(	$W1+_31W66_3<_3?_3XXXXX_3	Y7Y2;YYYY2YY2Z  _3+Y.,_32Y77Z =_3 	[	Z<&[*_35Z86_3<[[[
[[	_3_3 [3&[)'[3._36[9 9	^^ \#!^%	]0/]	]
]]0]]0^)],*^0^	6]97^	>^_3^_3_3^_3	_(_ __3__3___0$_'%_0,_3	recipientmessage
parse_modec                   K   t         syt        ||       d{   }|s|rdd| dfS y	 t        | t              r| }nQt	        |       }|j                  d      r|d	d }|}n-|j                  d
      j                         rt        |      }n|}d}	|dk(  rd}	n|dk(  rd}	|j                  |||	       d{   }
t        j                  d|
j                          y7 7 )# t        $ r3}d|j                   d}t        j                  |       d|fcY d}~S d}~wt        t         f$ r1}dt	        |       }t        j                  |       d|fcY d}~S d}~wt"        t$        t&        f$ r4}d|  dt	        |       }t        j                  |       d|fcY d}~S d}~wt(        $ r3}dt	        |       }t        j+                  |d       d|fcY d}~S d}~ww xY ww)u  
    Отправить сообщение через Telegram Client API (MTProto)
    Позволяет отправлять сообщения без /start, так как использует пользовательский аккаунт
    
    Args:
        recipient: username (@username) или chat_id (число)
        message: текст сообщения
        parse_mode: режим парсинга (Markdown, HTML, None)
        account_id: ID MTProto аккаунта из БД (опционально)
        db: Database session (требуется если указан account_id)
    
    Returns:
        tuple[bool, Optional[str]]: (success, error_message)
    )Fr   r   r   NFr   u2    не настроен или недоступен)Fu   Telegram Client API не настроен. Проверьте настройки или добавьте MTProto аккаунт@   -MarkdownmarkdownHTMLhtml)chat_idtextrU   u<   Сообщение отправлено через MTProto: )TNuA   Превышен лимит запросов. Подождите u    секундu#   Нет доступа к чату: u'   Неверный получатель (z): u2   Ошибка отправки через MTProto: Tr"   )r%   rR   
isinstanceintstr
startswithlstripisdigitsend_messager&   rC   r+   r   valuer'   r	   r
   r   r   r   r3   r7   )rS   rT   rU   r   r   rJ   targetrecipient_strrA   pyrogram_parse_modesent_messagerK   	error_msgs                rQ   send_message_via_mtprotorn      s    * o&*DDF3J<?qrrr X6  i%F	NM'',(,!%%c*224]+ ' ##",6!"( $00* 1 
 
 	RS_SbSbRcdeQ EB
   WXYX_X_W``mn	y!i 23  9#a&B	y!i.@  =i[CPQF8T	y!i  HQQ	Y.i s   G"C!G"BC% 9C#:&C%  G"#C% %	G.(DGG"G.&EGG"G1)F GG" G,(GGG"GG"c                 j   K   t         syt        | |       d{   }|duxr |j                  S 7 w)u<   Проверить доступен ли Telegram Client APIFrW   N)r%   rR   r1   )r   r   rJ   s      rQ   is_mtproto_availablerp   7  s7     &*DDF5&"5"55 Es   313	tenant_idc                   K   t         syddlm} |j                  |      j	                  |j
                  | k(  |j                  dk(  |j                  dk(        j                         }|r|j                  S |j                  |      j	                  |j
                  | k(  |j                  dk(        j                         }|r|j                  S dS w)u   
    Получить ID аккаунта по умолчанию для тенанта
    
    Returns:
        int: ID аккаунта или None если нет аккаунтов
    Nr   r   r   T)
r%   r(   r   r)   r*   rq   r,   
is_defaultr-   r+   )rq   r   r   rH   s       rQ   get_default_mtproto_accountrt   ?  s      4 hh-.55((I5%%1))T1 eg	  zz hh-.55((I5%%1 eg 
 !7::*d*s   CCcustomer_phonec                   K   t         r|syddlm} ddlm} |j                         j                  dd      j                  dd      j                  dd      j                  d	d      }|j                  |      j                  |j                  | k(  |j                  d
k(        j                         }|D ]o  }|j                  j                         j                  dd      j                  dd      j                  dd      j                  d	d      }||k(  sc|j                  c S  r|j                  S t        | |       d{   S 7 w)u  
    Получить ID MTProto аккаунта по номеру телефона клиента
    Логика: ищем MTProto аккаунт с номером телефона, совпадающим с номером клиента
    
    Args:
        tenant_id: ID тенанта
        customer_phone: Номер телефона клиента (например, +79991234567)
        db: Database session
    
    Returns:
        int: ID MTProto аккаунта или None если не найден
    Nr   r   )func  rZ   ()r   )r%   r(   r   
sqlalchemyrw   stripreplacer)   r*   rq   r,   allr?   r+   rt   )	rq   ru   r   r   rw   normalized_phoneaccountsrH   account_phone_normalizeds	            rQ   get_mtproto_account_by_phoner   ^  s8     ^4 &++-55c2>FFsBOWWX[]_`hhilnpq xx./66((I5%%1 
ce 
  #*==#6#6#8#@#@b#I#Q#QRUWY#Z#b#bcfhj#k#s#stwy{#| #'77::	 zz -Y;;;;s   DE	,E	EE	c                   K   t         sy| 1| t        v r(	 t        |    j                          d{    t        | = yyt        t        j                               D ]  \  }}	 |j                          d{      t        j                          y7 `# t        $ r%}t        j                  d|  d|        Y d}~d}~ww xY w# t        | = w xY w7 Z# t        $ r%}t        j                  d| d|        Y d}~d}~ww xY ww)u6   Закрыть соединение с Telegram ClientNu-   Ошибка закрытия клиента r   )	r%   r   r4   r3   r&   r7   listitemsclear)r   rK   acc_idrJ   s       rQ   close_telegram_clientr     s	     **2'
388::: &j1 + ##4#:#:#<= 	\NFF\kkm##	\
 	! ; `LZLXZ[\Z]^__` &j1
 $ \LVHTVWXVYZ[[\s   DB BB ,D!C4C5C9DB 	C B;6C ;C  C 	CDC	C?C:5D:C??D)NN)NNN)N)*__doc__r/   r8   typingr   r   sqlalchemy.ormr   app.core.configr   loggingpyrogramr   pyrogram.errorsr   r	   r
   r   r   r   r%   ImportErrorr3   	getLogger__name__r&   r<   r   rb   __annotations__r   r0   r.   rR   rc   tupleboolrn   rp   rt   r   r        rQ   <module>r      s  
  	 ! " (     
		8	$N	 (* 4V$ ))+tC%& +p(3- pHWDU paijpaq pl !% $ T T T  T  	T 
 	T  4#T n68C= 6XgEV 6bf 6+ +' +hsm +>'<# '<s '<PW '<\deh\i '<T"HSM "_   FI""M#O s   C: :DD