+
    jTjx                       R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt]P                  P                  RR4      P                  R4      tRtR R ltRR	 R
 lltR R ltR R ltR R ltR R ltR R ltR R ltR R ltR R ltRR R lltR# )zSmartlead cold-email logic for the jarvis-tools service (Railway).
Key from env SMARTLEAD_API_KEY. Env-based so every device reaches it via the
one connector. Isolated from the memory service (no ML deps).
)annotationsNSMARTLEAD_URLz"https://server.smartlead.ai/api/v1/zuMozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36c                   V ^8  d   QhRR/# )   returnbool )formats   "L/Users/ahmed/devFolder/Ultron/claude-voice/jarvis-tools-service/smartlead.py__annotate__r      s     9 9D 9    c                 T    \        \        P                  P                  R R4      4      # )SMARTLEAD_API_KEY )r   osenvirongetr	   r   r   
configuredr      s    

2B788r   c               $    V ^8  d   QhRRRRRR/# )r   methodstrpathtimeoutintr	   )r
   s   "r   r   r      s!     * * *C *S *r   c           
     x   \         P                  P                  R R4      pVP                  R4      '       g
   RV,           pRV9   d   RMRp\         V V RV 2pVe%   \
        P                  ! V4      P                  4       MRp\        P                  P                  WgV R7      pVP                  RR	4       VP                  R
\        4       VP                  RR	4        \        P                  P                  WR7      ;_uu_ 4       p	V	P                  4       p
RRR4       X
'       d   \
        P(                  ! T
4      # / #   + '       g   i     L0; i  \        P                  P                    dF   p\#        RTP$                   RTP                  4       R,          P'                  RR4       24      hRp?ii ; i)r   r   r   ?&zapi_key=N)datar   zContent-Typezapplication/jsonz
User-AgentAccept)r   zHTTP z: :Ni  Nzutf-8ignore)r   r   r   
startswith_BASEjsondumpsencodeurllibrequestRequest
add_header_UAurlopenreaderror	HTTPErrorRuntimeErrorcodedecodeloads)r   r   bodyr   keysepurlr   reqrrawes   &&&&        r   _apir;      sV   
**..,b
1C??3Tz##CGD6#hse
,C(,(84::d""$dD
..
 
 
 
?CNN>#56NN<%NN8/0X^^##C#99Q&&(C : "4::c?)r)	 :9<<!! XU166("QVVXd^-B-B78-T,UVWWXs7   !(E 	EE E	E E F94A F44F9c                    V ^8  d   QhRRRR/# )r   refr   r   z
str | Noner	   )r
   s   "r   r   r   )   s      c j r   c                R   \        V 4      P                  4       p V '       g   R # V P                  4       '       d   V #  \        RR4      ;'       g    . pV F[  p\        VP	                  RR4      4      P                  4       V P                  4       8X  g   KA  \        VP	                  R4      4      u # 	  V F[  pV P                  4       \        VP	                  RR4      4      P                  4       9   g   KA  \        VP	                  R4      4      u # 	  R #   \         d     R # i ; i)NGET
/campaignsnamer   id)r   stripisdigitr;   r   lower	Exception)r=   campscs   &  r   _campaign_idrI   )   s    
c(..
C
{{}}
	UL)//RA155$%++-<155;''  Ayy{c!%%"34::<<155;'' 
   s1   D AD D 2A D 7D D D&%D&c                   V ^8  d   QhRR/# r   r   r   r	   )r
   s   "r   r   r   <   s     U U3 Ur   c                     \        R R4      p V '       g   R# \        V 4       R2RP                  R V  4       4      ,           # )r?   r@   z=No campaigns yet (sender inboxes are ready, nothing running).z campaign(s):

c           	   3     "   T F>  pR VP                  R4       RVP                  R4      : RVP                  R4       2x  K@  	  R# 5i)z- [rB   z] rA   u    — statusNr   ).0rH   s   & r   	<genexpr>campaigns.<locals>.<genexpr>@   sA      6UNS#aeeDk]"QUU6]-U155?2CDes   AA)r;   lenjoin)rG   s    r   	campaignsrV   <   sI    %EN%j\)DII 6UNS6U -U U Ur   c                    V ^8  d   QhRRRR/# )r   campaignr   r   r	   )r
   s   "r   r   r   D   s     M MS MS Mr   c                   a \        V 4      pV'       g   R # \        RRV R24      oV3R lpRSP                  RV4       RV! R4       R	V! R
4       RV! R4       RV! R4       RV! R4       R2# )u,   Campaign not found — list campaigns first.r?   /campaigns/z
/analyticsc                (   < SP                  V ^ 4      # )    rP   )kas   &r   <lambda> campaign_stats.<locals>.<lambda>I   s    !%%1+r   	Campaign rA   z: sent 
sent_countz	, opened 
open_countz
, replied reply_countz
, bounced bounce_countz, unsubscribed unsubscribed_count.)rI   r;   r   )rX   cidgr^   s   &  @r   campaign_statsrj   D   s    
x
 C=Uk#j12AAfc*+71\?2C9z!M*:);: !3G1H0IL Mr   c                   V ^8  d   QhRR/# rK   r	   )r
   s   "r   r   r   O   s     : : :r   c                    \        R R4      p V '       g   R# . pV  F  pVP                  R4      ;'       g    / pTP                  RVP                  R4       RVP                  RR4       R	VP                  R
R4       RVP                  R4      '       d   RMR 24       K  	  \        V 4       R2RP	                  V4      ,           # )r?   z#/email-accounts/?offset=0&limit=100zNo sender inboxes configured.warmup_detailsz- 
from_emailu    — reputation warmup_reputationzn/az, message_per_dayr   z/day, warmup is_warmup_enabledonoffz inbox(es):
rM   )r;   r   appendrT   rU   )accslinesr:   wus       r   sendersrx   O   s    <=D.EUU#$**r!%%-..>2E:;2/56 7'(uu-@'A'AtuMO 	P  $i[&5)999r   c                    V ^8  d   QhRRRR/# )r   rA   r   r   r	   )r
   s   "r   r   r   ]   s     X X# X# Xr   c                    \        V 4      P                  4       p V '       g   R # \        RRRV /4      pRV : RVP                  R4      ;'       g    VP                  R4       R2# )	z$create_campaign failed: need a name.POSTz/campaigns/createrA   zCreated campaign z (id rB   campaign_idz).)r   rC   r;   r   )rA   outs   & r   create_campaignr~   ]   s[    t9??D5
v*VTN
;CtheCGGDM,S,SSWW]=S+TTVWWr   c               $    V ^8  d   QhRRRRRR/# )r   rX   r   sequence_jsonr   r	   )r
   s   "r   r   r   e   s&     	C 	C3 	Cs 	Cs 	Cr   c                    \        V 4      pV'       g   R #  \        P                  ! V4      p\        RRT R2RT/4       R\        T4       R	T R
2#   \         d    pR\	        T4      R,           2u Rp?# Rp?ii ; i)Campaign not found.z sequence_json isn't valid JSON: Nx   NNr{   rZ   z
/sequences	sequenceszSaved a z-step sequence on campaign rg   )rI   r#   r2   rF   r   r;   rT   )rX   r   rh   seqsr:   s   &&   r   set_sequencer   e   s    
x
 C$Azz-( 	;se:.d0CDc$i[ ;C5BB  A1#a&,@@As   A A<A71A<7A<c               $    V ^8  d   QhRRRRRR/# )r   rX   r   
leads_jsonr   r	   )r
   s   "r   r   r   q   s!     4 4 4 4 4r   c           	     d   \        V 4      pV'       g   R #  \        P                  ! V4      pT'       g   R# \        RRT R2RTR	,          /4      pTP                  R
TP                  R\        T4      4      4      pRT RT R2#   \         d    pR\	        T4      R,           2u Rp?# Rp?ii ; i)r   zleads_json isn't valid JSON: r   NzNo leads to add.r{   rZ   z/leads	lead_list:Nd   Nupload_counttotal_leadszAdded z lead(s) to campaign rg   )rI   r#   r2   rF   r   r;   r   rT   )rX   r   rh   leadsr:   r}   ups   &&     r   	add_leadsr   q   s    
x
 C$>

:& !
vSE0;d2L
MC	E
!C	DBB4,SE33  >.s1vd|n==>s   B B/B*$B/*B/c               $    V ^8  d   QhRRRRRR/# )r   rX   r   actionr   r	   )r
   s   "r   r   r      s!     	+ 	+s 	+C 	+C 	+r   c                    \        V 4      pV'       g   R # RRRRRR/P                  \        V4      P                  4       4      pV'       g   R# \	        RR	V R
2RV/4       RV RV R2# )r   startSTARTpausePAUSEDstopSTOPPEDz%action must be start, pause, or stop.r{   rZ   z/statusrO   ra   u    → rg   )rI   r   r   rE   r;   )rX   r   rh   rO   s   &&  r   campaign_controlr      st    
x
 C$w69EIIFF6;se7+h-?@se5**r   c               (    V ^8  d   QhRRRRRRRR/# )r   r   r   r   	body_jsonr   r	   )r
   s   "r   r   r      s.     	C 	C 	C3 	C3 	C 	Cr   c                x   R pV'       d    \         P                  ! V4      p\	        \        V 4      P                  4       \        V4      V4      p\         P                  ! VRR7      pVR,          \        V4      R8  d	   R,           # R,           #   \         d    pR\        T4      R,           2u R p?# R p?ii ; i)	Nzbody_json isn't valid JSON: r   F)ensure_ascii:Ni  Ni  u    …[truncated]r   )r#   r2   rF   r   r;   upperr$   rT   )r   r   r   r3   r:   r}   ss   &&&    r   r9   r9      s    D	A::i(D s6{  "CIt
4C

3U+AU8CFTM(BBrBB	  	A1#a&,@@	As   B B9B4.B94B9)N   )r   )__doc__
__future__r   r#   r   urllib.errorr&   urllib.requestr   r   rstripr"   r*   r   r;   rI   rV   rj   rx   r~   r   r   r   r9   r	   r   r   <module>r      s    #  	  


;	==CVC[ <9*&&UM:X	C4	+	C 	Cr   