+
    TjH                        R t ^ RIHt ^ RIt^ RIt^ RIHtHtHt ^ RIH	t	 . ROt
R R ltR tR R	 ltRR
 R lltR R ltRR R lltR R ltRR R lltRR R lltR R ltR R ltR# )u  Work Google Workspace (ahmed.alrajeh@alrugaibfurniture.com) for the
jarvis-tools service — Gmail + Calendar + Sheets, over an OAuth refresh token
carried in env so it runs headless and every device reaches it via the one
connector.

Env:
  GWS_REFRESH_TOKEN   the work account's OAuth refresh token
  GWS_CLIENT_ID       OAuth client id
  GWS_CLIENT_SECRET   OAuth client secret
  GWS_EMAIL           the account address (for display; default alrugaib)
)annotationsN)datetime	timedeltatimezone)EmailMessagec                   V ^8  d   QhRR/# )   returnbool )formats   "M/Users/ahmed/devFolder/Ultron/claude-voice/jarvis-tools-service/gworkspace.py__annotate__r      s     9 9D 9    c                     \        \        P                  P                  R 4      ;'       dG    \        P                  P                  R4      ;'       d     \        P                  P                  R4      4      # )GWS_REFRESH_TOKENGWS_CLIENT_IDGWS_CLIENT_SECRET)r
   osenvirongetr   r   r   
configuredr      sT    

23 8 8JJNN?38 8JJNN#679 9r   c            	         ^ RI Hp  V ! R\        P                  R,          \        P                  R,          \        P                  R,          R\        R7      # )    CredentialsNr   r   r   z#https://oauth2.googleapis.com/token)tokenrefresh_token	client_idclient_secret	token_uriscopes)google.oauth2.credentialsr   r   r   _SCOPESr   s    r   _credsr$   #   sA    5jj!45**_-jj!457 r   c                    V ^8  d   QhRRRR/# )r   apistrverr   )r   s   "r   r   r   /   s     H Hc H Hr   c                4    ^ RI Hp V! W\        4       RR7      # )r   )buildF)credentialscache_discovery)googleapiclient.discoveryr*   r$   )r&   r(   r*   s   && r   _svcr.   /   s    /vxGGr   c          
     ,    V ^8  d   QhRRRRRRRRRR/# )r   tor'   subjectbodyccr	   r   )r   s   "r   r   r   5   s6     E E3 E EC ES E# Er   c                   \        V 4      P                  4       p V '       g   R # \        4       pWR&   V'       d   W4R&   WR&   VP                  V4       \        P
                  ! VP                  4       4      P                  4       p\        RR4      P                  4       P                  4       P                  RRV/R7      P                  4       pR	V R
V  RVP                  R4       R2# )z gmail_send failed: no recipient.ToCcSubjectgmailv1meraw)userIdr2   zSent 'z' to z (message id idz).)r'   stripr   set_contentbase64urlsafe_b64encodeas_bytesdecoder.   usersmessagessendexecuter   )r0   r1   r2   r3   msgr;   outs   &&&&   r   
gmail_sendrJ   5   s    	RB1
.CI	D		NOOD

"
"3<<>
2
9
9
;C
w

#
#
%
.
.
0
5
55#, 6 ((/	 G9E"]3774=/DDr   c                   V ^8  d   QhRR/# )r   r	   r'   r   )r   s   "r   r   r   E   s     
3 
3C 
3r   c                4   a V3R  loS! V 4      ;'       g    R# )c                X  < V P                  R 4      R8X  d\   V P                  R/ 4      P                  R4      '       d5   \        P                  ! V R,          R,          4      P                  RR4      # V P                  R. 4      ;'       g    .  F  pS! V4      pV'       g   K  Vu # 	  R# )mimeTypez
text/plainr2   datazutf-8replaceparts )r   r@   urlsafe_b64decoderC   )ppartrwalks   &  r   rW   _gmail_body.<locals>.walkF   s    55,vr1B1F1Fv1N1N++&	&!##)6'9#=>EE'2&,,",DT
Aq - r   z(no plain-text body)r   )payloadrW   s   &@r   _gmail_bodyrZ   E   s     =2222r   c               $    V ^8  d   QhRRRRRR/# )r   queryr'   limitintr	   r   )r   s   "r   r   r   R   s!       C  r   c                @   \        ^\        \        T;'       g    ^
4      ^4      4      p\        RR4      pVP	                  4       P                  4       P                  R\        T ;'       g    R4      VR7      P                  4       pVP                  R. 4      pV'       g   R# . pV F  pVP	                  4       P                  4       P                  RVR,          R	. ROR7      P                  4       pVP                  R/ 4      P                  R. 4       Uu/ uF  pVR,          VR,          bK  	  p	pVP                  RVR,           RV	P                  RR4       RV	P                  R
R4       RV	P                  RR4       24       K  	  RP                  V4      # u upi )   r8   r9   r:   rR   )r<   q
maxResultsrE   zNo matching messages.r=   metadataFromr7   Date)r<   r=   r   metadataHeadersrY   headersnamevaluez[id z] z	
  from: z	
  subj: 
)rd   r7   re   )maxminr^   r.   rD   rE   listr'   rG   r   appendjoin)
r\   r]   svcresmsgslinesmrefmxhs
   &&        r   gmail_searchrx   R   s   3s5;;B',-E
w
C
))+


 
%
%s5;;B'E & ;;B79 77:r"D&EIIK  "&&DJz7 ' 99@ 	
 eeIr*..y"=?= vY'
"= 	
 ?tDJ<r!%%r*:); <  !fR 01AEE)B<O;PR 	S  99U	?s   Fc                    V ^8  d   QhRRRR/# )r   
message_idr'   r	   r   )r   s   "r   r   r   f   s     	3 	33 	33 	3r   c           	     <   \        R R4      P                  4       P                  4       P                  R\	        V 4      P                  4       RR7      P                  4       pVP                  R/ 4      P                  R. 4       Uu/ uF  pVR,          VR,          bK  	  pp\        VP                  R/ 4      4      p\        V4      R	8  d   VR
,          R,           pRVP                  RR4       RVP                  RR4       RVP                  RR4       RV 2# u upi )r8   r9   r:   full)r<   r=   r   rY   rg   rh   ri     Ni  Nu   
…(truncated)zFrom: rd   rR   z

Subject: r7   z
Date: re   z

)	r.   rD   rE   r   r'   r>   rG   rZ   len)rz   ru   rv   rw   r2   s   &    r   
gmail_readr   f   s   Wd!!#,,.22J--/ 	3 	@@G	  %%	2&**9b9	;9Q 
6AgJ	9  	;quuY+,D
4y4E{//QUU6"%&k!%%	"2E1F GUU6"%&d4&2 3	;s   Dc                    V ^8  d   QhRRRR/# )r   daysr^   r	   r'   r   )r   s   "r   r   r   s   s     T T TC Tr   c           
     P   \        ^\        \        T ;'       g    ^4      ^<4      4      p \        P                  ! \
        P                  4      p\        RR4      pVP                  4       P                  RVP                  4       V\        V R7      ,           P                  4       RR^2R7      P                  4       pVP                  R. 4      pV'       g   R	V  R
2# . pV F  pVP                  R/ 4      P                  R4      ;'       g"    VP                  R/ 4      P                  R4      pTP                  RV RVP                  RR4       2VP                  R4      '       d   RVR,           R2MR,           4       K  	  \        V4       RV  R2RP!                  V4      ,           # )r`   calendarv3primary)r   T	startTime)
calendarIdtimeMintimeMaxsingleEventsorderByrb   itemszNo events in the next z day(s).startdateTimedatez- z  summaryz
(no title)r=   z  []rR   z event(s) in the next z	 day(s):
rj   )rk   rl   r^   r   nowr   utcr.   eventsrm   	isoformatr   rG   r   rn   r   ro   )r   r   rp   rq   r   rs   ests   &       r   calendar_listr   s   sn   q#c$))!nb)*D
,,x||
$C
z4
 C
**,

cmmoyd++668;2  ? @Gwy  GGGR E'vX66EUU7B##J/QQ155"3E3I3I&3Qr"Ri =>?,-EE$KK#agYa(RA 	B  %j\/vZ@499UCSSSr   c               4    V ^8  d   QhRRRRRRRRRRRRRR/# )	r   titler'   r   end	attendeesdescriptionadd_meetr	   r   )r   s   "r   r   r      sJ     L L LS Ls L%(L<?L$'L14Lr   c           	     6   RV RVRRV/RRV//p\        V4      P                  R4       Uu. uF*  qwP                  4       '       g   K  VP                  4       NK,  	  ppV'       d   V Uu. uF  pRV/NK	  	  upVR&   / p	\        V4      P                  4       R&9   dO   ^ R	Ip
R
RV
P                  W,           P                  4       4      P                  4       R,          RRR///VR&   ^V	R&   \        RR4      P                  4       P                  ! R'RRRVRR/V	B P                  4       pVP                  R4      pRV  RV RV R2V'       d   R\        V4       R2MR ,           V'       d   R!V 2MR",           R#VP                  R$4       R%2,           # u upi u upi )(zstart/end = ISO datetime (2026-07-15T14:00:00+03:00). attendees =
comma-separated emails. add_meet='yes' attaches a Google Meet link.r   r   r   r   r   ,emailr   NcreateRequest	requestId:N   NconferenceSolutionKeytypehangoutsMeetconferenceDataconferenceDataVersionr   r   r   r   r2   sendUpdatesallhangoutLinkz	Created 'z' (u    → )z, z invitedrR   z. Meet: .z [r=   r   )yestrue1r   )r'   splitr>   lowerhashlibsha256encode	hexdigestr.   r   insertrG   r   r   )r   r   r   r   r   r   r2   aatskwr   rI   meets   &&&&&&       r   calendar_create_eventr      s   
 um[j%(%*c1BDD!)n2237
E7779917797C
E
3673agq\37[	B
8} 44"1&&(**3)+c;#fn%=4? "@ '("#
z4
 
'
'
)
0
0 BB#'B5:B>@BBI') 77=!Dwc%cU!4*-CH:X&27$($ c379#''$-5JK L F7s   FF)Fc               $    V ^8  d   QhRRRRRR/# )r   spreadsheet_idr'   a1_ranger	   r   )r   s   "r   r   r      s&     G G Gs Gs Gr   c                   \        R R4      P                  4       P                  4       P                  \	        V 4      P                  4       \	        V4      P                  4       R7      P                  4       pVP                  R. 4      pV'       g   R# RP                  R VR,           4       4      pVR,          \        V4      R	8  d	   R
,           # R,           # )sheetsv4)spreadsheetIdrangevaluesz(no data in that range)rj   c              3  R   "   T F  pR P                  R V 4       4      x  K  	  R# 5i)z | c              3  8   "   T F  p\        V4      x  K  	  R # 5i)N)r'   ).0cs   & r   	<genexpr>(sheets_read.<locals>.<genexpr>.<genexpr>   s     1q!s1vvqs   N)ro   )r   rV   s   & r   r   sheets_read.<locals>.<genexpr>   s"     F:aEJJ1q111:s   %':N   Nr~   r}   u    …[truncated]rR   )	r.   spreadsheetsr   r   r'   r>   rG   ro   r   )r   r   rq   rowsrI   s   &&   r   sheets_readr      s    
x

+
+
-
4
4
6
:
:.)//1(m!!# ; %%,WY  778R D(
))F4:F
FCu:c#ho*FF2FFr   c               (    V ^8  d   QhRRRRRRRR/# )r   r   r'   r   values_jsonr	   r   )r   s   "r   r   r      s.     	J 	J 	J 	J# 	J# 	Jr   c                   ^ RI p VP                  V4      p\	        RR4      P                  4       P                  4       P                  \        T 4      P                  4       \        T4      P                  4       RRT/R7      P                  4       pR	TP                  R
^ 4       RT R2#   \         d    pR\        T4      R,           2u Rp?# Rp?ii ; i)r   Nz*values_json must be a JSON array of rows: :Nd   Nr   r   USER_ENTEREDr   )r   r   valueInputOptionr2   zUpdated updatedCellsz cell(s) in r   )jsonloads	Exceptionr'   r.   r   r   updater>   rG   r   )r   r   r   r   r   r   rq   s   &&&    r   sheets_writer      s    KK( x

+
+
-
4
4
6
=
=.)//1X9L9L9N'x.@ > BBI')  cggna01hZqII  K;CF4L>JJKs   B) )C4CCC)z*https://www.googleapis.com/auth/gmail.sendz.https://www.googleapis.com/auth/gmail.readonlyz,https://www.googleapis.com/auth/gmail.modifyz(https://www.googleapis.com/auth/calendarz/https://www.googleapis.com/auth/calendar.eventsz,https://www.googleapis.com/auth/spreadsheets)rR   )
   )   )rR   rR   rR   )__doc__
__future__r   r@   r   r   r   r   email.messager   r#   r   r$   r.   rJ   rZ   rx   r   r   r   r   r   r   r   r   <module>r      sb   
 #  	 2 2 &9	HE 
3(	3T&L6G	Jr   