
    _j               	      b   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m	Z	 ddl
mZ ddlmZ ddlmZmZmZ  ee      j'                         j(                  Zedz  Zej/                  d	d	
        e	edz  ddd      Zej3                   ej4                  d              ej6                  ej8                        Zej3                   ej4                  d              ej<                  ej>                  eeg        ej@                  d      Z!	 ddl"m#Z#  e#d        e#ej(                  dz         ddl4m5Z5 ddl6m7Z7  ejp                  dd      jY                         Z9 ejp                  dd      jY                         Z:e9se!jw                  d        ee<      Z=dd d4d!Z>d5d"Z?e=j                  d#d$g%      d&        ZAe=j                  d'd(g%      d)        ZBe=j                  d*d$g%      d+        ZCe<d,k(  rU eD ejp                  d-d.            ZE ejp                  d/d0      ZFe!j                  d1eFeE       e=j                  eFeEd2d	3       yy# e$$ r d e%ej(                  dz        fD ]  Z&ejN                  jQ                  e&      s e)e&d      5 Z*e*D ]w  Z+e+jY                         Z-e-re-j]                  d      sde-vr+e-j_                  dd      \  Z0Z1ejd                  jg                  e0jY                         e1jY                                y 	 ddd       # 1 sw Y   xY w Y w xY w)6u   
Sweet Angels SDR Webhook — porta 5055.

Recebe eventos do Linkia (GoHighLevel) quando um lead responde WhatsApp,
processa com o agente Angel (Claude) e devolve a resposta pelo Linkia.
    )annotationsN)RotatingFileHandler)Path)Any)FlaskjsonifyrequestlogsT)parentsexist_okzwebhook.logi  P    zutf-8)maxBytesbackupCountencodingz1%(asctime)s [%(levelname)s] %(name)s: %(message)s)levelhandlerssdr_webhook)load_dotenvz/opt/mia/.envz
linkia.env)r   #=   )gerar_resposta)send_whatsapp_messageLINKIA_TOKEN LINKIA_LOCATION_IDuD   LINKIA_TOKEN nao configurado — respostas nao serao enviadas ao GHLdefaultc                   |D ]e  }|sd|v rF| }d}|j                  d      D ]  }t        |t              r
||v r||   }d} n |sD|d dg fvsL|c S || v sU| |   d dg fvs`| |   c S  |S )N.TFr   )split
isinstancedict)dr   keyskcurokparts          ;/opt/mia/workspace/clientes/sweet_angels/sdr_webhook/app.py
_get_firstr+   O   s     !8CB c4(TS[d)CB c$B/
!V!T2rN2Q4K!" N    c           	         t        | dddd      }t        | ddd      }t        | dd	d
ddd      }t        | ddd      }t        | ddd      }t        | dd      }t        | dd      }t        | ddd      }||||||||dS )z4
    Normaliza payloads variados do GHL/Linkia.
    	contactId
contact_idz
contact.ididconversationIdconversation_idzconversation.idbodymessagemessageBodytextzmessage.bodyzlastMessage.body	firstName
first_namezcontact.firstNamelastName	last_namezcontact.lastNamephonezcontact.phone	directioninboundr   typemessageTypeWhatsApp)r/   r2   mensagemr8   r:   r;   r<   r>   )r+   )	payloadr/   r2   rA   r8   r:   r;   r<   msg_types	            r*   extrair_payloadrD   d   s     \<J !+->O 	=&*H
 G[,@STJ7J=OPIw9E7KCI'6=*MH !* 	 	r,   z/healthGET)methodsc                 <    t        dddt        t              d      S )NTsweet_angels_sdri  )r(   serviceportlinkia_token_ok)r   boolr    r,   r*   healthrN      s%    %-	  r,   z/webhook/sweet-angelsPOSTc            
        t        j                          } 	 t        j                  dd      xs i }t        j                  dt        j                  |d	      d d
        t        |      }|d   s>t        j                  dt        j                  |d	      d d        t        ddd      dfS |d   s%t        j                  d       t        ddd      dfS t        |d         j                         dk(  r%t        j                  d       t        ddd      dfS t        |d         }|d   rt        |d         nd }t        |d         j                         }t        j                  d||j                  d      |d d        	 t!        |||j                  d      |j                  d      |j                  d      ||d      }t$        s&t        j'                  d!       t        dd"|d#      d fS t)        ||t$        |$      \  }}	}
t+        t        j                          | z
  d%      }t        j                  d&||	||       t        t-        |      |	|
r|
d d nd'||d d d(      |rdfS d)fS # t        $ rB}t        j                  d|t        j                  d d        t        ddd      dfcY d }~S d }~ww xY w# t        $ r:}t        j#                  d|       t        ddt        |      d      d fcY d }~S d }~ww xY w)*NTF)forcesilentzpayload nao-JSON: %s | raw=%si  invalid_json)r(   errorzwebhook recebido: %s)ensure_asciii   r/   z#webhook sem contact_id | payload=%smissing_contact_id   rA   u?   webhook sem mensagem util (ex: evento de sistema) — ignorando
no_message)r(   skippedr<   outboundu,   mensagem outbound — ignorando (evita loop)r2   z%processando contact=%s nome=%s msg=%rr8   r:   r;   )r8   r:   r;   r/   r2   )r/   mensagem_leadcontact_metazerro gerando resposta: %sagent_error)r(   rT   detaili  u,   LINKIA_TOKEN ausente — nao enviando ao GHLlinkia_token_missing)r(   rT   	generated)r/   r4   tokenr2      z1enviado ao GHL ok=%s status=%s dur=%ss contact=%sr   )r(   
ghl_statusghl_body	duracao_sresposta_previewi  )timer	   get_json	Exceptionlogwarningdatar   infojsondumpsrD   strlowerstripgetr   	exceptionr   rT   r   roundrL   )startedrB   edadosr/   r2   r[   respostar(   statusr3   duracaos               r*   webhook_sweet_angelsr|      s   iikGD""e<B
 HH#TZZe%LTc%RSG$E 9JJwU;DSA	Ce.BCDcIIRSd|<=sBB 5$$&*4?@dz:;S@@U<()J7<=N7Oc% 123UYOj)*002MHH/EIIl+]4C-@U!!'#ii5"YY{37+(#2

  		@A+!
  	 	 -'	B DIIK')1-GHH;
FGZ
 2h"&D#JB$TcN     O  D3QTc8JKen=>CCDZ  U115ems1vNOQTTTUs<   I. AJ< .	J977J4.J94J9<	K?/K:4K?:K?/c                 $    t        ddddd      S )NzSweet Angels SDR WebhookzGET /healthzPOST /webhook/sweet-angels)rN   webhook)rI   	endpoints)r   rM   r,   r*   indexr      s"    -#3
  r,   __main__PORT5055HOSTz0.0.0.0zsubindo Flask em %s:%sF)hostrJ   debugthreaded)r$   dict[str, Any]r%   rp   r   r   returnr   )rB   r   r   r   )I__doc__
__future__r   rn   loggingossysrg   logging.handlersr   pathlibr   typingr   flaskr   r   r	   __file__resolveparentBASE_DIRLOG_DIRmkdirlog_handlersetFormatter	FormatterStreamHandlerstdoutstream_handlerbasicConfigINFO	getLoggerrj   dotenvr   ImportErrorrp   envfilepathexistsopenfrawrr   line
startswithr!   r&   venviron
setdefaultangel_agentr   
ghl_clientr   getenvr   r   rk   __name__appr+   rD   routerN   r|   r   intrJ   r   rm   runrM   r,   r*   <module>r      s-   #   	 
  0   ) )>!!#**
V
 dT *
 "m	   GIJ '&&szz2   GIJ   ',,+~1N Og&
@" ,./ ' ,ryy,224RYY3R8>>@ KKVWHo >B * N 9ug& ' "VH5S 6Sl 3  ! zyryy()D299VY'DHH%tT2GGDG=	 O  
@#S<)G%HI @77>>'"g0 @A @C99;D4??3#73d? ::c1-DAqJJ))!'')QWWY?@@ @ @@
@s1   #I :L.
L.A=L	L.L&"L.-L.