
    i(                       U d 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mZ ddl	Z	ddl
Z
ddlmZ  ej        e          Z ej        d          Z ej        d          Z ej        d          Z ej        d          Z ej        d	          ZeZ eh d
          Z ej        d          Zh dZh dZh dZddhZddhZ ej        dej                  Z  ej        dej                  Z!de"fdZ#de"de$fdZ%de&de'de(dz  fdZ)ddde'fdZ*d d!d"d#d$d%gd&d'd#d(d)d#d*d)d+g d,d-Z+d. Z,d/ Z-d0 Z.d1e"d2e"fd3Z/d4 Z0d5 Z1d1e"d6e"d7e"dz  fd8Z2d9 Z3dXd:Z4dYd<Z5de"de"fd=Z6i Z7ee"e8f         e9d><   d6e"d?e8ddfd@Z:d6e"dee8         fdAZ;dXdBZ<dC Z=dD Z>dZdEZ?dF Z@dG ZAdH ZBdI ZCdXdJZDdK ZEdL ZFdM ZGdZdNZHdO ZIdXdPZJdQ ZKdR ZLdZdSZMddTlNmOZOmPZP  eOjQ        d dUe+e,eKdVW           dS )[a$  Send Message Tool -- cross-channel messaging via platform APIs.

Sends a message to a user or channel on any connected messaging platform
(Telegram, Discord, Slack). Supports listing available targets and resolving
human-friendly channel names to IDs. Works in both CLI and gateway contexts.
    N)DictOptional)redact_sensitive_textz^\s*(-?\d+)(?::(\d+))?\s*$zD^\s*((?:oc|ou|on|chat|open)_[-A-Za-z0-9]+)(?::([-A-Za-z0-9_]+))?\s*$z^\s*([CGD][A-Z0-9]{8,})\s*$zS^\s*((?:wxid|gh|v\d+|wm|wb)_[A-Za-z0-9_-]+|[A-Za-z0-9._-]+@chatroom|filehelper)\s*$z ^\s*((?:group|direct):[^:]+)\s*$>   smssignalwhatsappz^\s*\+(\d{7,15})\s*$>   .gif.jpg.png.jpeg.webp>   .3gp.avi.mkv.mov.mp4>   .wav.flac.m4a.mp3.ogg.opusr   r   r   r   zP([?&](?:access_token|api[_-]?key|auth[_-]?token|token|signature|sig)=)([^&#\s]+)zJ\b(access_token|api[_-]?key|auth[_-]?token|signature|sig)\s*=\s*([^\s,;]+)returnc                     t          |           }t                              d |          }t                              d |          }|S )zCRedact secrets from error text before surfacing it to users/models.c                 2    |                      d           dS )N   z***groupms    </home/ubuntu/.hermes/hermes-agent/tools/send_message_tool.py<lambda>z&_sanitize_error_text.<locals>.<lambda>>   s    QWWQZZ2D2D2D     c                 2    |                      d           dS )Nr   z=***r   r   s    r!   r"   z&_sanitize_error_text.<locals>.<lambda>?   s    !''!**7J7J7J r#   )r   _URL_SECRET_QUERY_REsub_GENERIC_SECRET_ASSIGN_RE)textredacteds     r!   _sanitize_error_textr*   ;   sF    $T**H#''(D(DhOOH(,,-J-JHUUHOr#   messagec                 $    dt          |           iS )z9Build a standardized error payload with redacted content.error)r*   )r+   s    r!   _errorr.   C   s    )'2233r#   excattemptc                 R   t          | dd           }|6	 t          t          |          d          S # t          t          f$ r Y dS w xY wt          |                                           }d|v sd|v rd S d|v sd|v sd|v sd	|v sd
|v sd|v sd|v sd|v rt          d|z            S d S )Nretry_afterg        g      ?z	timed outtimeoutzbad gateway502ztoo many requests429zservice unavailable503zgateway timeout504   )getattrmaxfloat	TypeError
ValueErrorstrlower)r/   r0   r2   r(   s       r!   _telegram_retry_delayr@   H   s    #}d33K	u[))3///:& 	 	 	33	 s88>>Ddi4//tD==$&&D== D((D==$$D==Q'\"""4s   2 AA   )attemptsrB   c                N  K   t          |          D ]}	  | j        di | d {V c S # t          $ rn}t          ||          }|	||dz
  k    r t                              d|dz   ||t          |                     t          j        |           d {V  Y d }~d }~ww xY wd S )Nr   zFTransient Telegram send failure (attempt %d/%d), retrying in %.1fs: %s )	rangesend_message	Exceptionr@   loggerwarningr*   asynciosleep)botrB   kwargsr0   r/   delays         r!   !_send_telegram_message_with_retryrO   a   s     ?? ' '	'))33F33333333333 	' 	' 	')#w77E}8a< 7 7NNX!$S))   -&&&&&&&&&&&&&&	'' 's   *
B"A$BB"rF   a  Send a message to a connected messaging platform, or list available targets.

IMPORTANT: When the user asks to send to a specific channel or person (not just a bare platform name), call send_message(action='list') FIRST to see available targets, then send to the correct one.
If the user just says a platform name like 'send to telegram', send directly to the home channel without listing first.objectstringsendlistzAction to perform. 'send' (default) sends a message. 'list' returns all available channels/contacts across connected platforms.)typeenumdescriptiona  Delivery target. Format: 'platform' (uses home channel), 'platform:#channel-name', 'platform:chat_id', or 'platform:chat_id:thread_id' for Telegram topics and Discord threads. Examples: 'telegram', 'telegram:-1001234567890:17585', 'discord:999888777:555444333', 'discord:#bot-home', 'slack:#engineering', 'signal:+155****4567', 'matrix:!roomid:server.org', 'matrix:@user:server.org', 'yuanbao:direct:<account_id>' (DM), 'yuanbao:group:<group_code>' (group chat))rT   rV   u   The message text to send. To send an image or file, include MEDIA:<local_path> (e.g. 'MEDIA:/tmp/hermes/cache/img_xxx.jpg') in the message — the platform will deliver it as a native media attachment.)actiontargetr+   )rT   
propertiesrequired)namerV   
parametersc                 t    |                      dd          }|dk    rt                      S t          |           S )z-Handle cross-channel send_message tool calls.rW   rR   rS   )get_handle_list_handle_send)argskwrW   s      r!   send_message_toolrc      s8    XXh''F~~r#   c                      	 ddl m}  t          j        d |             i          S # t          $ r.}t          j        t          d|                     cY d}~S d}~ww xY w)z5Return formatted list of available messaging targets.r   )format_directory_for_displaytargetsz"Failed to load channel directory: N)gateway.channel_directoryre   jsondumpsrG   r.   )re   es     r!   r_   r_      s    LJJJJJJz9&B&B&D&DEFFF L L Lz&!Ia!I!IJJKKKKKKKKLs   #& 
A#AAAc           
      
   |                      dd          }|                      dd          }|r|st          d          S |                    dd          }|d                                                                         }t          |          dk    r|d                                         nd}d}d}|rt          ||          \  }}}nd	}|rw|su	 dd
lm}	  |	||          }
|
rt          ||
          \  }}}nt          j
        dd| d| di          S n-# t          $ r  t          j
        dd| d| di          cY S w xY wddlm}  |            rt          d          S 	 ddlm}m}  |            }n;# t          $ r.}t          j
        t#          d|                     cY d}~S d}~ww xY w	  ||          }n)# t$          t&          f$ r t          d|           cY S w xY w|j                             |          }|r|j        s|dk    rt-          j        dd                                          }t-          j        dd                                          }|re|rcddlm}  |d||t-          j        dd                                          t-          j        dd                                          d          }n&t          d| d          S t          d| d          S dd lm} |                    |          \  }}|                                pt9          |          }d	}|s|                    |          }|sC|dk    r=t-          j        d!d                                          }|rdd"lm}  |||d#$          }|r
|j        }d}n2t          j
        dd%| d&| d'|                                  d(i          S tC          |||          }|rt          j
        |          S 	 dd)l"m#}  |tI          ||||||*                    } |r6tK          | tL                    r!|                      d+          rd,| d-| d.| d/<   tK          | tL                    re|                      d+          rP|rN	 dd0l'm(}! dd1l)m*}"  |"d2d3          }# |"d4d          pd}$ |!||||#||$5          rd| d6<   n# t          $ r Y nw xY wtK          | tL                    rd| v rtW          | d                   | d<   t          j
        |           S # t          $ r.}t          j
        t#          d7|                     cY d}~S d}~ww xY w)8z$Send a message to a platform target.rX    r+   z;Both 'target' and 'message' are required when action='send':r   r   NF)resolve_channel_namer-   zCould not resolve 'z' on z;. Use send_message(action='list') to see available targets.z). Try using a numeric channel ID instead.)is_interruptedInterrupted)load_gateway_configPlatformzFailed to load gateway config: zUnknown platform: weixinWEIXIN_TOKENWEIXIN_ACCOUNT_IDPlatformConfigTWEIXIN_BASE_URLWEIXIN_CDN_BASE_URL)
account_idbase_urlcdn_base_url)enabledtokenextraz
Platform 'zZ' is not configured. Set up credentials in ~/.hermes/config.yaml or environment variables.)BasePlatformAdapterWEIXIN_HOME_CHANNEL)HomeChannelzWeixin Home)platformchat_idr[   zNo home channel set for zQ to determine where to send the message. Either specify a channel directly with 'z=:CHANNEL_NAME', or set a home channel via: hermes config set z_HOME_CHANNEL <channel_id>)
_run_async)	thread_idmedia_filessuccesszSent to z home channel (chat_id: )note)mirror_to_sessionget_session_envHERMES_SESSION_PLATFORMcliHERMES_SESSION_USER_ID)source_labelr   user_idmirroredzSend failed: ),r^   
tool_errorsplitstripr?   len_parse_target_refrg   rn   rh   ri   rG   tools.interruptro   gateway.configrq   rr   r.   r=   KeyError	platformsr}   osgetenvrw   gateway.platforms.baser   extract_media_describe_media_for_mirrorget_home_channelr   r   upper_maybe_skip_cron_duplicate_sendmodel_toolsr   _send_to_platform
isinstancedictgateway.mirrorr   gateway.session_contextr   r*   )%ra   rX   r+   partsplatform_name
target_refr   r   is_explicitrn   resolved_ro   rq   rr   configrj   r   pconfigwx_token
wx_accountrw   r   r   cleaned_messagemirror_textused_home_channelhomewx_homer   duplicate_skipr   resultr   r   r   r   s%                                        r!   r`   r`      s   XXh##Fhhy"%%G Y YWXXXLLa  E!HNN$$**,,M%(ZZ!^^q!!!JGI *;M:*V*V'KK  + 	FFFFFF++M:FFH (9-(R(R%AAz Q: Q QM Q Q Q#    %&  	 	 	: ;z ; ; ; ; ;     	 /.....~ )-(((I@@@@@@@@$$&& I I Iz&!F1!F!FGGHHHHHHHHI
@8M**! @ @ @>}>>?????@ ""8,,G V'/ V H$$y44::<<H#6;;AACCJ ZJ Z999999(. "&0$&I.?$D$D$J$J$L$L(*	2G(L(L(R(R(T(T    "  #Y}  #Y  #Y  #Y  Z  Z  Z  U=  U  U  U  V  V  V::::::#6#D#DW#M#M K!''))T-G-T-TK &&x00 	[11i 5r::@@BBG [666666"{HgMZZZ 	lG $: rM r r;Hr r@M@S@S@U@Ur r r    5]GYWWN *z.)))&7******#'  	
 	
  	ZFD!9!9 	Zfjj>S>S 	ZYYYwYYYF6N fd## 	

9(=(= 	+ 	<<<<<<CCCCCC./H%PP)/*BBGGO4$$!!-'#   . *.F:&    fd## 	D6(9(926'?CCF7Oz&!!! 7 7 7z&!4!4!455666666667s   AD 'EE'E: :
F2#F-'F2-F26G #G('G(4BT =<R: 9T :
ST SAT 
U#U<UUr   r   c                    | dk    rGt                               |          }|r+|                    d          |                    d          dfS | dk    rGt                              |          }|r+|                    d          |                    d          dfS | dk    rGt                              |          }|r+|                    d          |                    d          dfS | dk    r4t
                              |          }|r|                    d          ddfS | d	k    r4t                              |          }|r|                    d          ddfS | d
k    rvt                              |          }|r|                    d          ddfS |                                	                                rd|                                 ddfS dS | t          v r3t                              |          }|r|                                ddfS |                    d          	                                r|ddfS | dk    r/|                    d          s|                    d          r|ddfS dS )zFParse a tool target into chat_id/thread_id and whether it is explicit.telegramr   r8   TfeishudiscordslackNrs   yuanbaogroup:NNF-matrix!@)_TELEGRAM_TOPIC_TARGET_RE	fullmatchr   _FEISHU_TARGET_RE_NUMERIC_TOPIC_RE_SLACK_TARGET_RE_WEIXIN_TARGET_RE_YUANBAO_TARGET_REr   isdigit_PHONE_PLATFORMS_E164_TARGET_RElstrip
startswith)r   r   matchs      r!   r   r   6  s   
"")33J?? 	8;;q>>5;;q>>477  !++J77 	8;;q>>5;;q>>477	!!!++J77 	8;;q>>5;;q>>477 **:66 	.;;q>>4--  !++J77 	.;;q>>4--	!!",,Z88 	.;;q>>4--%%'' 	=0J,,..00$<<  ((())*55 	2 ##%%tT11%%'' &4%%  j&;&;C&@&@ JDYDYZ]D^D^ 4%%r#   c                 :   | sdS t          |           dk    rr| d         \  }}t          j                            |          d                                         }|r|t
          v rdS |t          v rdS |t          v rdS |t          v rdS dS d	t          |            d
S )zJReturn a human-readable mirror summary when a message only contains media.rl   r   r   z[Sent voice message]z[Sent image attachment]z[Sent video attachment]z[Sent audio attachment]z[Sent document attachment]z[Sent z media attachments])	r   r   pathsplitextr?   _VOICE_EXTS_IMAGE_EXTS_VIDEO_EXTS_AUDIO_EXTS)r   
media_pathis_voiceexts       r!   r   r   a  s     r
;1*1~
Hgz**1-3355 	*{**))+,,+,,+,,++9C$$9999r#   c                     ddl m}   | dd                                                                          } | dd                                          }|r|sdS  | dd                                          pd}|||dS )	zMReturn the cron scheduler's auto-delivery target for the current run, if any.r   r   !HERMES_CRON_AUTO_DELIVER_PLATFORMrl    HERMES_CRON_AUTO_DELIVER_CHAT_IDN"HERMES_CRON_AUTO_DELIVER_THREAD_ID)r   r   r   )r   r   r   r?   )r   r   r   r   s       r!   _get_cron_auto_delivery_targetr   t  s    777777BBGGMMOOUUWWHo@"EEKKMMG 7 t DbIIOOQQYUYI  r#   r   r   c                     t                      }|sdS |d         | k    o>t          |d                   t          |          k    o|                    d          |k    }|sdS |  d| }||d| z  }ddd|d| d	d
S )zRSkip redundant cron send_message calls when the scheduler will auto-deliver there.Nr   r   r   rm   T#cron_auto_delivery_duplicate_targetzSkipped send_message to z. This cron job will already auto-deliver its final response to that same target. Put the intended user-facing content in your final response instead, or use a different target if you want an additional message.)r   skippedreasonrX   r   )r   r>   r^   )r   r   r   auto_targetsame_targettarget_labels         r!   r   r     s    022K t 	J=0 	6I&''3w<<7	6OOK((I5 
  t#//g//LI' 7h| h h h
 
 
r#   c                 <  K   	 ddl m}  |            }|r\|j                            |           }|r@ddlm} |                    ||           d{V }|j        r
d|j        dS dd	|j	         iS n# t          $ r}	dd
|	 icY d}	~	S d}	~	ww xY wdd| j         diS )zSend a message via a live gateway adapter (for plugin platforms).

    Falls back to error if no adapter is connected for this platform.
    r   )_gateway_runner_ref)
SendResult)r   contentNT)r   
message_idr-   zAdapter send failed: zPlugin platform send failed: zNo live adapter for platform 'z7'. Is the gateway running with this platform connected?)gateway.runr   adaptersr^   r   r   rR   r   r   r-   rG   value)
r   r   r   chunkr   runneradapterr   r   rj   s
             r!   _send_via_adapterr     s     
>333333$$&& 	Io))(33G I======&||GU|KKKKKKKK> N'+6;LMMM!G!G!GHH > > ><<<=======>}hn}}}~~s$   A!A3 &A3 3
B=B	B	Bc           	        K   ddl m} ddlm}m} ddlm}	 ddlm}
 	 ddl	m
} d}n# t          $ r d}Y nw xY w	 dd	lm} d}n# t          $ r d}Y nw xY w|pg }| |j        k    rZ|rX	 |
                    |
          }|                    |          }n,# t"          $ r t$                              d
d           Y nw xY w|j        |r|j        nd|j        |	j        |j        |
j        i}|r|j        ||j        <   | |vrI	 ddlm} |                    | j                  }|r|j        dk    r
|j        || <   n# t"          $ r Y nw xY w|                    |           }|r(| |j        k    r|nd}|                    |||          }n|g}| |j        k    rd}t=          t?          |di           o|j                             d                    }tC          |          D ]o\  }}|tE          |          dz
  k    }tG          |j$        |||r|ng ||           d{V }tK          |tL                    r|                    d          r|c S |}p|S | |j'        k    rtQ          ||||           d{V S | |j        k    rd}tC          |          D ]n\  }}|tE          |          dz
  k    }tS          |j$        |||r|ng |           d{V }tK          |tL                    r|                    d          r|c S |}o|S | |j*        k    r|r}d}tC          |          D ]i\  }}|tE          |          dz
  k    }tW          ||||r|ng |           d{V }tK          |tL                    r|                    d          r|c S |}j|S | |j,        k    r|rd}tC          |          D ]m\  }}|tE          |          dz
  k    }t[          |j         |||r|ng            d{V }tK          |tL                    r|                    d          r|c S |}n|S | |j.        k    r}|r{d}tC          |          D ]g\  }}|tE          |          dz
  k    }t_          |||r|nd           d{V }tK          |tL                    r|                    d          r|c S |}h|S |r!|0                                sdd| j         diS d}|rd| j         d}d}|D ]}| |j        k    rtc          |j$        ||           d{V }n*| |j2        k    rtg          |j         ||           d{V }n| |j,        k    rt[          |j         ||           d{V }n| |j4        k    rtk          |j         ||           d{V }n| |j6        k    rto          |j8        ||           d{V }n| |j9        k    r$tu          |j$        |j         ||           d{V }nW| |j*        k    r$tw          |j$        |j         ||           d{V }n(| |j<        k    r#t{          |j$        |j         ||           d{V }n| |j>        k    rt          |j         ||           d{V }n| |j        k    rt          ||||           d{V }n| |jA        k    rt          |j         ||           d{V }n| |jC        k    rt          |j         ||           d{V }n]| |jE        k    rt          |||           d{V }n:| |j.        k    rt_          ||           d{V }nt          | |||           d{V }tK          |tL                    r|                    d          r|c S |}|rgtK          |tL                    rR|                    d          r=t          |                    dg                     }|I                    |           ||d<   |S )a  Route a message to the appropriate platform sender.

    Long messages are automatically chunked to fit within platform limits
    using the same smart-splitting algorithm as the gateway adapters
    (preserves code-block boundaries, adds part indicators).
    r   )rr   )r   	utf16_len)DiscordAdapter)SlackAdapterTelegramAdapterTF)FeishuAdapterz<Failed to apply Slack mrkdwn formatting in _send_to_platformexc_infoi   )platform_registryN)len_fnr   disable_link_previewsr   )r   r   r  r-   r   )r   r   zzsend_message MEDIA delivery is currently only supported for telegram, discord, matrix, weixin, signal and yuanbao; target z had only media attachmentsz#MEDIA attachments were omitted for zz; native send_message media delivery is currently only supported for telegram, discord, matrix, weixin, signal and yuanbao)r   r   warnings)Jr   rr   r   r   r   gateway.platforms.discordr   gateway.platforms.slackr   gateway.platforms.telegramr   ImportErrorgateway.platforms.feishur   SLACK__new__format_messagerG   rH   debugTELEGRAMMAX_MESSAGE_LENGTHDISCORDFEISHUgateway.platform_registryr   r^   r   max_message_lengthtruncate_messageboolr9   r   	enumerater   _send_telegramr~   r   r   WEIXIN_send_weixin_send_discordMATRIX_send_matrix_via_adapterSIGNAL_send_signalYUANBAO_send_yuanbaor   _send_slackWHATSAPP_send_whatsappEMAIL_send_emailSMS	_send_smsapi_key
MATTERMOST_send_mattermost_send_matrixHOMEASSISTANT_send_homeassistantDINGTALK_send_dingtalk_send_feishuWECOM_send_wecomBLUEBUBBLES_send_bluebubblesQQBOT_send_qqbotr   rS   append)r   r   r   r+   r   r   rr   r   r   r   r   r   _telegram_availabler   _feishu_availableslack_adapter_MAX_LENGTHSr   entrymax_len_len_fnchunkslast_resultr  ir   is_lastr   rI   r  s                                 r!   r   r     s2      ('''''EEEEEEEE888888444444$>>>>>>" $ $ $#$"::::::  " " "!" #K8>!!g!	h(00>>M#227;;GG 	h 	h 	hLLWbfLggggg	h
 	AT^?==Z^.;7L
  I(5(HX_% |##	CCCCCC%))(.99E B1A55).)AX& 	 	 	D	 x((G '8+<<<))$$55gww5WW 8$$$ $WWgr%B%B%qw}GXGXYpGqGq r r!&)) 	! 	!HAuCKK!O+G)+2:KK#&;        F &$'' FJJw,?,?  KK 8?""!'7GUUUUUUUUUU 8###!&)) 	! 	!HAuCKK!O+G(+2:KK#        F &$'' FJJw,?,?  KK 8?""{"!&)) 	! 	!HAuCKK!O+G3+2:KK#        F &$'' FJJw,?,?  KK 8?""{"!&)) 
	! 
	!HAuCKK!O+G'+2:KK	        F &$'' FJJw,?,?  KK 8####!&)) 		! 		!HAuCKK!O+G(+2<KK        F
 &$'' FJJw,?,?  KK  
7==?? 
F".F F F
 	
 G 
G(. G G G 	
 K $ $x~%%&w}guEEEEEEEEFF***)'-%HHHHHHHHFF(('wFFFFFFFFFF''&w}guEEEEEEEEFF%%$W_guEEEEEEEEFF,,,+GM7='SXYYYYYYYYFF(('w}guUUUUUUUUFF///.w}gmWV[\\\\\\\\FF***)'-%HHHHHHHHFF(('%9UUUUUUUUUFF''&w}guEEEEEEEEFF---,W]GUKKKKKKKKFF''&w????????FF)))(%88888888FF -XwOOOOOOOOFfd## 	

7(;(; 	MMM +:k400 +[__Y5O5O +
B7788   "*JsA   ' 66A AA'*B &B;:B;>7D6 6
EEFc                   K   	 ddl m} ddlm} t	          t          j        d|                    }|r
|}	|j        }
nK	 ddlm	} |
                    |          }|                    |          }	n# t          $ r |}	Y nw xY w|j        }
 ||           }t          |          }|pg }i }|t          |          |d<   |rd	|d
<   d}g }|	                                r	 t!          |f||	|
d| d{V }n# t          $ r}dt#          |                                          v sFdt#          |                                          v s#dt#          |                                          v rjt&                              d|
t+          |                     |s%	 ddlm}  ||	          }n# t          $ r |}Y nw xY w|}t!          |f||dd| d{V }n Y d}~nd}~ww xY w|D ]\  }}t.          j                            |          s5d| }t&                              |           |                    |           Zt.          j                            |          d                                         }	 t9          |d          5 }|t:          v r |j        d#||d| d{V }nx|t>          v r |j         d#||d| d{V }nX|tB          v r|r |j"        d#||d| d{V }n6|tF          v r |j$        d#||d| d{V }n |j%        d#||d| d{V }ddd           n# 1 swxY w Y   T# t          $ rO}t+          d| d|           }t&          &                    |           |                    |           Y d}~d}~ww xY w|d}|r||dS d|iS d	d|t#          |j'                  d}|r||d <   |S # tP          $ r dd!icY S t          $ r}tS          d"|           cY d}~S d}~ww xY w)$uD  Send via Telegram Bot API (one-shot, no polling needed).

    Applies markdown→MarkdownV2 formatting (same as the gateway adapter)
    so that bold, links, and headers render correctly.  If the message
    already contains HTML tags, it is sent with ``parse_mode='HTML'``
    instead, bypassing MarkdownV2 conversion.
    r   )Bot)	ParseModez<[a-zA-Z/][^>]*>r   )r~   Nmessage_thread_idTdisable_web_page_preview)r   r(   
parse_modeparsemarkdownhtmlzFParse mode %s failed in _send_telegram, falling back to plain text: %s)_strip_mdv2 Media file not found, skipping: r   rb)r   photo)r   video)r   voice)r   audio)r   documentFailed to send media : ANo deliverable text or media remained after processing MEDIA tagsr-   r  r-   r   r   r   r   r   r  zGpython-telegram-bot not installed. Run: pip install python-telegram-botzTelegram send failed: rD   )*r   rD  telegram.constantsrE  r  researchHTMLr  r   r  r  rG   MARKDOWN_V2intr   rO   r>   r?   rH   rI   r*   rL  r   r   existsr7  r   openr   
send_photor   
send_videor   
send_voice_TELEGRAM_SEND_AUDIO_EXTS
send_audiosend_documentr-   r   r  r.   )r~   r   r+   r   r   r  rD  rE  	_has_html	formattedsend_parse_moder   _adapterrL   int_chat_idthread_kwargslast_msgr  md_errorrL  plainr   r   rI   r   frj   r-   r   s                                r!   r  r    s     v4      000000 #6@@AA	 	4I'nOO$FFFFFF*22?CC$33G<<		 $ $ $#			$ (3Oc'll!'R 14YM-.  	=8<M45?? 	!B"'i." " 3@" "      
    c(mm113333zS]]EXEXEZEZ7Z7Z^dhklthuhuh{h{h}h}^}^}NN`',X66  
 % (,NNNNNN$/K	$:$:EE( , , ,$+EEE, !(%F& +%#'& & ,9& &            HH  HHHH!0 %0 !	) !	) J7>>*-- IZIIw'''((('"":..q17799C)*d++ qk)))7 *$/q* *<I* * $ $ $ $ $ $ ++)7 *$/q* *<I* * $ $ $ $ $ $ +++)7 *$/q* *<I* * $ $ $ $ $ $  999)7 *$/q* *<I* * $ $ $ $ $ $ *;): *$/!* *?L* * $ $ $ $ $ $%              *  ) ) )./Xz/X/XUV/X/XYYW%%%(((((((()
 WE >!&H===U## "h122	
 
  	*!)F: d d dbcccc 4 4 42q22333333334s   :O 0A0 /O 0A?<O >A??AO C7 6O 7
GBGF('G(F74G6F77GO GBO 6L8BL+L8+L/	/L82L/	3L86O 8
NANO NO O #!O O:	O:O5/O:5O:c                     |                                                      dd          d                                          }|                    d                                           }|sd}|dd         S )zMDerive a thread name from the first line of the message, capped at 100 chars.
r   r   #zNew PostNd   )r   r   r   )r+   
first_lines     r!   _derive_forum_thread_namerv    sk    &&tQ//288::J""3''--//J  
dsdr#   !_DISCORD_CHANNEL_TYPE_PROBE_CACHEis_forumc                 N    t          |          t          t          |           <   d S N)r  rw  r>   )r   rx  s     r!   _remember_channel_is_forumr{    s    6:8nn%c'll333r#   c                 P    t                               t          |                     S rz  )rw  r^   r>   )r   s    r!   _probe_is_forum_cachedr}  !  s    ,00W>>>r#   c                 .  K   	 ddl }n# t          $ r ddicY S w xY w	 ddlm}m}  |d          } ||          \  }	}
dd	|  i}i |d
di}|pg }d}g }|rd| d}n.d}	 ddlm}  |d|          }n# t          $ r Y nw xY w|dk    rd}n&|d}n t          |          }||}nd}	 d| } |j	        d<d|
                    d          i|	4 d{V } |j        |fd|i|
4 d{V }|j        dk    rC|                                 d{V }|                    d          dk    }t          ||           ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   n-# t          $ r  t                              d|d           Y nw xY w|rt#          |          }d| d}g }|D ]n\  }}t$          j                            |          s5d| }t                              |           |                    |           Y|                    |           o |j	        d<d|
                    d          i|	4 d{V }|rd t/          |          D             }||d} t          j        || d           }!|                                }"|"                    d!|!d"           	 t/          |          D ]x\  }#}t7          |d#          5 }$|"                    d$|# d%|$                                t$          j                            |          &           ddd           n# 1 swxY w Y   y |j        |f||"d'|
4 d{V }%|%j        d(vrX|%                                 d{V }&tA          d)|%j         d*|&           cddd          d{V  cddd          d{V  S |%                                 d{V }'ddd          d{V  n# 1 d{V swxY w Y   n# t          $ r;}(tA          tC          d+|(                     cY d}(~(cddd          d{V  S d}(~(ww xY w |j        |f||d,|id d-|
4 d{V 	 }%|%j        d(vrX|%                                 d{V }&tA          d)|%j         d*|&           cddd          d{V  cddd          d{V  S |%                                 d{V }'ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   |'                    d.          })|'                    d/          pi                     d.|)          }*dd||)|*d0}+|r||+d1<   |+S d| d} |j	        d<d|
                    d2          i|	4 d{V }|"                                s|s |j        |f|d,|id-|
4 d{V }%|%j        d(vrX|%                                 d{V }&tA          d3|%j         d*|&           cddd          d{V  cddd          d{V  S |%                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   |D ]\  }}t$          j                            |          s5d| }t                              |           |                    |           Z	 |                                }"t$          j                            |          },t7          |d#          5 }-|"                    d4|-|,&            |j        |f||"d'|
4 d{V }%|%j        d(vr|%                                 d{V }&tC          d5| d6|%j         d*|&           }t          #                    |           |                    |           	 ddd          d{V  ddd           ]|%                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   ddd           n# 1 swxY w Y   # t          $ rO}(tC          d5| d7|(           }t          #                    |           |                    |           Y d}(~(d}(~(ww xY w	 ddd          d{V  n# 1 d{V swxY w Y   |d8}.|r|.|d9S d|.iS dd||                    d.          d:}+|r||+d1<   |+S # t          $ r}(tA          d;|(           cY d}(~(S d}(~(ww xY w)=u@  Send a single message via Discord REST API (no websocket client needed).

    Chunking is handled by _send_to_platform() before this is called.

    When thread_id is provided, the message is sent directly to that thread
    via the /channels/{thread_id}/messages endpoint.

    Media files are uploaded one-by-one via multipart/form-data after the
    text message is sent (same pattern as Telegram).

    Forum channels (type 15) reject POST /messages — a thread post is created
    automatically via POST /channels/{id}/threads.  Media files are uploaded
    as multipart attachments on the starter message of the new thread.

    Channel type is resolved from the channel directory first, then a
    process-local probe cache, and only as a last resort with a live
    GET /channels/{id} probe (whose result is memoized).
    r   Nr-   /aiohttp not installed. Run: pip install aiohttpresolve_proxy_urlproxy_kwargs_for_aiohttpDISCORD_PROXY)platform_env_varAuthorizationzBot Content-Typeapplication/jsonz%https://discord.com/api/v10/channels/	/messages)lookup_channel_typer   forumTFr3      totalheaders   rT   z#Failed to probe channel type for %sr   z/threadsrM  <   c                 r    g | ]4\  }}t          |          t          j                            |          d 5S ))idfilename)r>   r   r   basename).0idxr   s      r!   
<listcomp>z!_send_discord.<locals>.<listcomp>~  sJ     , , , )T $'s889I9I$9O9OPP, , ,r#   )r   attachments)r[   r+   payload_json)content_typerN  zfiles[])r  )r  datar     z%Discord forum thread creation error (): z$Discord forum thread upload failed: r   r  rh   r  r+   )r   r   r   r   r   r     zDiscord API error (zfiles[0]rT  z: Discord API error (rU  z6No deliverable text or media remained after processingrW  rX  zDiscord send failed: rD   )$aiohttpr  r   r  r  rg   r  rG   r}  ClientSessionClientTimeoutr^   statusrh   r{  rH   r  rv  r   r   r_  rI   r7  r  ri   FormData	add_fieldr`  readr  postr(   r.   r*   r   r-   )/r~   r   r+   r   r   r  r  r  _proxy_sess_kw_req_kwauth_headersjson_headers	last_datar  url_channel_typer  rx  cachedinfo_url	info_sess	info_respinfothread_name
thread_urlvalid_mediar   	_is_voicerI   sessionattachments_metastarter_messager  formr  fhrespbodyr  rj   thread_id_createdstarter_msg_idr   r  rp  r-   s/                                                  r!   r  r  %  s     &L L L LJKKKKLk3VVVVVVVV""ODDD44V<<''8K,K8JKK!'R	  q	MN)NNNCC !MIIIIII 3 3Iw G G    ''* /88%%HH$H	d#T7#T#T#87#8#m#mAVAV]_AVA`A`#mdl#m#m R R R R R R Rqz'4y}X'_'_|'_W^'_'_ R R R R R R Rcl#,#3s#:#:1:1A1A+A+A+A+A+A+AD/3xx/?/?2/EH$>w$Q$Q$Q	R R R R R R R R R R R R R R R R R R R R R R R R R R RR R R R R R R R R R R R R R R R R R R R R R R R R R R % d d d%JG^bcccccd  L7@@VWVVV
 !-8 3 3)J	7>>*55 !"QZ"Q"Qw/// 000 &&z2222070ee9N9NUW9N9X9Xe\dee 05 05 05 05 05 05 05ip" /5, ,-6{-C-C, , ,( 7>N^*_*_'+z;Sb2c2c'd'd&//11~|Rdeee
l3<[3I3I & &Z%)*d%;%; !&r$(NN(7(*		131A1A*1M1M %3 %& %& %&!& !& !& !& !& !& !& !& !& !& !& !& !& !& !& (4w|J'k[_'k'kcj'k'k 9 9 9 9 9 9 9os#';j#@#@15+<+<+<+<+<+<D+12pZ^Ze2p2pjn2p2p+q+q9 9 9 9 9 9 9 9 9 9 9 9 9505 05 05 05 05 05 05 05 05 05 05 05 05 05< .2YY[['8'8'8'8'8'8	9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
  ) l l l#)*>?ifg?i?i*j*j#k#kkkkkkA05 05 05 05 05 05 05 05 05 05 05 05 05 05>l
 $07<&$$0(3,5w+?" "$ $ &$ $ 5 5 5 5 5 5 5 5 "#{*<<-1YY[['8'8'8'8'8'8'-.lVZVa.l.lfj.l.l'm'm5 5 5 5 5 5 5 5 5 5 5 5 5I05 05 05 05 05 05 05 05 05 05 05 05 05 05` *.#4#4#4#4#4#4D5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5I05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05d %)HHTNN!"&((9"5"5";!@!@GX!Y!Y# )&!2"0   2)1F:&L'LLLC(7(]]1F1FR1F1P1P]T\]]  	-  	-  	-  	-  	-  	-  	-ah}} 2k 2'7<h\T[H\hh`ghh 2 2 2 2 2 2 2lp{*44%)YY[[000000%&RDK&R&RD&R&RSS2 2 2 2 2 2 2 2 2 2 2 2 2 	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	- '+iikk 1 1 1 1 1 1I	2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 *5 - -%
Iw~~j11 MMMGNN7+++OOG,,,-"++--D!w//
;;Hj$// 	:1z1xHHH#/7<#`\PT#`#`X_#`#` : : : : : : :dh#{*<<-1YY[['8'8'8'8'8'8*>  @OWa  @O  @Ox|  yD  @O  @O  IM  @O  @O  +P  +P &W 5 5 5 ( 8 8 8 (: : : : : : : : : : : :	: 	: 	: 	: 	: 	: 	: /3iikk(9(9(9(9(9(9I: : : : : : : : : : : : : : : : : : : : : : : : : : :	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: 	: ! - - -23\:3\3\YZ3\3\]]GLL)))OOG,,,,,,,,-'- 	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-  	-D LE >!&H===U##!yW\e\i\ijn\o\opp 	*!)F: 3 3 31a11222222223s  	 Ac. $A7 6c. 7
Bc. B*c. /.F
 E84AEE8
E	E8"E	#E8&F
 8
FF
 FF
 	c. 
'F41c. 3F44B7c. +A%T'$P5AMPMPMP0=O>-P?c. O>,P>
P	PP	PT'
QQ9Q:T'>c. QT'6=T3T'c. T2T'
T	T'T	T'c. '
T11c. 4T15Ac. 	/c. 80b+(=Y6%b+7c. 
Y6$b+6
Z 	 b+Z 	Ab+$A`<'0`/A1`	`/`<$b+&`	 `/
``/` `/#`</`33`<6`37`<:b+<
bAb
b+bb+c. +
b55c. 8b59c. c. "c. .
d8d	ddc           	      P  K   	 ddl }n# t          $ r ddicY S w xY w	 ddlm}m}  |            } ||          \  }}d}	d|  dd	}
 |j        dd
|                    d          i|4 d{V }||dd} |j        |	f|
|d|4 d{V }|                                 d{V }|	                    d          r>dd||	                    d          dcddd          d{V  cddd          d{V  S t          d|	                    dd                     cddd          d{V  cddd          d{V  S # 1 d{V swxY w Y   	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t          $ r}t          d|           cY d}~S d}~ww xY w)zSend via Slack Web API.r   Nr-   r  r  z&https://slack.com/api/chat.postMessageBearer r  r  r  r3   r  r  T)channelr(   mrkdwnr  okr   tsrX  zSlack API error: unknownzSlack send failed: rD   )r  r  r   r  r  r  r  r  rh   r^   r.   rG   )r~   r   r+   r  r  r  r  r  r  r  r  r  payloadr  r  rj   s                   r!   r!  r!    sk     L L L LJKKKKL1VVVVVVVV""$$44V<<'6$5e$5$5GYZZ(7(]]1F1FR1F1P1P]T\]] 	R 	R 	R 	R 	R 	R 	Rah")7dKKG#w|CRwRR'RR R R R R R R RVZ!YY[[((((((88D>> t'+WdhdldlmqdrdrssR R R R R R R R R R R R R	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R P$((7I2N2NPPQQ	R R R R R R R R R R R R R	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	RR R R R R R R R R R R R R R R	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R 	R  1 1 1/A//000000001s   	 AE? 1E,A	EE,*E? =%E"E,4E? 
E	E,E	E,E? ,
E66E? 9E6:E? ?
F%	F F% F%c                 L  K   	 ddl }n# t          $ r ddicY S w xY w	 |                     dd          }|                                4 d{V }|                    d| d||d	|                    d
                    4 d{V 	 }|j        dk    rX|                                 d{V }dd||                    d          dcddd          d{V  cddd          d{V  S |                                 d{V }t          d|j         d|           cddd          d{V  cddd          d{V  S # 1 d{V swxY w Y   	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t          $ r}	t          d|	           cY d}	~	S d}	~	ww xY w)z,Send via the local WhatsApp bridge HTTP API.r   Nr-   r  bridge_porti  zhttp://localhost:z/send)chatIdr+   r  r  )rh   r3   r  Tr   	messageIdrX  zWhatsApp bridge error (r  zWhatsApp send failed: )r  r  r^   r  r  r  r  rh   r(   r.   rG   )
r   r   r+   r  r  r  r  r  r  rj   s
             r!   r#  r#    s?     L L L LJKKKKL4iit44((** 	P 	P 	P 	P 	P 	P 	Pg||6K666 'G<<--B-77 $   P P P P P P P P ;#%%!%,,,,,,D#'$.#*&*hh{&;&;	 P P P P P P P P P P P P P	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P "YY[[((((((NNNNNOOP P P P P P P P P P P P P	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	PP P P P P P P P P P P P P P P	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P   4 4 42q22333333334s   	 0E= :E*	?EE*E= -3E E*2E= 
E	E*E	E*E= *
E44E= 7E48E= =
F#FF#F#c                 Z
   !"#$%K   	 ddl %n# t          $ r ddicY S w xY wddlm}m m}m}m}m}m	!m
}	 	 |                     dd                              d          $|                     d	d
          ""sddiS |pg }
g #|
D ]U\  }}t          j                            |          r#                    |           :t"                              d|           V#r, #fdt'          dt)          #                     D             }ng g}!"$%fd}dt*          ddf"$%fd} |	            }t"                              d|                                t)          #          t)          |                     g }t1          |          D ]\  }}t)          |          }|dk    rO|                    |          }||k    r4 |d ||           d|dz    dt)          |           d           d{V  |dk    r|nd
}t'          d|dz             D ]}	 |                    |           d{V  t7          j                    } |||           d{V }t7          j                    |z
  }d|vr|                    ||           d{V   n|d         } ||          s,t=          d|dz    dt)          |           d|           c c S  ||          }|                    ||           ||k    rP|                    |dz              t"                               d|dz   t)          |          ||r|ddnd            nt"                              d|dz   t)          |          |||r|ddnd           l# tB          $ r}||k    rY|                    |dz              t"                               d|dz   t)          |          |t+          |                     Y d}~ nJt"                              d|dz   t)          |          ||t+          |                     Y d}~d}~ww xY wg }t)          #          t)          |
          k     r|                    d            |rF|                    d!t)          |           d"d#"                    d$ |D                        d%           |r@t)          |          t)          |          k    r t=          d&t)          |           d'          S d(d)d*}|r||d+<   |S # tB          $ r}t=          d,|           cY d}~S d}~ww xY w)-u  Send via signal-cli JSON-RPC API.

    Supports both text-only and text-with-attachments (images/audio/documents).
    Multi-attachment sends are chunked into batches of
    SIGNAL_MAX_ATTACHMENTS_PER_MSG and metered by the process-wide
    SignalAttachmentScheduler — same bucket the gateway adapter uses, so
    sends from this tool and inbound-driven replies share rate-limit state.
    r   Nr-   httpx not installed)$SIGNAL_BATCH_PACING_NOTICE_THRESHOLDSIGNAL_MAX_ATTACHMENTS_PER_MSGSIGNAL_RATE_LIMIT_MAX_ATTEMPTS_extract_retry_after_seconds_format_wait_is_signal_rate_limit_error_signal_send_timeoutget_schedulerhttp_urlzhttp://127.0.0.1:8080/accountrl   zSignal account not configuredz)Signal media file not found, skipping: %sc                 *    g | ]}||z            S rD   rD   )r  rA  r  attachment_pathss     r!   r  z _send_signal.<locals>.<listcomp>H  s9        !1'E#E!EF  r#   c                   K   |d}	                     d          r	dd          |d<   n	g|d<   | r| |d<   dd|d	t          t          j                    d
z             d} | rt          |           nd          }                    |          4 d {V }|                    
 d|           d {V }|                                 |                                cd d d           d {V  S # 1 d {V swxY w Y   d S )Nr  r+   r      groupId	recipientr  2.0rR   send_  jsonrpcmethodparamsr  r   r3   /api/v1/rpcrh   )r   r^  timer   AsyncClientr  raise_for_statusrh   )batch_attachmentsbatch_messager  r  r3   clientr  r  r  r   r  httpxs          r!   _postz_send_signal.<locals>._postO  s     !(]CCF!!(++ 0$+ABBKy!!'.i{#  :(9}% !  7c$)++"45577	 G +*EV+]3/@+A+A+A\]^^G(((99 # # # # # # #V#[[H)A)A)A[PPPPPPPP%%'''yy{{# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #s   AC77
DDr(   r   c                   K   | d}                     d          rdd         |d<   ng|d<   	                     d          4 d{V }|                     d	d
d|dt          t	          j                    dz             d           d{V  ddd          d{V  dS # 1 d{V swxY w Y   dS # t
          $ r&}t                              d|           Y d}~dS d}~ww xY w)z9Best-effort one-shot RPC for a user-facing pacing notice.r  r   r  Nr  r        >@r  r  r  rR   notice_r  r  r  z Signal: inline notice failed: %s)r   r  r  r^  r  rG   rH   rI   )r(   notice_params_client_er  r   r  r  s       r!   _send_inline_noticez)_send_signal.<locals>._send_inline_noticed  s     (/DAAM!!(++ 7+2122;i((.5Yk*G ,,T,:: 	 	 	 	 	 	 	g!,,#000',&,&3"EC	d0B,C,C"E"E	  '         	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	  G G GA2FFFFFFFFFGs<   B? A
B,B? ,
B66B? 9B6:B? ?
C/	C**C/zIsend_message Signal: scheduler state=%s, %d attachment(s) in %d batch(es)u!   (More images coming — pausing ~z for Signal rate limit, batch r   z.)zSignal RPC error on batch rU  z`Signal: rate-limit retries exhausted on batch %d/%d (%d attachments lost, server retry_after=%s)z.0fsr  ziSignal: rate-limited on batch %d/%d (attempt %d/%d, server retry_after=%s); scheduler will pace the retryz7Signal: send error on batch %d/%d after %d attempts: %szFSignal: transient error on batch %d/%d (attempt %d/%d): %s; will retryz1Some media files were skipped (not found on disk)zSignal rate-limited z batch(es) (#z, #c              3   4   K   | ]}t          |          V  d S rz  )r>   )r  bs     r!   	<genexpr>z_send_signal.<locals>.<genexpr>  s(      ??1A??????r#   r   zSignal: every batch (z*) hit rate limit; no attachments deliveredTr   r   r   r   r  zSignal send failed: )#r  r  #gateway.platforms.signal_rate_limitr  r  r  r  r  r  r  r  r^   rstripr   r   r_  r7  rH   rI   rE   r   r>   r  stater  estimate_waitacquirer  	monotonicreport_rpc_durationr.   feedbackr-   rG   join)&r   r   r+   r   r  r  r  r  r  r  r  r   r  att_batchesr  r  	schedulerfailed_batchesr  	att_batchn	estimatedr  r0   _rpc_t0r  _rpc_durationerrserver_retry_afterrj   r  r   r  r  r  r  r  r  s&    `                              @@@@@@r!   r  r    s     0 0 0 0.////0	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	Y299Z)@AAHHMM))Ir** 	><==!'R%0 	X 	X!J	w~~j)) X ''
3333JJWWWW
  	    q#&6"7"79WXX  KK
 $K	# 	# 	# 	# 	# 	# 	# 	# 	#*	GC 	GD 	G 	G 	G 	G 	G 	G 	G 	G 	G* "MOO	WOOs#344c+6F6F	
 	
 	
 %''44 :	 :	NCIA1uu%33A66	 DDD--WLL<S<S W W8;aW WBEkBRBRW W W        
 (+axxGGRM $BQ$FGG . .-#++A........."n..G!&y-!@!@@@@@@@D$(N$4$4w$>Md**';;M1MMMMMMMMMw-C66s;; h%&f37&f&fSQ\M]M]&f&fad&f&fggggggg)E)Ec)J)J&&&'91==="@@@&--cAg666K!GS%5%5q<N]188888T]	   NN8 a[!1!1!?8JY-44444PY    !   "@@@&--cAg666U!GS%5%5wA   NN`a[!1!17<Z\_`a\b\b          3{#3#333OOOPPP 	OOCs>':': C CZZ???????C C C  
  	c.11S5E5EEE,K(8(8 , , ,  
 "xGLL 	*!)F: 2 2 20Q00111111112s    !!AT >FT A6M?T :M?
T A5M?T 7M?=T ?
P/	AP*"T (<P*$T *P//CT 5T 
T*T%T*%T*c                 L  K   ddl }ddlm} ddlm} |                     d          pt          j        dd          }t          j        dd          }|                     d	          pt          j        d
d          }	 t          t          j        dd                    }	n# t          t          f$ r d}	Y nw xY wt          |||g          sddiS 	  ||dd          }
||
d<   ||
d<   d|
d<    |d          |
d<   |                    ||	          }|                    t          j                               |                    ||           |                    |
           |                                 dd|dS # t&          $ r}t)          d|           cY d}~S d}~ww xY w)z:Send via SMTP (one-shot, no persistent connection needed).r   N)MIMEText)
formatdateaddressEMAIL_ADDRESSrl   EMAIL_PASSWORD	smtp_hostEMAIL_SMTP_HOSTEMAIL_SMTP_PORT587iK  r-   zNEmail not configured (EMAIL_ADDRESS, EMAIL_PASSWORD, EMAIL_SMTP_HOST required)ro  zutf-8FromTozHermes AgentSubjectT)	localtimeDate)contextemailr  zEmail send failed: )smtplibemail.mime.textr  email.utilsr  r^   r   r   r^  r=   r<   allSMTPstarttlssslcreate_default_contextloginrF   quitrG   r.   )r   r   r+   r'  r  r  r  passwordr  	smtp_portmsgserverrj   s                r!   r%  r%    s     NNN((((((&&&&&&ii	""Dbi&D&DGy)2..H		+&&J")4Er*J*JI	"3U;;<<			"   			 9-.. kijj1hw11FD	'I j4000Fi33 : < <===Wh'''C   WIII 1 1 1/A//000000001s1   ="B   B65B6B,E= =
F#FF#F#c                 6  K   	 ddl }n# t          $ r ddicY S w xY wddl}t          j        dd          }t          j        dd          }|r| r|sddiS t          j        d	d
|t
          j                  }t          j        dd
|t
          j                  }t          j        dd
|t
          j                  }t          j        dd
|t
          j                  }t          j        dd|          }t          j        dd
|          }t          j        dd|t
          j                  }t          j        dd
|          }t          j        dd|          }|	                                }	 ddl
m}m}  |            }	 ||	          \  }
}| d|  }|                    |                    d                                        d          }d| d}dd| i} |j        d,d|                    d          i|
4 d{V }|                                }|                    d|           |                    d |           |                    d!|            |j        |f||d"|4 d{V }|                                 d{V }|j        d#k    ra|                    d$t1          |                    }t3          d%|j         d&|           cddd          d{V  cddd          d{V  S |                    d'd          }d(d)||d*cddd          d{V  cddd          d{V  S # 1 d{V swxY w Y   	 ddd          d{V  dS # 1 d{V swxY w Y   dS # t4          $ r}t3          d+|           cY d}~S d}~ww xY w)-zSend a single SMS via Twilio REST API.

    Uses HTTP Basic auth (Account SID : Auth Token) and form-encoded POST.
    Chunking is handled by _send_to_platform() before this is called.
    r   Nr-   r  TWILIO_ACCOUNT_SIDrl   TWILIO_PHONE_NUMBERzXSMS not configured (TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_PHONE_NUMBER required)z\*\*(.+?)\*\*z\1)flagsz	\*(.+?)\*z	__(.+?)__z_(.+?)_z```[a-z]*\n?z`(.+?)`z
^#{1,6}\s+z\[([^\]]+)\]\([^\)]+\)z\n{3,}z

r  rm   asciiz+https://api.twilio.com/2010-04-01/Accounts/z/Messages.jsonr  zBasic r3   r  r  r   r!  Body)r  r  i  r+   zTwilio API error (r  sidTr   rX  zSMS send failed: rD   )r  r  base64r   r   rZ  r&   DOTALL	MULTILINEr   r   r  r  	b64encodeencodedecoder  r  r  r  r  rh   r  r^   r>   r.   rG   )
auth_tokenr   r+   r  r<  account_sidfrom_numberr  r  r  r  r  credsencodedr  r  r  	form_datar  r  	error_msgmsg_sidrj   s                          r!   r'  r'    s=     L L L LJKKKKL MMM)0"55K)1266K uj u ustt f%ugRYGGGGf\5'CCCGf\5'CCCGfZryAAAGf_b'22GfZ00Gf]Br|DDDGf.w??GfY00GmmooG/VVVVVVVV""$$44V<<'----""5<<#8#899@@IIWKWWW"$6W$6$67(7(]]1F1FR1F1P1P]T\]] 	g 	g 	g 	g 	g 	g 	gah((**I444g...000#w|CTiTTGTT g g g g g g gX\!YY[[((((((;#%% $CII > >I!"Rt{"R"Ry"R"RSS	g g g g g g g g g g g g g	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g ((5"--#'Uw^effg g g g g g g g g g g g g	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	gg g g g g g g g g g g g g g g	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g 	g  / / /-!--......../s   	 ,BM2 A.M2A"L:M&M2 9L:M'M2 :
M	MM	MM2 
M))M2 ,M)-M2 2
N<NNNc                   K   	 ddl }n# t          $ r ddicY S w xY w	 |                    d          pt          j        dd                              d          }| pt          j        d	d          } |r| sdd
iS | d}d|  dd}|                    |                    d                    4 d{V }|                    ||||d          4 d{V }	|	j	        dvrX|	
                                 d{V }
t          d|	j	         d|
           cddd          d{V  cddd          d{V  S |	                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   dd||                    d          dS # t          $ r}t          d|           cY d}~S d}~ww xY w)zSend via Mattermost REST API.r   Nr-   r  r  MATTERMOST_URLrl   r  MATTERMOST_TOKENzEMattermost not configured (MATTERMOST_URL, MATTERMOST_TOKEN required)z/api/v4/postsr  r  r  r  r  r  )
channel_idr+   r  r  zMattermost API error (r  T
mattermostr  rX  zMattermost send failed: )r  r  r^   r   r   r  r  r  r  r  r(   r.   rh   rG   )r~   r   r   r+   r  r{   r  r  r  r  r  r  rj   s                r!   r*  r*  ,  s     L L L LJKKKKL6IIe$$G	2BB(G(GOOPSTT:#5r:: 	fu 	fdee((($5e$5$5GYZZ((1F1FR1F1P1P(QQ 	) 	) 	) 	) 	) 	) 	)U\||Cgbi?j?j|kk ) ) ) ) ) ) )os;j00!%,,,,,,D!"Q4;"Q"Q4"Q"QRR) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)
 "YY[[((((((	) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)  \g]a]e]efj]k]klll 6 6 6444555555556s   	 AF5 :=F5 7"F
=E'F
(F5 ;E'F
'
E1	1F
4E1	5F
8F5 

FF5 FF5 5
G?GGGc                 (  K   	 ddl }n# t          $ r ddicY S w xY w	 |                    d          pt          j        dd                              d          }| pt          j        d	d          } |r| sdd
iS dt          t          j                    dz             dt          j        d          	                                 }ddl
m}  ||d          }| d| d| }	d|  dd}
d|d}	 ddl}|                    |ddg          }t          j        dd|          }d|d<   ||d<   n# t          $ r Y nw xY w|                    |                    d !          "          4 d{V }|                    |	|
|#          4 d{V }|j        d$vrX|                                 d{V }t)          d%|j         d&|           cddd          d{V  cddd          d{V  S |                                 d{V }ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   d'd(||                    d)          d*S # t,          $ r}t)          d+|           cY d}~S d}~ww xY w),zSend via Matrix Client-Server API.

    Converts markdown to HTML for rich rendering in Matrix clients.
    Falls back to plain text if the ``markdown`` library is not installed.
    r   Nr-   r  
homeserverMATRIX_HOMESERVERrl   r  MATRIX_ACCESS_TOKENzGMatrix not configured (MATRIX_HOMESERVER, MATRIX_ACCESS_TOKEN required)hermes_r  r      )quote)safez/_matrix/client/v3/rooms/z/send/m.room.message/r  r  r  zm.text)msgtyper  fenced_codetables)
extensionsz<h[1-6]>(.*?)</h[1-6]>z<strong>\1</strong>zorg.matrix.custom.htmlformatformatted_bodyr  r  r  r  r  zMatrix API error (r  Tr   event_idrX  Matrix send failed: )r  r  r^   r   r   r  r^  r  urandomhexurllib.parserU  rJ  rZ  r&   r  r  putr  r(   r.   rh   rG   )r~   r   r   r+   r  rP  txn_idrU  encoded_roomr  r  r  _mdrK  r  r  r  r  rj   s                      r!   r+  r+  D  s     L L L LJKKKKL2ii--S;NPR1S1S[[\_``
=#8"== 	h 	hfggJ3ty{{T122JJRZ]]5F5F5H5HJJ&&&&&&uW2...aalaaY_aa$5e$5$5GYZZ '88	""""<<]H4M<NND635KTRRD 8GH(,G$%% 	 	 	D	 ((1F1FR1F1P1P(QQ 	) 	) 	) 	) 	) 	) 	)U\{{3g{FF ) ) ) ) ) ) )$;j00!%,,,,,,D!"Mt{"M"Mt"M"MNN) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)
 "YY[[((((((	) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)  X'Y]YaYablYmYmnnn 2 2 20Q00111111112s   	 AI+ :A7I+ 2=D0 /I+ 0
D=:I+ <D==3I+ 0I =HI I+ 1HI 
H'	'I *H'	+I .I+  
I

I+ I
I+ +
J5JJJc                 @  K   	 ddl m} n# t          $ r ddicY S w xY w|pg }	  ||           }|                                 d{V }|s:t	          d          	 |                                 d{V  S # t          $ r Y S w xY w|rd|ind}d}	|                                rg|                    |||           d{V }	|	j	        sBt	          d	|	j
                   	 |                                 d{V  S # t          $ r Y S w xY w|D ]\  }
}t          j                            |
          s?t	          d
|
           c 	 |                                 d{V  S # t          $ r Y S w xY wt          j                            |
          d                                         }|t           v r|                    ||
|           d{V }	n|t$          v r|                    ||
|           d{V }	np|t(          v r!|r|                    ||
|           d{V }	nF|t,          v r|                    ||
|           d{V }	n|                    ||
|           d{V }	|	j	        sDt	          d|	j
                   c 	 |                                 d{V  S # t          $ r Y S w xY w|	/ddi	 |                                 d{V  S # t          $ r Y S w xY wdd||	j        d	 |                                 d{V  S # t          $ r Y S w xY w# t          $ rG}t	          d	|           cY d}~	 |                                 d{V  S # t          $ r Y S w xY wd}~ww xY w# 	 |                                 d{V  w # t          $ r Y w w xY wxY w)zISend via the Matrix adapter so native Matrix media uploads are preserved.r   )MatrixAdapterr-   zIMatrix dependencies not installed. Run: pip install 'mautrix[encryption]'NzMatrix connect failedr   metadatar^  Media file not found: r   zMatrix media send failed: rV  Tr   rX  )gateway.platforms.matrixrg  r  connectr.   
disconnectrG   r   rR   r   r-   r   r   r_  r   r?   r   send_image_filer   rb  r   rc  r   rf  r   )r   r   r+   r   r   rg  r   	connectedri  r@  r   r   r   rj   s                 r!   r  r  p  s     f::::::: f f fdeeeef #K0-((!//++++++++	 	3122R	$$&&&&&&&&&& 	 	 	D	S 09BK++d==?? 	J 'Wg Q QQQQQQQK& JH[5FHHIIB	$$&&&&&&&&&& 	 	 	D	C %0 	P 	P J7>>*-- ECzCCDDDD:	$$&&&&&&&&&& 	 	 	D	; '"":..q17799Ck!!$+$;$;GZZb$;$c$ccccccc##$+$6$6w
U]$6$^$^^^^^^^###$+$6$6w
U]$6$^$^^^^^^^##$+$6$6w
U]$6$^$^^^^^^^$+$9$9':X`$9$a$aaaaaaa& PN;;LNNOOOO	$$&&&&&&&&&& 	 	 	D	#P `a	$$&&&&&&&&&& 	 	 	D	  %0	
 
	$$&&&&&&&&&& 	 	 	D	  2 2 20Q001111111	$$&&&&&&&&&& 	 	 	D	2	$$&&&&&&&&&& 	 	 	D	s    5L A55
BBAL C::
DD
:L E  
E-,E-0DL J""
J/.J/2L :K
K"!K"%L 1L
LL
M-&M(7M-8M0 =M
M%$M%(M--M0 0N2NN
NNNNc                 b  K   	 ddl }n# t          $ r ddicY S w xY w	 |                    d          pt          j        dd                              d          }| pt          j        d	d          } |r| sdd
iS | d}d|  dd}|                    |                    d                    4 d{V }|                    ||||d          4 d{V }	|	j	        dvrX|	
                                 d{V }
t          d|	j	         d|
           cddd          d{V  cddd          d{V  S 	 ddd          d{V  n# 1 d{V swxY w Y   ddd          d{V  n# 1 d{V swxY w Y   dd|dS # t          $ r}t          d|           cY d}~S d}~ww xY w)z'Send via Home Assistant notify service.r   Nr-   r  r  HASS_URLrl   r  
HASS_TOKENz=Home Assistant not configured (HASS_URL, HASS_TOKEN required)z/api/services/notify/notifyr  r  r  r  r  r  )r+   rX   r  r  zHome Assistant API error (r  Thomeassistantr  zHome Assistant send failed: )r  r  r^   r   r   r  r  r  r  r  r(   r.   rG   )r~   r   r   r+   r  hass_urlr  r  r  r  r  rj   s               r!   r-  r-    s     L L L LJKKKKL:IIe$$A	*b(A(AII#NN4<44 	^u 	^\]]666$5e$5$5GYZZ((1F1FR1F1P1P(QQ 	W 	W 	W 	W 	W 	W 	WU\||C7^e?f?f|gg W W W W W W Wko;j00!%,,,,,,D!"Ut{"U"Ut"U"UVVW W W W W W W W W W W W W	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W0W W W W W W W W W W W W W W W W W W W W W W W W W W W	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W 	W
  _QQQ : : :8Q8899999999:s   	 AF :=F 7"E1=EE1(F <E1
E	E1E	E1F 1
E;;F >E;?F 
F.F)#F.)F.c                   K   	 ddl }n# t          $ r ddicY S w xY w	 |                     d          pt          j        dd          }|sddiS |                    d	
          4 d{V }|                    |dd|id           d{V }|                                 |                                }|                    dd          dk    r8t          d|                    dd                     cddd          d{V  S 	 ddd          d{V  n# 1 d{V swxY w Y   dd|dS # t          $ r}t          d|           cY d}~S d}~ww xY w)aq  Send via DingTalk robot webhook.

    Note: The gateway's DingTalk adapter uses per-session webhook URLs from
    incoming messages (dingtalk-stream SDK).  For cross-platform send_message
    delivery we use a static robot webhook URL instead, which must be
    configured via ``DINGTALK_WEBHOOK_URL`` env var or ``webhook_url`` in the
    platform's extra config.
    r   Nr-   r  webhook_urlDINGTALK_WEBHOOK_URLrl   zkDingTalk not configured. Set DINGTALK_WEBHOOK_URL env var or webhook_url in dingtalk platform extra config.r  r  r(   r   )rW  r(   r  errcodezDingTalk API error: errmsgr  Tdingtalkr  zDingTalk send failed: )r  r  r^   r   r   r  r  r  rh   r.   rG   )	r   r   r+   r  rv  r  r  r  rj   s	            r!   r/  r/    s     0 0 0 0.////04ii..W")<RTV2W2W 	L  K  L  L$$T$22 	V 	V 	V 	V 	V 	V 	Vf!')W1EFF %        D !!###99;;Dxx	1%%**TTXXh	5R5RTTUU	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V +	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V 	V  ZGLLL 4 4 42q22333333334sZ   	 /D1 D1 *B
D4D1 D1 
D$$D1 'D$(D1 1
E;EEEc                   K   	 ddl m}m}  |            sddiS n# t          $ r ddicY S w xY w	 ddlm}  ||           } ||          }|                                 d{V }|st          d	|j        pd
           S 	 |	                    ||           d{V }	|	j
        s1t          d|	j                   |                                 d{V  S dd||	j        d|                                 d{V  S # |                                 d{V  w xY w# t          $ r}
t          d|
           cY d}
~
S d}
~
ww xY w)z;Send via WeCom using the adapter's WebSocket send pipeline.r   )WeComAdaptercheck_wecom_requirementsr-   z?WeCom requirements not met. Need aiohttp + WECOM_BOT_ID/SECRET.zWeCom adapter not available.rv   r   NzWeCom: failed to connect - zunknown errorzWeCom send failed: TwecomrX  )gateway.platforms.wecomr|  r}  r  r   rw   rl  r.   fatal_error_messagerR   r   r-   rm  r   rG   )r   r   r+   r|  r}  rw   r   r   ro  r   rj   s              r!   r2  r2    s     9RRRRRRRR'')) 	`^__	` 9 9 97888891111111 .u---,w''!//++++++++	 	jh8S8fWfhhiii	'"<<99999999F> DBFLBBCC $$&&&&&&&&&&  $W\b\mnn$$&&&&&&&&&&'$$&&&&&&&&&& 1 1 1/A//000000001sN    ,,AD 9C= <D C= "D =DD 
E&D=7E=Ec                    K   	 ddl m}m}  |            sddiS n# t          $ r ddicY S w xY w	  || j        | j        |||           d{V S # t          $ r}t          d|           cY d}~S d}~ww xY w)	z6Send via Weixin iLink using the native adapter helper.r   )check_weixin_requirementssend_weixin_directr-   z9Weixin requirements not met. Need aiohttp + cryptography.zWeixin adapter not available.)r   r~   r   r+   r   NzWeixin send failed: )gateway.platforms.weixinr  r  r  r   r~   rG   r.   )r   r   r+   r   r  r  rj   s          r!   r  r    s     :ZZZZZZZZ((** 	ZXYY	Z : : :89999:	2''--#
 
 
 
 
 
 
 
 
 	
  2 2 20Q00111111112s)    ,,A 
A6A1+A61A6c                 v  K   	 ddl m}m}  |            sddiS n# t          $ r ddicY S w xY w	 ddlm}  ||           } ||          }|                                 d{V }|st          d	          S 	 |                    ||           d{V }	|	j	        s1t          d
|	j
                   |                                 d{V  S dd||	j        d|                                 d{V  S # |                                 d{V  w xY w# t          $ r}
t          d
|
           cY d}
~
S d}
~
ww xY w)zBSend via BlueBubbles iMessage server using the adapter's REST API.r   )BlueBubblesAdaptercheck_bluebubbles_requirementsr-   z8BlueBubbles requirements not met (need aiohttp + httpx).z"BlueBubbles adapter not available.rv   r~  Nz(BlueBubbles: failed to connect to serverzBlueBubbles send failed: TbluebubblesrX  )gateway.platforms.bluebubblesr  r  r  r   rw   rl  r.   rR   r   r-   rm  r   rG   )r   r   r+   r  r  rw   r   r   ro  r   rj   s              r!   r4  r4    s     ?dddddddd--// 	YWXX	Y ? ? ?=>>>>?7111111 .u---$$W--!//++++++++	 	FDEEE	'"<<99999999F> JH&,HHII $$&&&&&&&&&&  $7bhbstt$$&&&&&&&&&&'$$&&&&&&&&&& 7 7 75!55666666667sN    ,,AD 99C3 2D C3 D 3DD 
D8D3-D83D8c                   K   	 ddl m}m} |sddiS ddl m}m} n# t
          $ r ddicY S w xY w|pg }	  ||           }	t          |	dd          }
|
dk    r|n|}|	                    |          |	_        |rd	|ind
}d
}|	                                r<|	
                    |||           d
{V }|j        st          d|j                   S |D ]P\  }}t          j                            |          st          d|           c S t          j                            |          d                                         }|t&          v r|	                    |||           d
{V }n|t*          v r|	                    |||           d
{V }np|t.          v r!|r|	                    |||           d
{V }nF|t2          v r|	                    |||           d
{V }n|	                    |||           d
{V }|j        st          d|j                   c S R|ddiS dd||j        dS # t8          $ r}t          d|           cY d
}~S d
}~ww xY w)z7Send via Feishu/Lark using the adapter's send pipeline.r   )r   FEISHU_AVAILABLEr-   zJFeishu dependencies not installed. Run: pip install 'hermes-agent[feishu]')FEISHU_DOMAINLARK_DOMAIN_domain_namer   larkr   Nrh  zFeishu send failed: rj  r   zFeishu media send failed: rV  TrX  )r	  r   r  r  r  r  r9   _build_lark_clientr  r   rR   r   r.   r-   r   r   r_  r   r?   r   rn  r   rb  r   rc  r   rf  r   rG   )r   r   r+   r   r   r   r  r  r  r   domain_namedomainri  r@  r   r   r   rj   s                     r!   r0  r0  -  s     gLLLLLLLL 	kijjGGGGGGGGG g g geffffg #K*2-((g~x@@"-"7"7[!44V<</8BK++d==?? 	J 'Wg Q QQQQQQQK& JH[5FHHIII$/ 	P 	P J7>>*-- ECzCCDDDDD'"":..q17799Ck!!$+$;$;GZZb$;$c$ccccccc##$+$6$6w
U]$6$^$^^^^^^^###$+$6$6w
U]$6$^$^^^^^^^##$+$6$6w
U]$6$^$^^^^^^^$+$9$9':X`$9$a$aaaaaaa& PN;;LNNOOOOOP `aa  %0	
 
 	
  2 2 20Q00111111112sG     ,,BH4 :H4 	DH4  H4 (H4 4
I>IIIc                  ~    ddl m}   | dd          }|r|dk    rdS 	 ddlm}  |            S # t          $ r Y dS w xY w)	zOGate send_message on gateway running (always available on messaging platforms).r   r   r   rl   localT)is_gateway_runningF)r   r   gateway.statusr  rG   )r   r   r  s      r!   _check_send_messager  f  s    7777778"==H H''t555555!!###   uus   . 
<<c                   K   	 ddl }n# t          $ r t          d          cY S w xY w| j        pi }|                    d          pt          j        dd          }| j        p)|                    d          pt          j        dd          }|r|st          d	          S 	 |                    d
          4 d{V }|	                    dt          |          t          |          d           d{V }|j        dk    r)t          d|j                   cddd          d{V  S |                                }	|	                    d          }
|
s!t          d          cddd          d{V  S d|
 dd}d| d}|dd         dd}|	                    |||           d{V }|j        dv r@|                                }dd||                    d          dcddd          d{V  S t          d |j         d!|j                   cddd          d{V  S # 1 d{V swxY w Y   dS # t          $ r}t          d |           cY d}~S d}~ww xY w)"zSend via QQBot using the REST API directly (no WebSocket needed).

    Uses the QQ Bot Open Platform REST endpoints to get an access token
    and post a message. Works for guild channels without requiring
    a running gateway adapter.
    r   Nz8QQBot direct send requires httpx. Run: pip install httpxapp_id	QQ_APP_IDrl   client_secretQQ_CLIENT_SECRETz3QQBot: QQ_APP_ID / QQ_CLIENT_SECRET not configured.r  r  z)https://bots.qq.com/app/getAppAccessToken)appIdclientSecretr  r  zQQBot token request failed: access_tokenz"QQBot: no access_token in responsezQQBot r  r  z#https://api.sgroup.qq.com/channels/r  i  )r   msg_type)rh   r  r  Tqqbotr  rX  zQQBot send failed:  )r  r  r.   r   r^   r   r   r~   r  r  r>   status_coderh   r(   rG   )r   r   r+   r  r   appidsecretr  
token_resp
token_datar  r  r  r  r  r  rj   s                    r!   r6  r6  s  s     R R R RPQQQQQR MREIIh=29["#=#=Em 3uyy99 3-r22  M MKLLL1$$R$00 	T 	T 	T 	T 	T 	T 	TF%{{;"5zz3v;;GG  +          J %,,UZ=SUUVV	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T $**J%>>.99L ECDD	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T "9,!8!8 2 G KJJJC")%4%.a@@GSwHHHHHHHHD:--yy{{#'W&*hhtnn6 61	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T6 RD4DRRtyRRSS7	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T 	T8  1 1 1/A//000000001st   	 %% H= <AH*H= +9H*$H= 7A/H*&H= 9H*H= *
H44H= 7H48H= =
I#II#I#c                   K   	 ddl m}m} n# t          $ r t	          d          cY S w xY w |            }|t	          d          S 	  ||| ||           d{V S # t
          $ r}t	          d|           cY d}~S d}~ww xY w)u  Send via Yuanbao using the running gateway adapter's WebSocket connection.

    Yuanbao uses a persistent WebSocket — unlike HTTP-based platforms, we
    cannot create a throwaway client.  We obtain the running singleton from
    the adapter module itself (``get_active_adapter``).

    chat_id format:
      - Group: "group:<group_code>"
      - DM:    "direct:<account_id>" or just "<account_id>"
    r   )get_active_adaptersend_yuanbao_directz%Yuanbao adapter module not available.NzVYuanbao adapter is not running. Start the gateway with yuanbao platform enabled first.r  zYuanbao send failed: )gateway.platforms.yuanbaor  r  r  r.   rG   )r   r+   r   r  r  r   rj   s          r!   r   r     s      ?UUUUUUUUU ? ? ?=>>>>>? ! ""GE
 
 	

3(('7P[\\\\\\\\\\ 3 3 31a11222222223s*    ))A 
B'A>8B>B)registryr   	messagingu   📨)r[   toolsetschemahandlercheck_fnemoji)NNr   rz  )R__doc__rJ   rh   loggingr   rZ  typingr   r   r-  r  agent.redactr   	getLogger__name__rH   compiler   r   r   r   r   r   	frozensetr   r   r   r   r   r   rd  
IGNORECASEr%   r'   r>   r*   r   r.   rG   r^  r;   r@   rO   SEND_MESSAGE_SCHEMArc   r_   r`   r   r   r   r   r   r   r  rv  rw  r  __annotations__r{  r}  r  r!  r#  r  r%  r'  r*  r+  r  r-  r/  r2  r  r4  r0  r  r6  r   tools.registryr  r   registerrD   r#   r!   <module>r     s        				 				 ! ! ! ! ! ! ! ! 



  . . . . . .		8	$	$&BJ'DEE BJfgg  2:<== BJuvv RZ CDD -  9:::;; "*455888666@@@w $V, !rzWM   'BJQM  #    4C 4D 4 4 4 4
y 3 54<    2 EF ' ' 'c ' ' ' '& 	5  !(  a  !  o 
 !  k 
 
 #   @  L L LM7 M7 M7`(S (c ( ( ( (V: : :&  3  QTW[Q[    >  *R R R Rj~4 ~4 ~4 ~4Bs s     68 !4T	? 7 7 7E Et E E E E E?C ?HTN ? ? ? ?B3 B3 B3 B3J1 1 1.4 4 48r2 r2 r2 r2j1 1 1D5/ 5/ 5/p6 6 60)2 )2 )2X9 9 9 9x: : :.4 4 4>1 1 162 2 2 2*7 7 7662 62 62 62r
 
 
11 11 11h3 3 3 3< 0 / / / / / / /  	 
     r#   