HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/buyercall/blueprints/widgets/__pycache__/routing.cpython-310.pyc
o

�weJ��@s�ddlZddlZddlZddlZddlmZddlZddlmZmZ	m
Z
ddlmZm
Z
ddlmZddlZddlZddlmmZddlmZddlmZddlmZmZdd	lmZmZm Z!m"Z"dd
l#m$Z$ddl%m&Z&dd
l'm(Z(ddl)m*Z*ddl+m,Z,dZ-dZ.dZ/dZ0dZ1e�2e3�Z4e$�Z5Gdd�de6�Z7Gdd�de6�Z8d3dd�Z9		d4dd�Z:dd �Z;d!d"�Z<Gd#d$�d$e=�Z>Gd%d&�d&e>�Z?d'd(�Z@d)d*�ZAd+d,�ZBd-d.�ZCd/d0�ZDd1d2�ZEdS)5�N)�datetime)�url_for�current_app�request)�and_�or_)�TwilioRestException)�db)�_try_renderer_template)�first�	to_string)�
BusyAgents�CallStorage�InboundCallState�subaccount_client)�WebhookUtil�)�Agent)�User)�Lead)�format_phone_number�i�QzHello ... ..zThe lead's name is: {} . {} .zThe lead is asking: {}. c@�eZdZdS)�FileFormatExceptionN��__name__�
__module__�__qualname__�rr�F/home/arjun/projects/buyercall/buyercall/blueprints/widgets/routing.pyr+�rc@r)�NoAgentsExceptionNrrrrrr!/r r!�cKsz|r;|r;t|�}tj�|tjk|jtjk��ttjdtjktjdtjk���	�}|r;t
�d�|j
|j
|j��dSdS)N�in-progress�ringingzTCancelling widget {0} call request. Lead {1} with phonenumber {2} currently on call.TF)�	normalizer�query�filter�phonenumber�partnership_account_idr�STATUSES�statusr�log�info�format�id)�widget�phoneNumber�kwargs�phone_number�lead_on_callrrr�phonecall_inprogress3s,
���	��r5r$cKs@|jdur
td�|j���|jj}	|jj}
|j}t|�}|s)|s)t�|j	|�\}}tj
�|tjk|j	tj	k���}|durD|j
}
|j}nd}
d}tdid|j	�d|�d|�d|�d|�d|
�d	|�d
t���dd�d
|�d|	�d|j�d|�d|�d|�d|	�d|
��}tj�|�tj��ddlm}||||||j	�|S)Nz)Widget {} has no inbound phone associatedz	no statusr)�	firstname�lastname�emailr(�progress_status�question�	starttime�	call_type�outboundr+�my_phone�widget_guid�additional_info�call_source�agent_assigned_id�originating_number�
inbound_id�)�add_contactr)�inbound�	Exceptionr.r/r(�namer%r�get_last_known_namer)r&r'rr9rBr�utcnow�guidr	�session�add�commit�tasksrF)r0�	firstName�lastName�emailAddressr1�	sourceTagr:r+r2r>rDr3�
previous_leadr9�agent_assigned�leadrFrrr�add_widget_leadJs|
������������	�
���
�����
rXc
Cszt|���}}|�d�s|�t�dddddd���}|�d�r"|St|�dkr,d|St|�dkr;|�d�r;d|S|S)	z5 Convert a US phone number into an E.123 format.
    zsip:r")� �.�(�-�)�+�
z+1��1)�str�strip�
startswith�	translate�	maketrans�len)r3�strippedrrrr%�s

r%cCs*dd�t|jdd�d�D�}t�|�}|S)z3Return a list of available agent IDs for a widgets.cSsg|]	}|jjr|j�qSr)�agent�
available_now�agent_id)�.0�asgrrr�
<listcomp>�s��z+get_available_agent_ids.<locals>.<listcomp>cSs|jS�N)�order��xrrr�<lambda>�sz)get_available_agent_ids.<locals>.<lambda>)�key)�sorted�assignmentsr
�filter_from)r0�	agent_ids�free_agentsrrr�get_available_agent_ids�s
�
rzc@sReZdZdd�Zdd�Zdd�Zdd�Z				dd
d�Zdd
�Zdd�Z	dd�Z
d	S)�RoutingcC�
||_dSro��client��selfr~rrr�__init__��
zRouting.__init__cCs�tjtjdtjdd�}t||�}d�|�}|���|js#||_n		Wd�dSWd�n1s6wY|�|dd�}|D]}|�	d	�\}}	t
|�|krbt�d
�|��|j
j�|	�qDtjd|_tj�tj|k���}
||
_tj��dS)
z� Save the agent on call to the database for this lead.
        Return True if this is the agent chosen for the call, or False
        if some other agent picked up first.
        �REDIS_CONFIG_URL�REDIS_CONFIG_PORT��host�portzLIST{}NFr����_zCanceling call for agent {}...�callIdT)�redis�StrictRedis�app�configrr.�lockrk�lrange�split�intr,r-r~�calls�hangupr�args�agent_call_sidrr&r'r/rr	rMrO)r��lead_idrk�redis_db�storage�called_agents_keyr��call�a�sidrWrrr�save_lead_agent�s,


���
zRouting.save_lead_agentcC��tjtjdtjdd�}t||j�}|jj}|s|jjj}|j	|_
|��tj
|_t�d|j�t|�}|sQt�d�|j��d|_tj��t||�t|��|jdr]|�|�|S|jdrgt�|�|�|||�|S�	Nr�r�r��operational_start_callz"No agents available for widget {}.�missed�routeSimultaneously�
routeRandomly� r�r�r�r�rr/�partnership_account�subscription�partnership�twilio_subaccount_sid�subaccount_sid�clear_callback_cnt�State�NEW�state�	webhooker�trigger_generic_webhookrzr,�warningr.r+r	rMrO�send_notify_emailr!�options�schedule_call_parallel�random�shuffle�route_sequential�r�r0rWr�r�r�rxrrr�	call_lead�s.






zRouting.call_leadcC�ddlm}|�|j�dS�NrE)�
call_parallel)rPr��delayr/�r�rWr�rrrr���zRouting.schedule_call_parallelNc
	sPtjtjdtjdd�}tj�tj|k���}|s!t	�
d�dSddlm}
m
}|j�|j|jk���}|
j�|
j|jk���}t||�}t|j|j�}d}t|j�fdd	��}|sht	�d
��j|j��dS|jdkrq�j}n*|jdkrz�j}n!|jd
kr��j}�jr�d�jnd}ntd�t|j��j|j���|jj|||||||d�S)�D Call either the agent's phone number, mobile, or extension
        r�r�r�zLead not found in the databaseNr��Partnership�PartnershipAccountc�|j�jkSro�rkr/rq�rirrrs�z+Routing.call_agent_number.<locals>.<lambda>z2Cannot find agent {} in widget {}'s list of agents�phone�mobile�	extension�wwww�1Unknown calling method {} for agent {}, widget {})�to�from_�url�status_callback�status_callback_event�send_digits�timeout)r�r�r�r�rr&r'r/rr,r��partnership.modelsr�r�r)�partnership_idrrr�rv�errorr.�	full_name�
contact_usingr(r�r�rH�reprr��create)r�rir0r�r�r��
status_eventsr�r��
if_machiner2r�rWr�r��partner_account�partnerr��
twilio_clientr��war�rr�r�call_agent_number�sT
�
��


���zRouting.call_agent_numberc	Cs~tjtjdtjdd�}t�|�}d}|r5tj�t	tj
|j
ktj|dk����}|r-n|dd�}|st
�d�|j��|rI|dusI|jdkrwt
�d�|j��|�d	�|j�d
td�|jdkrud|_tj��t||�t|�dS|�d
�|j�dtd�zt
�d�|j|j��|�||||�tj��WdSty�t
�d�|d��|�|dd�||�YdSw)Nr�r�r�rrE�The lead call status is: {}�	completed�'No more agents available for widget {}.�	CONNECT{}r�-1r��CALL{}��0�"Trying call from {} to agent {}...z"Error caling agent {}; retrying...)r�r�r�r�r
rwrr&r'rr)r/rr,r-r.r+r��setex�DAYSr	rMrOr��schedule_retries�debugrI�call_agent_sequentialrr�)r�rxr0rWr�rirrrr�'sN

���	�


���zRouting.route_sequentialc
CsZ|j||td|j|jddd�td|j|j|jt|dd��ddd�gd�t|jj|jd	�S)
N�twilio_api.agent_digit_promptT�https�r�rk�	_external�_schemez'twilio_api.agent_sequential_call_statusrE)r?r�rk�other_agentsr�r��r$�answeredr��r�r�r�r�r�r�)r�rr/rLr�
AGENT_TIMEOUTrGr(�r�rWrir0rxrrrr�Ts0��	�zRouting.call_agent_sequentialcCsH|j||td|j|jddd�td|j|jddd�gd�t|jj|jd�S)	Nr�Tr�r�z%twilio_api.agent_parallel_call_status)rkr�r�r�r�r�)r�rr/r�rGr(�r�rWrir0rrr�call_agent_parallelns,���zRouting.call_agent_parallel�NNNNNN)rrrr�r�r�r�r�r�r�r�rrrrr{�s!#
�7-r{c@sLeZdZdd�Z	dd�Zdd�Z		ddd	�Zd
d�Zdd
�Zdd�Z	dS)�BandwidthRoutingcCr|ror}rrrrr��r�zBandwidthRouting.__init__cCr�r�r�r�rrrr��s.






zBandwidthRouting.call_leadcCr�r�)�bw_tasksr�r�r/r�rrrr��r�z'BandwidthRouting.schedule_call_parallelNc
sP|
�dd�}|
�dd�}|
�dd�}
t|j�fdd��}|s.t�d��j�j|j��t��|j	dkr7�j
}n |j	d	kr@�j}n|j	d
krI�j
}ntd�t
|j	��j|j���dd
lm}|�|�}|rg|}nt|�}tdd|ddd�}tdd|ddd�}|jjj||||
|dt||ddddd�d�}t�d�|��t�|�}|�dd�}|S)r��answer_callback_urlr"�answer_fallback_callback_url�disconnect_callback_urlcr�ror�rqr�rrrs�r�z4BandwidthRouting.call_agent_number.<locals>.<lambda>z7Cannot find agent {} ({}) in widget {}'s list of agentsr�r�r�r�r��Phonezbw_outbound.manual_amd_webhookriTr�)�partyr�r�r�z'bw_outbound.manual_amd_fallback_webhookzstart-agent-widget-outboundr�rE�x)�callbackUrl�fallbackUrl�speechThreshold�speechEndThreshold�silenceTimeout�detectionTimeout)�c_from�c_torrr�tag�call_timeout�machine_detectionzThe BW call API error is: {}r�)�getrrvr,r�r.r�r/�
ValueErrorr�r(r�rHr��(buyercall.blueprints.phonenumbers.modelsr�mobile_sip_urirrr~r�r�r��json�loads)r�rir0r�r�r�r�r�r�r�r2rrrr�r�r�buyercall_sip_lookup�amd_callback_url�amd_fallback_callback_url�
agent_call�json_call_string�
agent_call_idrr�rr��sz��


��
����
z"BandwidthRouting.call_agent_numberc
Cs�tjtjdtjdd�}t�|�}d}|r5tj�t	tj
|j
ktj|dk����}|r-n|dd�}|st
�d�|j��|rI|dusI|jdkrwt
�d�|j��|�d	�|j�d
td�|jdkrud|_tj��t||�t|�dS|�d
�|j�dtd�zt
�d�|j|j��|�||||�tj��WdSty�}zt
�d�|d|��|�|dd�||�WYd}~dSd}~ww)Nr�r�r�rrEr�r�r�r�rr�r�r�r�r�r�z.Error calling agent {}; Error: {}; retrying...r")r�r�r�r�r
rwrr&r'rr)r/rr,r-r.r+r�r�r�r	rMrOr�r�r�rIr�rHr�)r�rxr0rWr�ri�errrr�	sX�

���	�


��� ��z!BandwidthRouting.route_sequentialcCsv|j||td|j|j|jjddd�td|j|j|jjddd�td|j|j|jjt|dd��ddd�t|jj|jd	�S)
N�0bw_outbound.widget_outbound_agent_answer_webhookTr��r�rk�from_tnr�r��9bw_outbound.widget_outbound_agent_answer_fallback_webhookz=bw_outbound.widget_sequence_outbound_agent_disconnect_webhookrE)r�rkr!r�r�r��rrrr�r�r�)r�rr/rGr(rr�r�rrrr�8s@���	�z&BandwidthRouting.call_agent_sequentialc
Csh|j||td|j|j|jjddd�td|j|j|jjddd�td|j|j|jjddd�t|jj|jd�S)NrTr�r r"z=bw_outbound.widget_parallel_outbound_agent_disconnect_webhookr#)r�rr/rGr(r�r�rrrr�Zs>����z$BandwidthRouting.call_agent_parallelr�)
rrrr�r�r�r�r�r�r�rrrrr��s'
�L/"r�cCs�tjtjdtjdd�}t}|�dt|j��}|jr&|t	�
|j|j�7}|j
r1|t�
|j
�7}|j�dd�rC||j�dd���7}|rN|�d	�sN|d
7}|durh|dkrh|jdurh|j��dkrh|d
|}|S)z� Builds the text that the call center agent will head before picking up a
    call. Agent Text = Custom Lead Message + Fullname + Question + Hidden Information + .
    r�r�r�zCUSTOM_LEAD_MESSAGE:�addHiddenInformationF�hiddenInformationr"rZz. N�adfz . . . )r�r�r�r��AGENT_WHISPER_HELLOrrbr/r��AGENT_WHISPER_LEAD_NAMEr.r6r7r:�AGENT_WHISPER_QUESTIONr�rc�endswithrA�lower)r0rWr��
agent_text�custom_lead_messagerrr�get_agent_text|s �(r.cCs4|dvrdS|dvrdS|dvrdS|dvr|SdS)	zB Translate a Twilio call status into a Buyercall lead status.
    )�busy�failed�canceledr�)z	no-answer�
unanswered)�	initiated�queuedr$)r#r��otherr)�call_statusrrr�	to_status�sr7cCs|ddlm}t||�|jdur�t|j���dkr�d|j}|j}|j	}|j
}|jj}ddl
m}|j�|j|jk���}	|durK|durK|d|7}|durY|durY|d	|7}|durg|durg|d
|7}|j�dd�r�|jd
ur�|j�dd���}
|
dur�|
dur�|
dur�|d|
7}t|j|�}t|�dkr�t�d�|dur�t|�dkr�|||	jd|d�dSdSdSdSdSdS)Nr��send_ses_emailTr&�
Call status: )r�r"�, Agent name: �, Call source: �, Phonenumber: r$Fr�r%rYz, Additional Information: zSending CRM redirect email.zADF lead notification��
recipients�p_id�subject�text)�buyercall.lib.util_ses_emailr9r��is_adfrbrAr+r+�
agent_name�adf_notification_emails�sourcerGr(�'buyercall.blueprints.partnership.modelsr�r&r'r/r)rr�rrc�update_adf_commentrgr,r�r�)rWr0r9�comment_textrE�
adf_emails�lead_source�widget_phonenumberr�r��hidden_info�
email_bodyrrr�after_call_events�sD

�

��rPc
Cs�ddlm}tjtjdtjdd�}�z|jdrWdS|jdr*|jdkr*WdStj	�
tj|jktjtj
�d	�tjd
k���}|j}tj�d�|��dd
lm}m}|j	�
|j|jk���}|j	�
|j|jk���}	t|�}
t�d�}|j�|��d�|
d<|j �|��d�|
d<|j!|
d<|	j"|
d<|	j#|
d<|j$r�d|
d<d�%|j$d|j&f�|
d<|j'r�|j'j�(dd�|
d<|j)r�|j)|
d<|jdkr�t*d;ddi|
��}|||	j|	j"d |d!�nt*d<ddi|
��}
|||	j|	j"d#|
d!�|j+d$u�r$t,|j-��.�d%k�r'|j/}|j0}|j1j2}d&|j|
d'<d|
d(<d|
d)<d|
d*<|j"}|�r+||
d+<nd|
d+<|j}|�r:||
d,<nd|
d,<|�(d-t,|j��}|du�rQ||
d(<|�(d.t,|j��}|du�rd||
d)<|�(d/t,|j��}|du�rw||
d*<|du�r�|du�r�t3|�dk�r�|
d'd0||
d'<|j)du�r�|j)du�r�|j)|
d1<|
d'd2|j)|
d'<|du�r�|du�r�|
d'd3||
d'<d|
d4<d	|
d5<dd6l4m5}m6}|j	�
|j|j7k|j|jk���}|�r|j8�r|j	�
|j|j8k���}|�rd$|
d5<|j9|
d4<|�r*t3|�dk�r-t*d=dd8i|
��}|||	j|	j"d9|d:�WdSWdSWdSWdSWdSt:�yJ}zt;�<t=�>��WYd}~dSd}~ww)>Nrr8r�r�r��
notifyNone�notifyMissedLeadsr�F�adminzThe email list are {}rr�z
US/Easternz%c�
created_on�
updated_on�adf_updated_on�company�partner_logozCaller Name:�caller_name_labelr"rY�caller_namer%�	referencerA�widgets/mail/missed_lead�ext�htmlz - Missed lead notification)r?r@rAr^�widgets/mail/captured_leadz - Answered lead notificationTr&r:�
lead_comments�vehicle_year�vehicle_make�
vehicle_model�vendor_name�call_lead_idzCUSTOM_LEAD_YEAR:zCUSTOM_LEAD_MAKE:zCUSTOM_LEAD_MODEL:r;�receiverr<r=�
campaign_name�campaign_exists)�Contact�	Campaigns�widgets/mail/adf_lead�txtz - ADF lead notificationr>)r\)r_)rk)?rCr9r�r�r�r�r�r+rr&r'r)�active�is_deactivated�is_�roler�emails�loggerr�r.r�r�r�r/r��vars�pytz�timezonerT�
astimezone�strftimerU�interaction_timerI�logor6�joinr7r0rrGr
rDrbrAr+rErFrGr(rg�$buyercall.blueprints.contacts.modelsrirj�
contact_id�campaign_id�display_namerHr,r��	traceback�
format_exc)rWr0r9r��userrqr�r�r�r��ctx�eastern�missed_lead_email_template�captured_lead_email_templaterErKr(�
dealershipre�custom_lead_vehicle_year�custom_lead_vehicle_make�custom_lead_vehicle_modelrirj�contact�campaign�adf_lead_email_templaterrrrr��s�


��





�� 




"


��
��
��8	��r�c

CsXtjtjdtjdd�}|jdvrt�d|j�dSt||j�}|j	}|j
jd}t|�|ks5||s7dSt
||�}t�d�|j|��d	|_tj��d
dlm}|j�|j|jk���}z-|jdkr{d
dlm}|j|jg|dd�WdSd
dlm}|j|jg|dd�WdSty�}	zt�d�|j|	��WYd}	~	dSd}	~	ww)Nr�r�r�)r$r�z+Cannot schedule retries yet/lead status is �retryRoutingFz/Scheduling retry call for lead {} in {} minutesz
retry-pendingrr�	bandwidthrE)�
call_again�<)r��	countdownTz;Unable to perform call-back or retry for lead: {} Error: {})r�r�r�r�r+r,r�rr/�callback_cntr0r�rgr�r-r.r	rMrO�phonenumbers.modelsrr&r'rDr�providerr�r��apply_asyncrPrH)
rWr�r��cnt�routing_delaysr�r�numberr�rrrrr�Ws<
�

���r�c	Cs6tjtjdtjdd�}|�dt|��}|dkr�t|�dkr�zet�|�}|�	d�}|dks3|dkr~|�	d�durp|�	d�}|�	d	�durf|�	d	�j
}t|�dkr]|d
||�	d	�_
n|||�	d	�_
nt�|d	�}||_
nt�
d�tj|dd
d�WSt�
d�WdSty�t�
dt���YdSwdS)Nr�r�r�zCUSTOM_LEAD_XML:r�prospectr"�customer�commentsz - z!No customer found in the XML lead�utf8�xml)�encoding�methodz!No prospect found in the XML leadz#Error parsing XML file. Exception: )r�r�r�r�rrbrg�et�
fromstring�findrB�
SubElementr,r��tostringr�sys�exc_info)	r��commentr��custom_lead_xml�	xmlentityr�r��customer_comments�new_commentrrrrI�s2



��rI)r")r"r"r"r"r"r"r$)F�loggingr�rr�rr�flaskrrr�r�
sqlalchemyrr�twilio.base.exceptionsrr�rt�xml.etree.ElementTree�etree�ElementTreer��buyercall.extensionsr	�buyercall.lib.flask_mailplusr
�buyercall.lib.util_listsrr�buyercall.lib.util_twilior
rrr�r�buyercall.lib.util_webhooksr�
agents.modelsr�user.modelsr�leads.modelsr�buyercall.blueprints.filtersrr�r�r'r(r)�	getLoggerrr,r�rHrr!r5rXr%rz�objectr{r�r.r7rPr�r�rIrrrr�<module>s^


�<gt++