
    <i                    .   d Z ddlmZ ddlZddlZddlZddlZddlZddl	Zddl
m
Z
mZmZ ddlmZmZ  ej                   e      Z G d de      ZddZdd	Zdd
Zddddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZddZ	 d	 	 	 	 	 	 	 ddZ	 	 d	 	 	 	 	 	 	 	 	 	 	 ddZy)zFHelpers for validating Telegram Web App initData and sending messages.    )annotationsN)datetime	timedeltatimezone)AnyMappingc                      e Zd ZdZy)TelegramDataValidationErrorz/Raised when Telegram initData fails validation.N)__name__
__module____qualname____doc__     ?/home/cursorai/projects/telegram-earn/backend/utils/telegram.pyr
   r
      s    9r   r
   c                    t         j                  j                  | d      }|j                         D ci c]  \  }}||d    c}}S c c}}w )z?Parse the initData query string into a flat dict of str -> str.F)strict_parsingr   )urllibparseparse_qsitems)	init_data	parsed_qskeyvaluess       r   parse_init_datar      sH    %%i%FI.7oo.?@.?{sFCN.?@@@s   A	c                f     dj                   fdt         j                               D              S )z
    Construct the data_check_string from parsed initData dict.

    This follows Telegram's requirement of alphabetical key sorting and
    excludes the `hash` field.
    
c              3  <   K   | ]  }|d k7  r| d|      yw)hash=Nr   ).0r   parsed_datas     r   	<genexpr>z*build_data_check_string.<locals>.<genexpr>#   s1      -C&= %qS!"#-s   )joinsortedkeys)r#   s   `r   build_data_check_stringr(      s1     99 +**,-  r   c                    |st        d      t        j                  |j                               j	                         }t        j                  || j                         t        j                        j                         S )z8Calculate the HMAC-SHA-256 hash for a data_check_string.Bot token not configured)r
   hashlibsha256encodedigesthmacnew	hexdigest)data_check_string	bot_token
secret_keys      r   calculate_init_data_hashr5   *   s[    )*DEE	 0 0 23::<J88J 1 8 8 :GNNKUUWWr   )	auth_datequery_idstart_paramextra_paramsc           
     <   |st        d      i }|r<|j                  |j                         D ci c]  \  }}|t        |       c}}       |j	                  dt        j                  |              |j	                  dt        |xs: t        t        j                  t        j                        j                                            |r||d<   |r||d<   t        |      }	t        |	|      |d<   t        j                   j#                  |      |	|d   dS c c}}w )z
    Build a signed initData string that mirrors Telegram's format.

    Returns a dict containing:
    - init_data: URL-encoded string ready to use
    - data_check_string: the string that was signed
    - hash: the calculated hash value
    r*   userr6   r7   r8   r    )r   r2   r    )r
   updater   str
setdefaultjsondumpsintr   nowr   utc	timestampr(   r5   r   r   	urlencode)
r;   r3   r6   r7   r8   r9   paramsr   valuer2   s
             r   generate_signed_init_datarH   3   s   " )*DEEF9K9K9MN9M:3sCJ9MNO
fdjj./
IDX\\(,,7AACDE
 %z +}/7-.?KF6N \\++F3.v ! Os   D
c                    t        |       }t        |      }	 t        ||      }|j	                  d      ||dS # t        $ r d}Y "w xY w)z
    Provide a debug-friendly view of the initData signature inputs/outputs.

    Useful for development harnesses to compare provided and calculated hashes.
    Nr    )provided_hashcalculated_hashr2   )r   r(   r5   r
   get)r   r3   parsedr2   rK   s        r   init_data_debug_snapshotrN   `   s_     Y'F/723DiP
  F+*.  ' s   9 AAc                @   |st        d      t        |       }d|vrt        d      |d   }t        |      }t        ||      }||k7  rt        d      |	 ddlm} t        |dd      }|dk  rnyd	|v rut        j                  t        |d	         t        j                  
      }t        j                  t        j                        |z
  }	|	t        |      kD  rt        d| d      i }
d|v rt!        j"                  |d         }
|
S # t        t        f$ r d}Y w xY w)aP  
    Validate Telegram Web App initData payload.

    Args:
        init_data: Raw initData string from Telegram Web App.
        bot_token: Telegram bot token used to derive the secret key.
        expiration_hours: Optional expiration window in hours. Defaults to 24 hours
                         (Telegram's standard). In dev mode, can be extended via
                         TELEGRAM_INIT_DATA_EXPIRATION_HOURS setting.

    Returns:
        Parsed user data dictionary when validation succeeds.

    Raises:
        TelegramDataValidationError: if validation fails for any reason.
    r*   r    zMissing hash in init_dataz#Invalid hash - data may be tamperedr   )settings#TELEGRAM_INIT_DATA_EXPIRATION_HOURS   r6   )tz)hourszinitData expired (older than z hours)r;   )r
   r   r(   r5   django.confrP   getattrImportErrorRuntimeErrorr   fromtimestamprA   r   rC   rB   r   r?   loads)r   r3   expiration_hoursr#   received_hashr2   rK   rP   r6   age	user_datas              r   validate_telegram_init_datar_   t   sG   * )*DEE!),K[ )*EFF'M/<./@)LO-')*OPP 	",&x1VXZ[
 1		#**K()||
	 ll8<<(94!122-/0@/AI  IJJ{623	- \* 	"!	"s   D	 	DDc                4   | st         j                  d       y||dd}|r||d<   |r||d<   d|  d}t        j                  |      j	                  d	      }	 t
        j                  j                  ||d
ddi      }t
        j                  j                  |d      5 }	|	j                  dk7  r*t         j                  d|	j                         	 ddd       y	 ddd       y# 1 sw Y   yxY w# t        $ r }
t         j                  d|
       Y d}
~
yd}
~
ww xY w)z
    Send a Telegram message using the Bot API via HTTP.

    This avoids introducing extra async dependencies in the webhook handler
    while still using the official Telegram Bot HTTP endpoint.
    z/Cannot send Telegram message: bot token missingFT)chat_idtextdisable_web_page_preview
parse_modereply_markupzhttps://api.telegram.org/botz/sendMessagezutf-8POSTzContent-Typezapplication/json)urldatamethodheaders
   )timeout   z0Telegram sendMessage returned non-200 status: %sNz#Failed to send Telegram message: %s)loggerwarningr?   r@   r-   r   requestRequesturlopenstatus	Exception)r3   ra   rb   re   rd   payloadrg   rh   rp   responseexcs              r   send_telegram_messagerx      s    HI $(G  *".(<
@C::g%%g.D..((#%78	 ) 
 ^^##GR#8H#%F  98% 9  9  <cBs=   AC. 1C"C. C. "C+'C. +C. .	D7DD)r   r=   returndict[str, str])r#   zMapping[str, str]ry   r=   )r2   r=   r3   r=   ry   r=   )r;   dictr3   r=   r6   
int | Noner7   
str | Noner8   r}   r9   zdict[str, str] | Nonery   rz   )r   r=   r3   r=   ry   zdict[str, str | None])N)r   r=   r3   r=   r[   r|   ry   r{   )NHTML)r3   r=   ra   rA   rb   r=   re   zdict[str, Any] | Nonerd   r}   ry   bool)r   
__future__r   r+   r/   r?   loggingurllib.parser   urllib.requestr   r   r   typingr   r   	getLoggerr   rn   
ValueErrorr
   r   r(   r5   rH   rN   r_   rx   r   r   r   <module>r      s-   L "       2 2  
		8	$:* :AX !"*.*
* * 	*
 * * (* *Z. $(BBB !B 
	BR +/#/// / (	/
 / 
/r   