
    th6                     \   S r SSKrSSKrSSKrSSKrSSKrSSKrSSKJr  SSKJ	r	  SSK
JrJrJrJr  SSKrSSKJr  \r\" \5      r\S   (       aG  \R*                  " \R,                  S9  \	" S	5      R/                  S
S9  \	" \S   5      R/                  S
S9   " S S5      r\R3                  SS/S9S 5       r\R3                  SS/S9S 5       r\R3                  SS/S9S 5       r\R3                  SS/S9S 5       r\S:X  Ga  SSKr\R>                  RA                  \R>                  RC                  \R>                  RC                  \"5      5      SS5      r#\R>                  RA                  \R>                  RC                  \R>                  RC                  \"5      5      SS5      r$Sr%\R>                  RM                  \#5      (       ak  \R>                  RM                  \$5      (       aK  \RN                  " \RP                  5      r%\%RS                  \#\$5        Sr*\RW                  SS5      r,\-" S 5        O%S!r*\S"   r,\-" S#5        \-" S$\# 35        \-" S$\$ 35        \-" S%5        \-" S&\* S'\, S35        \-" S(\S)    35        \-" S*\S+    35        \-" S,5        \R]                  \S-   \,\S   \%S.9  gg)/ul   
WhatsApp Webhook en Python
Convierte los mensajes recibidos de WhatsApp y los envía al servidor WebSocket
    N)datetime)Path)Flaskrequestjsonifyabort)WEBHOOK_CONFIGdebug)levellogsT)exist_okmedia_local_pathc                   x    \ rS rSr\S 5       r\S 5       r\S 5       r\S 5       r\S 5       r	\S
S j5       r
Srg	)WhatsAppWebhook    c                 0    SSK nUR                  SSU 5      $ )u.   Eliminar prefijos y normalizar a solo númerosr   Nz[^0-9] )resub)phoner   s     CC:\xampp\htdocs\multiusoWhatsapp\muliusoWhatsapp\webhook\webhook.pynormalize_phone_number&WhatsAppWebhook.normalize_phone_number"   s     	vviU++    c                 &   [         R                  R                  SS5      nU(       d  g[        R                  " UR                  5       U R                  5       [        R                  5      R                  5       n[        R                  " USU 35      $ )z$Validar firma de WhatsApp (opcional)zX-Hub-Signature-256r   Tzsha256=)
r   headersgethmacnewencodehashlibsha256	hexdigestcompare_digest)payloadtoken	signature
calculateds       r   validate_whatsapp_signature+WhatsAppWebhook.validate_whatsapp_signature(   sq     OO''(=rB	XXLLNNNNN
 )+	 	 ""9
|.DEEr   c                     SU ;   =(       a    [        U S   5      S:  =(       a    SU S   S   ;   =(       a    [        U S   S   S   5      S:  =(       an    SU S   S   S   S   ;   =(       aV    SU S   S   S   S   S   ;   =(       a;    [        U S   S   S   S   S   S   5      S:  =(       a    SU S   S   S   S   S   ;   $ ! [        [        [        4 a     gf = f)zValidar estructura del mensajeentryr   changesvaluemessagescontactsF)lenKeyError
IndexError	TypeError)datas    r   is_valid_message_structure*WhatsAppWebhook.is_valid_message_structure7   s$   	4 FDM"Q&FT']1--F DM!$Y/014F 4=+I6q99	F
 d7mA.y9!<WEEF DM!$Y/27;JGH1LF d7mA.y9!<WEE	 *i0 		s   CC CCc           	          SS[         S    30n[        R                  " SU  3USS9nUR                  S:w  a$  [        R
                  " SUR                   35        g	UR                  5       nUR                  S
5      nU(       d  [        R
                  " S5        g	[        R                  " XRSS9nUR                  S:w  a$  [        R
                  " SUR                   35        g	[        [         S   5      U-  nUR                  UR                  5        [         S   U-   $ ! [         a/  n[        R
                  " SU  S[        U5       35         S	nAg	S	nAff = f)u3   Descargar media de WhatsApp y devolver URL públicaAuthorizationzBearer whatsapp_tokenz!https://graph.facebook.com/v17.0/   )r   timeout   zError getting media URL: NurlzNo URL in media response
   zError downloading media: r   media_base_urlzError downloading media z: )CONFIGrequestsr   status_codeloggingerrorjsonr   write_bytescontent	Exceptionstr)media_idfilenamer   responser5   r>   	file_pathes           r   download_media_and_get_url*WhatsAppWebhook.download_media_and_get_urlH   sC   $	&'&9I2J1K(LMG||3H:>H ##s* 9(:N:N9OPQ==?D((5/C89  ||C"EH##s* 9(:N:N9OPQ V$6788CI!!("2"23 *+h66 	MM4XJbQIJ	s+   AD! >D! AD! %;D! !
E+%EEc           	      4   UUU SSUR                  S5      UR                  S5      S.0S.nU S:X  a)  0 UEUR                  S0 5      R                  SS	5      S
S.E$ U S:X  a  UR                  S0 5      R                  S5      nSU S3n[        R                  XV5      nUUR                  S0 5      R                  SS5      UR                  S0 5      R                  S5      UR                  S0 5      R                  S5      S.UR                  S0 5      R                  S5      US.n0 UEUUS.E$ U S:X  a  UR                  S0 5      R                  S5      UR                  S0 5      R                  SS5      UR                  S0 5      R                  S5      UR                  S0 5      R                  SS5      S.n0 UESUS.E$ U S:X  a  UR                  S0 5      R                  S5      nUR                  S0 5      R                  SS5      n	[        U	5      R                  n
S U U
 3n[        R                  XV5      nUUR                  S0 5      R                  SS!5      U	UR                  S0 5      R                  S"5      US#.n0 UEUUS.E$ 0 UES$U  S%3S
S&S'.E$ )(u   Procesar mensaje según su tipoinwhatsappid	timestamp)
message_idrV   )fromrV   type	directionmetadatatextbodyr   N)r]   mediaimageimg_z.jpg	mime_typez
image/jpegwidthheight)rb   rc   caption)rU   ra   
dimensionsrd   r>   audioz	audio/oggduration
voice_noteF)rU   ra   rg   rh   u   [🎧 Audio recibido]documentrL   zdocumento.pdfdoc_zapplication/octet-stream
page_count)rU   ra   rL   rk   r>   u   [❓ Tipo no soportado: ]unsupported)r]   r^   rY   )r   r   rP   r   suffix)msg_typemsg_data
from_phonerV   base_payloadrK   rL   url_publica
media_infofilename_raw	extensions              r   process_message_by_type'WhatsAppWebhook.process_message_by_typeq   s   
 ""*,,t"4!)k!:
 v VR044VR@   ||GR044T:HhZt,H)DDXXK %\\'26::;U%\\'26::7C&ll7B7;;HE $<<488C"	J #   ll7B/33D9%\\'26::;T$LL"599*E&ll7B7;;L%P	J/#  #||J377=H#<<
B7;;JXL \*11IhZ	{3H)DDXXK %\\*b9==kKef(&ll:r:>>|L"J # 28*A>%	 r   c                      [         R                  " U USS0US9nUR                  S:H  UR                  SUR                  S.$ ! [         R                  R
                   a  nSS[        U5      SS.s SnA$ SnAff = f)	z$Enviar payload al servidor WebSocketzContent-Typezapplication/json)rF   r   r<   r=   N)success	http_coderE   rM   Fr   )rB   postrC   r\   
exceptionsRequestExceptionrJ   )endpointr%   r<   rM   rO   s        r   send_to_websocket!WhatsAppWebhook.send_to_websocket   s    	}}');<	H $//36%11$MM	  ""33 	 Q 	 	s   A A A;!A60A;6A; N)   )__name__
__module____qualname____firstlineno__staticmethodr   r)   r6   rP   rw   r   __static_attributes__r   r   r   r   r       s~    , ,
 F F    & &P Z Zx  r   r   /webhookGET)methodsc                     [         R                  R                  S5      n [         R                  R                  S5      nU[        S   :X  a  [        R
                  " S5        U $ [        R                  " S5        [        S5        g)u%   Verificación del webhook de WhatsAppzhub.challengezhub.verify_tokenverify_tokenu$   ✅ Webhook verificado correctamenteu%   ❌ Token de verificación incorrectoi  N)r   argsr   rA   rD   inforE   r   )	challenger   s     r   verify_webhookr      sa       1I<<##$67Lvn--;<=>c
r   POSTc            
          [         R                  " SS9n [        S   (       aN  [        R                  " 5       R                  S5      n[        SU S3S5       nUR                  U 5        SSS5        [        R                  " U 5      n[        R                  U5      (       d!  [        R                  " S	5        [        S
5        US   S   S   S   S   S   S   nUS   S   S   S   S   S   S   n[        R                  US   5      nUS   nUR!                  S[#        [$        R$                  " 5       5      5      n[        R&                  " SU SU 35        [        R)                  XtXa5      n[        R+                  [        S   U[        S   5      n	[        S   (       aw  U	S   (       a	  U	S   S:w  ad  [        R                  " 5       R-                  5       UU	S.n
[        SS5       nUR                  [        R.                  " U
5      S-   5        SSS5        U	S   (       a  [        R&                  " S5        g"[        R                  " S U	S!    35        g"! , (       d  f       GN= f! , (       d  f       N^= f! [        R0                   a$    [        R                  " S#5        [        S
5         g[2         a  n[        R                  " S$[5        U5       35        [        S   (       a[  [        S%S5       nUR                  S&[        R                  " 5        S'[5        U5       S35        SSS5        O! , (       d  f       O= f[        S(5         SnAgSnAff = f))zRecibir mensajes de WhatsAppT)as_textr
   z%Y%m%d_%H%M%Szlogs/last_raw_z.jsonwNu#   ❌ Estructura de mensaje inválidai  r,   r   r-   r.   r/   r0   rX   rY   rV   u   📨 Mensaje recibido: z de ws_endpoint
ws_timeoutrz   r{   r=   )dater%   rM   zlogs/ws_errors.loga
u.   ✅ Mensaje enviado al WebSocket correctamenteu!   ❌ Error enviando al WebSocket: rE   )r   r=   u   ❌ Error decodificando JSONu   ❌ Error procesando mensaje: zlogs/errors.log[z]   )r   get_datarA   r   nowstrftimeopenwriterF   loadsr   r6   rD   rE   r   r   r   inttimer   rw   r   	isoformatdumpsJSONDecodeErrorrI   rJ   )
input_datarV   fr5   rp   contact_datatelefonotipo_mensajemessage_payloadrM   
error_datarO   s               r   receive_messager      s   A%%d3
 '? //@Iyk7=
# > zz*% 99$??MM?@#J =#I.q1'::FqIG}Q'	215g>zJ1M"99(6:JK'LLc$))+.>?	.|nD
KL *AAH

 #44=!< 
 '?HY$78K;PTW;W 002*$J
 *C0A

:.56 1 ILLIJ  MM=hw>O=PQRa >=P 10  45c
 6s1vh?@'?'-!HLLN+2c!fXR89 .--c

sm   AI9 I*E=I9 ')I((I9 9I9 
I% I9 (
I62I9 95M0	M9<M55L3*	M3
M	=MMz/test_recibir.phpc                      [         R                  " 5       n [        R                  " S5        [        R                  " S[        R
                  " U SS9 35        [        SS[        R                  " 5       R                  5       S.5      S4$ ! [         aE  n[        R                  " S	[        U5       35        [        S
[        U5      S.5      S4s SnA$ SnAff = f)z8Endpoint para simular test_recibir.php - URL de callbacku   📞 Callback recibido:z
   Datos:    )indentrz   z Callback procesado correctamente)statusmessagerV   r=   u   ❌ Error en callback: rE   )r   r   r   N)r   get_jsonrD   r   rF   r   r   r   r   r   rI   rE   rJ   )r5   rO   s     r   test_recibirr   =  s    !./z$**T!"<!=>?
 9!113
  	 	  /Ax891v
   	s   BB 
C:CCC/statusc            	          [        SS[        R                  R                  SS5      [        S   [        S   [
        R                  " 5       R                  5       S.5      $ )z*Endpoint para verificar estado del webhookactivez1.0.0r   r   call_back_urlr   )r   versionwebhook_urlcallback_urlwebsocket_endpointrV   )r   r   base_urlreplacerA   r   r   r   r   r   r   r   r   V  sT     ''//	:F/$]3\\^--/  r   __main__configzcert.pemzkey.pemhttpsssl_porti  u,   🔐 SSL habilitado con certificados localeshttpwebhook_portu7   ⚠️  SSL no disponible - certificados no encontradosz   Buscando: u,   🚀 Iniciando WhatsApp Webhook en Python...u   📡 Webhook URL: z://localhost:u   📞 Callback URL: r   u   🔗 WebSocket endpoint: r   u4   ✅ Servidor listo para recibir mensajes de WhatsAppwebhook_host)hostportr
   ssl_context)/__doc__osrF   r   r!   r   rB   r   pathlibr   flaskr   r   r   r   rD   webhook.webhook_configr	   rA   r   appbasicConfigDEBUGmkdirr   router   r   r   r   sslpathjoindirname__file__	cert_pathkey_pathr   exists
SSLContextPROTOCOL_TLS_SERVERload_cert_chainprotocolr   r   printrunr   r   r   <module>r      s  
 
        0 0  1 
 Ho 
'?gmm,L%"	#$**D*9F FT :w'
 (
 :x(C )CJ 1 20 9ug&	 '	 z RWW__RWW__X-FGS]^Iww||BGGOOBGGOOH,EFR[\H K	ww~~i  RWW^^H%=%=nnS%<%<=##Ix8zz*c*<=n%GHi[)*hZ()	
89	xjdV8
DE	 78
9:	%f]&;%<
=>	
@AGGN#Wo	  ; r   