§
    }Š›jV.  ã                  óØ  — U d Z ddlmZ ddlZddlmZ ddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ  eddg¬¦  «        Z e¦   «         Zded<    e¦   «         Z G d„ de¦  «        Ze                     d¦  «        d/d„¦   «         Ze                     d¦  «        d0d„¦   «         Z e !                    d ¦  «        d1d!„¦   «         Z"e !                    d"¦  «        d1d#„¦   «         Z#e !                    d$¦  «        d1d%„¦   «         Z$ G d&„ d'e¦  «        Z%e                     d(¦  «        d2d*„¦   «         Z&e !                    d+¦  «        d3d.„¦   «         Z'dS )4z¤FastAPI Presentation Router for Zalo CRM & Webhook Integration.
Strict Hexagonal Architecture COMPLIANT (Outbound network operations delegated to Gateway Adapter).
é    )ÚannotationsN)Údatetime)ÚAny)Ú	APIRouterÚBackgroundTasksÚRequest)Ú	BaseModel)Úrun_in_threadpool)ÚPostgresClient)ÚTelegramBridge)ÚZaloGatewayPort)ÚZaloHttpAdapter)ÚPostgresZaloCrmRepositoryz/crmÚCRM)ÚprefixÚtagsr   Úzalo_gatewayc                  ó~   — e Zd ZU ded<   ded<   ded<   ded<   dZded<   dZded	<   d
Zded<   dZded<   dZded<   dS )ÚWebhookPayloadÚstrÚ
event_nameÚ	sender_idÚsender_nameÚmessageNz
str | NoneÚdisplay_messageÚmember_nameFúbool | NoneÚis_groupÚphone_numberz
int | NoneÚ	timestamp)	Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r   r   r   r    © ó    ú>C:\Projects\DSCons\app\modules\zalo_crm\presentation\router.pyr   r      sŽ   € € € € € € Ø€O€O�OØ€N€N�NØÐÐÑØ€L€L�LØ"&€OÐ&Ð&Ð&Ñ&Ø"€KÐ"Ð"Ð"Ñ"Ø!€HÐ!Ð!Ð!Ñ!Ø#€LÐ#Ð#Ð#Ñ#Ø €IÐ Ð Ð Ñ Ð Ð r&   r   z/webhookÚpayloadÚbackground_tasksr   Úreturnúdict[str, Any]c           	   ƒ  óX  ‡ ‡‡	‡
‡‡‡‡‡‡K  — t          ¦   «         Št          ‰ j        ¦  «        Š‰ j        p‰ j        Šd‰v pd‰v pd‰v p
‰ j        dv p‰Š‰ j        }|‰ j        ‰ j        ‰t          j        ¦   «         t          j        ¦   «         dœŠ	d}|dd t          j        ¦   «         t          j        ¦   «         dœŠd	|› �Š‰||‰t          j        ¦   «         t          j        ¦   «         d
œŠ
t          t          j        ¦   «         ¦  «        }|‰d|‰ j        ‰ j        rt          j        ‰ j        dz  ¦  «        nt          j        ¦   «         dœŠdˆˆ	ˆ
ˆˆfd„}t          |¦  «        ƒ d {V —† dˆˆˆ fd„}|                     |¦  «         dˆˆ ˆfd„}|                     |¦  «         d|dœS )Nõ   SÆ¡n - GiÃ¡m Ä�á»‘cõ   GiÃ¡m Ä�á»‘cõ   SÆ¡n)Ú645566942630634031Ú8729784557598851324©ÚidÚnamer   Úis_internalÚ
created_atÚ
updated_atÚcompany_zalo_1zDSCons Zalo OA)r3   r4   r   r6   r7   Úconv_company_©r3   Úzalo_account_idÚ
contact_idr5   r6   r7   Úcontactg     @�@©r3   Úconversation_idÚsender_typer   Úcontentr    r*   ÚNonec                 ó°   •— ‰                       ‰¦  «         ‰                      ‰¦  «         ‰                      ‰¦  «         ‰                      ‰¦  «         d S )N)Úupsert_contactÚupsert_zalo_accountÚupsert_conversationÚinsert_message)ÚclientÚcontact_dataÚ	conv_dataÚmsg_dataÚ	zalo_datas   €€€€€r'   Ú_save_dbz handle_webhook.<locals>._save_dbe   sY   ø€ Ø×Ò˜lÑ+Ô+Ð+Ø×"Ò" 9Ñ-Ô-Ð-Ø×"Ò" 9Ñ-Ô-Ð-Ø×Ò˜hÑ'Ô'Ð'Ð'Ð'r&   c               “  óÐ   •K  — t          ¦   «         } ‰s$|                      ‰d‰j        › �¦  «        ƒ d {V —† |                      ‰j        ‰j        ‰j        ‰¬¦  «        ƒ d {V —† d S )NzZalo - )r   r   Útextr5   )r   Úcreate_topicr   Úforward_inbound_messager   r   )Úbridger?   r5   r(   s    €€€r'   Údispatch_telegram_forwardz1handle_webhook.<locals>.dispatch_telegram_forwardn   s¨   øè è € ÝÑ!Ô!ˆØð 	XØ×%Ò% oÐ7VÀÔATÐ7VÐ7VÑWÔWÐWÐWÐWÐWÐWÐWÐWØ×,Ò,ØÔ+ØÔ'Ø”Ø#ð	 -ñ 
ô 
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
r&   c               “  ó  •K  — 	 ddl m}   | ¦   «         }|                     ‰j        ‰‰j        ‰¬¦  «        ƒ d {V —† d S # t
          $ r:}dd l}|                     d¦  «                             d|› �¦  «         Y d }~d S d }~ww xY w)Nr   )ÚZaloAiDispatcher)r   r   r   r   zdscons.crm_webhookzError in Zalo AI auto-reply: )	Ú*app.modules.zalo_crm.application.use_casesrU   Úprocess_and_replyr   r   Ú	ExceptionÚloggingÚ	getLoggerÚerror)rU   Ú
dispatcherÚexcrY   r   r(   r   s       €€€r'   Údispatch_ai_replyz)handle_webhook.<locals>.dispatch_ai_reply|   sü   øè è € ð	ØSÐSÐSÐSÐSÐSà)Ð)Ñ+Ô+ˆJØ×.Ò.Ø!Ô+Ø'ØœØ!ð	 /ñ ô ð ð ð ð ð ð ð ð ð øõ ð 	ð 	ð 	ØˆNˆNˆNà×ÒÐ2Ñ3Ô3×9Ò9Ø5°Ð5Ð5ñô ð ð ð ð ð ð ð øøøøð	øøøs   …9A  Á 
BÁ
/A?Á?BÚsuccess)ÚstatusÚ
message_id©r*   rB   )r   Úboolr   r   r   r   r   r   Únowr   ÚuuidÚuuid4r   r    Úfromtimestampr
   Úadd_task)r(   r)   r<   r;   Úmsg_idrM   rS   r^   rH   rI   rJ   r?   r   r5   rK   r   rL   s   `       @@@@@@@@@r'   Úhandle_webhookrj   *   sb  øøøøøøøøøøè è € õ ÑÔ€Fõ �GÔ$Ñ%Ô%€HØÔ%Ð<¨Ô)<€Kà Ð,ð 	Ø˜[Ð(ð	à�[Ð ð	ð ÔÐ MÐMð	ð ð ð Ô"€JàØÔ#ØÔ,Ø"Ý”l‘n”nÝ”l‘n”nðð €Lð '€OàØ ØÝ”l‘n”nÝ”l‘n”nðð €Ið 3 jÐ2Ð2€OàØ*Ø Ø"Ý”l‘n”nÝ”l‘n”nðð €Iõ •”‘”ÑÔ€FàØ*Ø ØØ”?àÔð•XÔ+¨GÔ,=ÀÑ,FÑGÔGÐGåŒ\‰^Œ^ð	ð 	€Hð(ð (ð (ð (ð (ð (ð (ð (ð (ð (õ ˜HÑ
%Ô
%Ð%Ð%Ð%Ð%Ð%Ð%Ð%ð	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð 	
ð ×ÒÐ7Ñ8Ô8Ð8ðð ð ð ð ð ð ð ð$ ×ÒÐ/Ñ0Ô0Ð0à¨vÐ6Ð6Ð6r&   z/telegram_webhookÚrequestr   c              ƒ  ó”   K  — |                       ¦   «         ƒ d{V —†}t          ¦   «         }|                     |¦  «        ƒ d{V —† ddiS )z%Handle webhook updates from Telegram.Nr`   Úok)Újsonr   Úprocess_webhook)rk   ÚupdaterR   s      r'   Úhandle_telegram_webhookrq   “   sc   è è € ð —<’<‘>”>Ð!Ð!Ð!Ð!Ð!Ð!€FÝÑÔ€FØ
×
 Ò
  Ñ
(Ô
(Ð(Ð(Ð(Ð(Ð(Ð(Ð(Ø�dÐÐr&   z/qrc               ƒ  óD   K  — t                                ¦   «         ƒ d{V —†S )z?Proxy QR Code fetch to Node.js Zalo Bridge via Gateway Adapter.N)r   Úget_qrr%   r&   r'   Úget_zalo_qrrt   œ   s,   è è € õ ×$Ò$Ñ&Ô&Ð&Ð&Ð&Ð&Ð&Ð&Ð&r&   z/statusc               ƒ  óD   K  — t                                ¦   «         ƒ d{V —†S )z>Proxy status check to Node.js Zalo Bridge via Gateway Adapter.N)r   Ú
get_statusr%   r&   r'   Úget_zalo_statusrw   ¢   s,   è è € õ ×(Ò(Ñ*Ô*Ð*Ð*Ð*Ð*Ð*Ð*Ð*r&   z/friendsc               ƒ  ó   K  — 	 t                                ¦   «         ƒ d{V —†\  } }dd„}t          || |¦  «        ƒ d{V —†\  }}t          |                     ¦   «         ¦  «        t          |                     ¦   «         ¦  «        z   }|t          |¦  «        t          |¦  «        dœS # t          $ r}g t          |¦  «        dœcY d}~S d}~ww xY w)	zSFetch real friends and groups from Zalo via Gateway Adapter and sync to PostgreSQL.NÚfriends_dataúlist[dict[str, Any]]Úgroups_datac                ó  — t          ¦   «         }|                     ¦   «         }i }|D ]A}|                     d¦  «        s*|d         |d         |d         |d         dddœ||d         <   ŒB| D �]}|                     dd¦  «        }|                     dd¦  «        }|sŒ2|d	k    p|d
k    pd
|v pd|v }	|                     dd¦  «        p|	}
|	rdn|}||d<   |
|d<   d|d<   |||<   |||                     d¦  «        |
t          j        ¦   «         t          j        ¦   «         dœ}|                     |¦  «         d|› �d||
t          j        ¦   «         t          j        ¦   «         dœ}|                     |¦  «         �Œi }|D ]‡}|d         dk    rŒ|                     dd¦  «        p/d|                     dd¦  «        v pd|                     dd¦  «        v }|r0|d         |d         ddddœ||d         <   |d         |v r	||d         = Œˆ|D ]ö}|                     dd¦  «        }|r|dk    rŒ!|                     dd¦  «        }d|d<   d|d<   |||<   |                     |d ¦  «         |||                     dd¦  «        › d�dt          j        ¦   «         t          j        ¦   «         dœ}|                     |¦  «         d|› �d|dt          j        ¦   «         t          j        ¦   «         dœ}|                     |¦  «         Œ÷||fS )Nr   r3   r4   r   r5   FÚ )r3   r4   ÚphoneNumberr5   r   Úavatarr1   r/   r.   r-   r~   r2   r9   r8   r:   Ú
gridVerMapu   NhÃ³mÚCtyT)r3   r4   r5   r   r   u
   NhÃ³m ZaloÚtotalMemberr   u    thÃ nh viÃªn)r   Úget_all_contactsÚgetr   rd   rD   rF   Úpop)ry   r{   Ú	pg_clientÚdb_contactsÚmerged_friendsÚdb_cÚfÚraw_namer<   Úis_directorr5   Údisplay_namerI   rJ   Úmerged_groupsÚis_grpÚgÚgroup_idÚ
group_names                      r'   Ú_sync_db_logicz(get_zalo_friends.<locals>._sync_db_logic®   sÖ  € Ý&Ñ(Ô(ˆIØ#×4Ò4Ñ6Ô6ˆKà8:ˆNØ#ð 	ð 	�Ø—x’x 
Ñ+Ô+ð à" 4œjØ $ V¤Ø'+¨NÔ';Ø'+¨MÔ':Ø$)Ø"$ð2ð 2�N 4¨¤:Ñ.øð "ð %9ñ %9�ØŸ5š5 ¨Ñ,Ô,�ØŸUšU 4¨™_œ_�
Ø!ð ØàÐ"7Ò7ð 2Ø 6Ò)ð2à Ð)ð2ð &¨Ð1ð	 ð  Ÿeše M°5Ñ9Ô9ÐH¸[�Ø8CÐQÐ4Ð4È�Ø(��&‘	Ø#.��-Ñ Ø %��*‘à-.�˜zÑ*ð %Ø(Ø$%§E¢E¨-Ñ$8Ô$8Ø#.Ý"*¤,¡.¤.Ý"*¤,¡.¤.ð ð  �ð ×(Ò(¨Ñ6Ô6Ð6ð 7¨*Ð6Ð6Ø'7Ø",Ø#.Ý"*¤,¡.¤.Ý"*¤,¡.¤.ðð �	ð ×-Ò-¨iÑ8Ô8Ð8Ñ8à79ˆMØ#ð 7ð 7�Ø˜”: Ò-Ð-Øð —H’H˜Z¨Ñ/Ô/ð 5Ø $§(¢(¨6°2Ñ"6Ô"6Ð6ð5à §¢¨°Ñ 4Ô 4Ð4ð ð
 ð 	7à" 4œjØ $ V¤Ø'+Ø$(Ø"$ð1ð 1�M $ t¤*Ñ-ð ˜D”z ^Ð3Ð3Ø*¨4°¬:Ð6øà ð 9ð 9�ØŸ5š5  r™?œ?�Øð  8¨|Ò#;Ð#;ØØŸUšU 6¨<Ñ8Ô8�
Ø $��*‘Ø#'��-Ñ à*+�˜hÑ'Ø×"Ò" 8¨TÑ2Ô2Ð2ð #Ø&Ø'(§u¢u¨]¸AÑ'>Ô'>Ð$MÐ$MÐ$MØ#'Ý"*¤,¡.¤.Ý"*¤,¡.¤.ð ð  �ð ×(Ò(¨Ñ6Ô6Ð6ð 5¨(Ð4Ð4Ø'7Ø"*Ø#'Ý"*¤,¡.¤.Ý"*¤,¡.¤.ðð �	ð ×-Ò-¨iÑ8Ô8Ð8Ð8à! =Ð0Ð0r&   )ÚfriendsÚtotalÚgroups_count)r”   r[   )ry   rz   r{   rz   )r   Úget_friends_and_groupsr
   ÚlistÚvaluesÚlenrX   r   )r”   Úgroupsr“   rˆ   rŽ   Úcombinedr]   s          r'   Úget_zalo_friendsr�   ¨   s  è è € ðx2Ý ,× CÒ CÑ EÔ EÐEÐEÐEÐEÐEÐE‰ˆ�ðk	1ð k	1ð k	1ð k	1õZ /@ÀÐPWÐY_Ñ.`Ô.`Ð(`Ð(`Ð(`Ð(`Ð(`Ð(`Ñ%ˆ˜Ý˜×-Ò-Ñ/Ô/Ñ0Ô0µ4¸×8LÒ8LÑ8NÔ8NÑ3OÔ3OÑOˆàÝ˜‘]”]Ý Ñ.Ô.ð
ð 
ð 	
øõ
 ð 2ð 2ð 2Ø­¨C©¬Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1øøøøð2øøøs   „B"B' Â'
CÂ1CÃCÃCc                  ó2   — e Zd ZU ded<   ded<   dZded<   dS )ÚSendMessageRequestr   Úuser_idr   Fr   r   N)r!   r"   r#   r$   r   r%   r&   r'   rŸ   rŸ   &  s5   € € € € € € Ø€L€L�LØ€L€L�LØ!€HÐ!Ð!Ð!Ñ!Ð!Ð!r&   rŸ   z/send_messageÚreqc              ƒ  ó  ‡ K  — 	 t                                ‰ j        ‰ j        t	          ‰ j        ¦  «        ¬¦  «        ƒ d{V —†}dˆ fd„}t          |¦  «        ƒ d{V —† |S # t          $ r}t          |¦  «        ddœcY d}~S d}~ww xY w)	z.Send real message to Zalo via Gateway Adapter.)Ú	target_idr   r   Nr*   rB   c                 óÜ   •— t          ¦   «         } d‰j        › �}t          t          j        ¦   «         ¦  «        |dd‰j        t          j        ¦   «         dœ}|                      |¦  «         d S )Nr9   Úuserr8   r>   )	r   r    r   re   rf   r   r   rd   rG   )r†   Úconv_idrK   r¡   s      €r'   Ú_save_messagez(send_zalo_message.<locals>._save_message6  sm   ø€ Ý&Ñ(Ô(ˆIØ3 c¤kÐ3Ð3ˆGå�$œ*™,œ,Ñ'Ô'Ø#*Ø%Ø-Øœ;Ý%œ\™^œ^ðð ˆHð ×$Ò$ XÑ.Ô.Ð.Ð.Ð.r&   F)r[   r_   rb   )	r   Úsend_messager    r   rc   r   r
   rX   r   )r¡   Úres_datar§   r]   s   `   r'   Úsend_zalo_messagerª   ,  sâ   øè è € ð5Ý%×2Ò2Ø”kØ”KÝ˜#œ,Ñ'Ô'ð 3ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆð	/ð 	/ð 	/ð 	/ð 	/ð 	/õ   Ñ.Ô.Ð.Ð.Ð.Ð.Ð.Ð.Ð.ØˆøÝð 5ð 5ð 5Ý˜S™œ¨eÐ4Ð4Ð4Ð4Ð4Ð4Ð4Ð4øøøøð5øøøs   …AA! Á!
BÁ+BÁ<BÂBz/messages/{contact_id}r<   r   c                ó’   — t          ¦   «         }d| › �}|                     |¦  «        }|s|                     d| › �¦  «        }d|pg iS )z:Fetch all messages for a specific contact from PostgreSQL.r9   Úconv_company_zalo_1_Úmessages)r   Úget_messages_by_conversation)r<   r†   r¦   r­   s       r'   Úget_contact_messagesr¯   I  sh   € õ Ñ Ô €IØ*˜jÐ*Ð*€GØ×5Ò5°gÑ>Ô>€HØð 
Ø×9Ò9Ø/ :Ð/Ð/ñ
ô 
ˆð ˜˜ BÐ'Ð'r&   )r(   r   r)   r   r*   r+   )rk   r   r*   r+   )r*   r+   )r¡   rŸ   r*   r+   )r<   r   r*   r+   )(Ú__doc__Ú
__future__r   re   r   Útypingr   Úfastapir   r   r   Úpydanticr	   Ústarlette.concurrencyr
   Úapp.core.postgresr   Ú4app.modules.integrations.application.telegram_bridger   Ú3app.modules.zalo_crm.domain.ports.zalo_gateway_portr   Ú>app.modules.zalo_crm.infrastructure.adapters.zalo_http_adapterr   ÚDapp.modules.zalo_crm.infrastructure.repositories.zalo_crm_repositoryr   Úrouterr   r$   Úcrm_repositoryr   Úpostrj   rq   r„   rt   rw   r�   rŸ   rª   r¯   r%   r&   r'   ú<module>r¾      sã  ððð ð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ð 7Ø Ð Ð Ð Ð Ð Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3à ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø OÐ OÐ OÐ OÐ OÐ OØ OÐ OÐ OÐ OÐ OÐ OØ ZÐ ZÐ ZÐ ZÐ ZÐ Zðð ð ð ð ð ð 
ˆ˜&¨ wÐ	/Ñ	/Ô	/€ð !0 Ñ 1Ô 1€Ð 1Ð 1Ð 1Ñ 1Ø*Ð*Ñ,Ô,€ð	!ð 	!ð 	!ð 	!ð 	!�Yñ 	!ô 	!ð 	!ð ‡‚ˆZÑÔðe7ð e7ð e7ñ Ôðe7ðP ‡‚Ð Ñ!Ô!ðð ð ñ "Ô!ðð ‡‚ˆEÑÔð'ð 'ð 'ñ Ôð'ð
 ‡‚ˆIÑÔð+ð +ð +ñ Ôð+ð
 ‡‚ˆJÑÔðz2ð z2ð z2ñ Ôðz2ðz"ð "ð "ð "ð "˜ñ "ô "ð "ð ‡‚ˆ_ÑÔð5ð 5ð 5ñ Ôð5ð8 ‡‚Ð$Ñ%Ô%ð	(ð 	(ð 	(ñ &Ô%ð	(ð 	(ð 	(r&   