
    i,                        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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Zh dZh dZh d	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$d) Z%d*ed+efd,Z&d- Z'd. Z(d*ed/ed0edz  fd1Z)dJd2Z*dKd4Z+dJd5Z,d6 Z-d7 Z.d8 Z/d9 Z0d: Z1d; Z2d< Z3dJd=Z4d> Z5d? Z6d@ Z7dLdAZ8dB Z9dJdCZ:dD Z;dE Z<ddFl=m>Z>m?Z?  e>j@        ddGe"e#e;dHI           dS )Ma$  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)redact_sensitive_textz^\s*(-?\d+)(?::(\d+))?\s*$zD^\s*((?:oc|ou|on|chat|open)_[-A-Za-z0-9]+)(?::([-A-Za-z0-9_]+))?\s*$zS^\s*((?:wxid|gh|v\d+|wm|wb)_[A-Za-z0-9_-]+|[A-Za-z0-9._-]+@chatroom|filehelper)\s*$>   .gif.jpg.png.jpeg.webp>   .3gp.avi.mkv.mov.mp4>   .m4a.mp3.wav.ogg.opusr   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/agentuser/.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(   /   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)   r*   r,   r"   s       r   _telegram_retry_delayr:   4   s    #}d33K	u[))3///:& 	 	 	33	 s88>>Ddi4//tD==$&&D== D((D==$$D==Q'\"""4s   2 AA   )attemptsr<   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)botr<   kwargsr*   r)   delays         r   !_send_telegram_message_with_retryrI   M   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"r@   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')rN   rP   zThe message text to send)actiontargetr%   )rN   
propertiesrequired)namerP   
parametersc                 t    |                      dd          }|dk    rt                      S t          |           S )z-Handle cross-channel send_message tool calls.rQ   rL   rM   )get_handle_list_handle_send)argskwrQ   s      r   send_message_toolr]      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_directoryr_   jsondumpsrA   r(   )r_   es     r   rY   rY      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i d|j        d|j        d|j        d|j        d|j        d|j        d|j        d|j        d|j        d|j        d|j        d|j        d |j        d!|j        d"|j         d#|j!        d$|j"        }|                     |          }|s<d%#                    |$                                          }t          d&| d'|           S |j%                             |          }|r|j&        st          d(| d)          S dd*l'm(} |)                    |          \  }}|                                ptU          |          }d	}|sS|+                    |          }|r
|j,        }d+}n2t          j
        dd,| d-| d.|-                                 d/i          S t]          |||          }|rt          j
        |          S 	 dd0l/m0}  |tc          ||||||1                    }|r6te          |tf                    r!|                     d2          rd3| d4| d5|d6<   te          |tf                    rV|                     d2          rA|r?	 dd7l4m5} dd8l6m7}  |d9d:          }  ||||| |;          rd+|d<<   n# t          $ r Y nw xY wte          |tf                    rd|v rtq          |d                   |d<   t          j
        |          S # t          $ r.}t          j
        t#          d=|                     cY d}~S d}~ww xY w)>z$Send a message to a platform target.rR    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: telegramdiscordslackwhatsappsignalbluebubblesqqbotmatrix
mattermosthomeassistantdingtalkfeishuwecomwecom_callbackweixinemailsmsz, zUnknown platform: z. Available: z
Platform 'zZ' is not configured. Set up credentials in ~/.hermes/config.yaml or environment variables.)BasePlatformAdapterTz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)source_labelr   mirroredzSend failed: )9rX   
tool_errorsplitstripr9   len_parse_target_refra   rh   rb   rc   rA   tools.interruptri   gateway.configrk   rl   r(   TELEGRAMDISCORDSLACKWHATSAPPSIGNALBLUEBUBBLESQQBOTMATRIX
MATTERMOSTHOMEASSISTANTDINGTALKFEISHUWECOMWECOM_CALLBACKWEIXINEMAILSMSjoinkeys	platformsenabledgateway.platforms.baser~   extract_media_describe_media_for_mirrorget_home_channelchat_idupper_maybe_skip_cron_duplicate_sendmodel_toolsr   _send_to_platform
isinstancedictgateway.mirrorr   gateway.session_contextr   r$   )!r[   rR   r%   partsplatform_name
target_refr   r   is_explicitrh   resolved_ri   rk   rl   configrd   platform_mapplatformavailpconfigr~   r   cleaned_messagemirror_textused_home_channelhomeduplicate_skipr   resultr   r   r   s!                                    r   rZ   rZ      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H%8# 	 	H%	
 	(/ 	x+ 	 	(/ 	h) 	/ 	H% 	(/ 	 	(1 	(/  	!" 	x|#L& ..H T		,++--..R}RR5RRSSS""8,,G R'/ R  Q}  Q  Q  Q  R  R  	R::::::#6#D#DW#M#M K!''))T-G-T-TK 
&&x00 	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$$]G[Wcoxyyy .)-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7su   AD 'EE'E: :
F2#F-'F2-F2BR -P? >R ?
Q	R QAR 
S#SSS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	                                          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.rm   r   r2   Trx   rn   r{   N-rt   !@NNF)	_TELEGRAM_TOPIC_TARGET_RE	fullmatchr   _FEISHU_TARGET_RE_NUMERIC_TOPIC_RE_WEIXIN_TARGET_RElstripisdigit
startswith)r   r   matchs      r   r   r     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  !++J77 	.;;q>>4--%%'' &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.rf   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   ospathsplitextr9   _VOICE_EXTS_IMAGE_EXTS_VIDEO_EXTS_AUDIO_EXTS)r   
media_pathis_voiceexts       r   r   r   -  s     r
;1*1~
Hgz**1-3355 	*{**))+,,+,,+,,++9C$$9999r   c                  ,   t          j        dd                                                                          } t          j        dd                                          }| r|sdS t          j        dd                                          pd}| ||dS )zMReturn the cron scheduler's auto-delivery target for the current run, if any.!HERMES_CRON_AUTO_DELIVER_PLATFORMrf    HERMES_CRON_AUTO_DELIVER_CHAT_IDN"HERMES_CRON_AUTO_DELIVER_THREAD_IDr   r   r   )r   getenvr   r9   r   s      r   _get_cron_auto_delivery_targetr   @  s    y<bAAGGIIOOQQHi:B??EEGGG 7 t	>CCIIKKStI  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   rg   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reasonrR   r   )r   r8   rX   )r   r   r   auto_targetsame_targettarget_labels         r   r   r   N  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           	      l  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        <   |                    |           }|r(| |j        k    r|nd}|                    |||          }n|g}| |j        k    rd}t5          t7          |di           o|j                            d                    }t;          |          D ]o\  }}|t=          |          dz
  k    }t?          |j         |||r|ng ||           d{V }tC          |tD                    r|                    d          r|c S |}p|S | |j#        k    rtI          ||||           d{V S | |j        k    rd}t;          |          D ]n\  }}|t=          |          dz
  k    }tK          |j         |||r|ng |           d{V }tC          |tD                    r|                    d          r|c S |}o|S | |j&        k    r|r}d}t;          |          D ]i\  }}|t=          |          dz
  k    }tO          ||||r|ng |           d{V }tC          |tD                    r|                    d          r|c S |}j|S |r!|(                                sdd| j)         diS d}|rd| j)         d}d}|D ]W}| |j        k    rtU          |j         ||           d{V }n| |j+        k    rtY          |j        ||           d{V }n| |j-        k    rt]          |j        ||           d{V }n| |j/        k    rta          |j        ||           d{V }n| |j1        k    rte          |j3        ||           d{V }nW| |j4        k    r$tk          |j         |j        ||           d{V }n(| |j&        k    r#tm          |j         |j        ||           d{V }n| |j7        k    r#tq          |j         |j        ||           d{V }n| |j9        k    rtu          |j        ||           d{V }n| |j        k    rtw          ||||           d{V }n| |j<        k    rt{          |j        ||           d{V }nW| |j>        k    rt          |j        ||           d{V }n/| |j@        k    rt          |||           d{V }ndd| j)         i}tC          |tD                    r|                    d          r|c S |}Y|rgtC          |tD                    rR|                    d          r=t          |                    dg                     }|C                    |           ||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   )rl   )r~   	utf16_len)DiscordAdapter)SlackAdapterTelegramAdapterTF)FeishuAdapterz<Failed to apply Slack mrkdwn formatting in _send_to_platform)exc_infoi   N)len_fnextradisable_link_previewsr   )r   r   r   r'   )r   )r   r   zjsend_message MEDIA delivery is currently only supported for telegram, discord, matrix, and weixin; target z had only media attachmentsz#MEDIA attachments were omitted for zj; native send_message media delivery is currently only supported for telegram, discord, matrix, and weixin)r   z'Direct sending not yet implemented for r   warnings)Dr   rl   r   r~   r   gateway.platforms.discordr   gateway.platforms.slackr   gateway.platforms.telegramr   ImportErrorgateway.platforms.feishur   r   __new__format_messagerA   rB   debugr   MAX_MESSAGE_LENGTHr   r   rX   truncate_messageboolr3   r   	enumerater   _send_telegramtokenr   r   r   _send_weixin_send_discordr   _send_matrix_via_adapterr   value_send_slackr   _send_whatsappr   _send_signalr   _send_emailr   	_send_smsapi_keyr   _send_mattermost_send_matrixr   _send_homeassistantr   _send_dingtalk_send_feishur   _send_wecomr   _send_bluebubblesr   _send_qqbotrM   append)r   r   r   r%   r   r   rl   r~   r   r   r   r   _telegram_availabler   _feishu_availableslack_adapter_MAX_LENGTHSmax_len_len_fnchunkslast_resultr   ichunkis_lastr   rC   r   s                               r   r   r   m  s      ('''''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_%
 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  
7==?? 
F".F F F
 	
 G 
w(. w w w 	
 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YYYZFfd## 	

7(;(; 	MMM +:k400 +[__Y5O5O +
B7788   "*Js/   ' 66A AA'*B &B;:B;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'   rm   r   r   r   
message_idr   zGpython-telegram-bot not installed. Run: pip install python-telegram-botzTelegram send failed: r>   )*rm   r&  telegram.constantsr'  r  researchHTMLr   r   r   r   rA   MARKDOWN_V2intr   rI   r8   r9   rB   rC   r$   r.  r   r   existsr  r   openr   
send_photor   
send_videor   
send_voicer   
send_audiosend_documentr'   r;  r   r(   )r  r   r%   r   r   r   r&  r'  	_has_html	formattedsend_parse_moder   _adapterrF   int_chat_idthread_kwargslast_msgr   md_errorr.  plainr   r   rC   r   frd   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* * $ $ $ $ $ $ ++)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                   K   	 ddl }n# t          $ r ddicY S w xY w	 ddlm}m}  |d          } ||          \  }	}
|rd| d	}nd| d	}d
d|  i}|pg }d}g } |j        d&d|                    d          i|	4 d{V }|                                s|si |ddi} |j        |f|d|i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 ]\  }}t          j                            |          s5d| }t                               |           |                    |           Z	 |                                }t          j                            |          }t+          |d          5 }|                    d||            |j        |f||d|
4 d{V }|j	        dvr|
                                 d{V }t/          d| d|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   # t2          $ rO}t/          d| d|           }t                               |           |                    |           Y d}~d}~ww xY w	 ddd          d{V  n# 1 d{V swxY w Y   |d}|r||dS d|iS d d!||                    d"          d#}|r||d$<   |S # t2          $ r}t          d%|           cY d}~S d}~ww xY w)'a  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).
    r   Nr'   /aiohttp not installed. Run: pip install aiohttpresolve_proxy_urlproxy_kwargs_for_aiohttpDISCORD_PROXY)platform_env_varz%https://discord.com/api/v10/channels/	/messagesAuthorizationzBot r-      totalContent-Typeapplication/jsoncontentheadersrb         zDiscord API error (): r/  r0  zfiles[0])filename)rc  datar6  z: Discord API error (r7  z6No deliverable text or media remained after processingr9  Trn   idr:  r   zDiscord send failed: r>   )aiohttpr   r   rV  rW  ClientSessionClientTimeoutr   poststatusr"   r(   rb   r   r   rB  rB   rC   r  FormDatabasenamerC  	add_fieldr$   r'   rA   rX   )r  r   r%   r   r   rk  rV  rW  _proxy_sess_kw_req_kwurlauth_headers	last_datar   sessionrc  respbodyr   	_is_voicerC   formrh  rR  rd   r'   r   s                               r   r  r    s     L L L LJKKKKL<3VVVVVVVV""ODDD44V<<' 	MN)NNNCCL'LLLC'8!'R	(7(]]1F1FR1F1P1P]T\]] !	- !	- !	- !	- !	- !	- !	-ah}} 2k 2N\N>;MNN'7<cWIwCWcc[bcc 2 2 2 2 2 2 2gk{*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,,,,,,,,-'-!	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	- !	-F 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)O 8N?=E<NO !E;N
E	NE	AN;AL>0L.A1K)	L0L;N=K)	L)
K33L6K37L:LL

LL
LN
M,AM'!N'M,,N0O 
NO NO O ""O 
O+O& O+&O+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'   rT  rU  z&https://slack.com/api/chat.postMessageBearer r`  r[  r_  r-   r\  r]  T)channelr"   mrkdwnrb  okro   tsr:  zSlack API error: unknownzSlack send failed: r>   )rk  r   r   rV  rW  rl  rm  rn  rb   rX   r(   rA   )r  r   r%   rk  rV  rW  rs  rt  ru  rv  rc  ry  payloadrz  ri  rd   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'   rT  bridge_porti  zhttp://localhost:z/send)chatIdr%   r\  r]  )rb   r-   re  Trp   	messageIdr:  zWhatsApp bridge error (rg  zWhatsApp send failed: )rk  r   rX   rl  rn  rm  ro  rb   r"   r(   rA   )
r   r   r%   rk  r  ry  rz  ri  r{  rd   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                 F  K   	 ddl }n# t          $ r ddicY S w xY w	 |                     dd                              d          }|                     dd	          }|sdd
iS ||d}|                    d          r|dd         |d<   n|g|d<   dd|dt          t          j                    dz             d}|                    d          4 d{V }|                    | d|           d{V }	|		                                 |	
                                }
d|
v r*t          d|
d                    cddd          d{V  S dd|d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)z!Send via signal-cli JSON-RPC API.r   Nr'   httpx not installedhttp_urlzhttp://127.0.0.1:8080/accountrf   zSignal account not configured)r  r%   zgroup:   groupId	recipientz2.0rL   send_  )jsonrpcmethodparamsrj        >@r-   z/api/v1/rpcrb   zSignal RPC error: Trq   r   r   r   zSignal send failed: )httpxr   rX   rstripr   rA  timeAsyncClientrn  raise_for_statusrb   r(   rA   )r   r   r%   r  r  r  r  r  clientrz  ri  rd   s               r   r  r    s     0 0 0 0.////0299Z)@AAHHMM))Ir** 	><==$99h'' 	, 'F9#*)F; 3#dikkD01133	
 
 $$T$22 	O 	O 	O 	O 	O 	O 	Of%=%=%=GLLLLLLLLD!!###99;;D$B4=BBCC	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O  $gNN	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O 	O  2 2 20Q00111111112sb   	 AE: #A5E: A$E'<E: E'E: '
E11E: 4E15E: :
F FF F c                 "  K   ddl }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<   |
                    ||          }
|
                    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addressEMAIL_ADDRESSrf   EMAIL_PASSWORD	smtp_hostEMAIL_SMTP_HOSTEMAIL_SMTP_PORT587iK  r'   zNEmail not configured (EMAIL_ADDRESS, EMAIL_PASSWORD, EMAIL_SMTP_HOST required)rQ  zutf-8FromTozHermes AgentSubject)contextTr|   r  zEmail send failed: )smtplibemail.mime.textr  rX   r   r   rA  r7   r6   allSMTPstarttlssslcreate_default_contextloginr@   quitrA   r(   )r   r   r%   r  r  r  passwordr  	smtp_portmsgserverrd   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i33 : < <===Wh'''C   WIII 1 1 1/A//000000001s1   7"B B0/B0
BE( (
F2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'   rT  TWILIO_ACCOUNT_SIDrf   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

rU  rg   asciiz+https://api.twilio.com/2010-04-01/Accounts/z/Messages.jsonr[  zBasic r-   r\  r]  r  r  Body)ri  rc  i  r%   zTwilio API error (rg  sidTr}   r:  zSMS send failed: r>   )rk  r   base64r   r   r=  r    DOTALL	MULTILINEr   r   rV  rW  	b64encodeencodedecoderl  rm  rp  rr  rn  rb   ro  rX   r8   r(   rA   )
auth_tokenr   r%   rk  r  account_sidfrom_numberrV  rW  rs  rt  ru  credsencodedrv  rc  ry  	form_datarz  r{  	error_msgmsg_sidrd   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'   rT  rv  MATTERMOST_URLrf   r  MATTERMOST_TOKENzEMattermost not configured (MATTERMOST_URL, MATTERMOST_TOKEN required)z/api/v4/postsr  r`  r  r\  r]  r  )
channel_idr%   rb  rd  zMattermost API error (rg  Tru   rj  r:  zMattermost send failed: )rk  r   rX   r   r   r  rl  rm  rn  ro  r"   r(   rb   rA   )r  r   r   r%   rk  base_urlrv  rc  ry  rz  r{  ri  rd   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'   rT  
homeserverMATRIX_HOMESERVERrf   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  rb  rd  zMatrix API error (rg  Trt   event_idr:  Matrix send failed: )rk  r   rX   r   r   r  rA  r  urandomhexurllib.parser  r,  r=  r    rl  rm  putro  r"   r(   rb   rA   )r  r   r   r%   rk  r  txn_idr  encoded_roomrv  rc  r  _mdr-  ry  rz  r{  ri  rd   s                      r   r  r    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: r8  Trt   r:  )gateway.platforms.matrixr  r   connectr(   
disconnectrA   r   rL   r   r'   r   r   rB  r   r9   r   send_image_filer   rE  r   rF  r   rH  r;  )r   r   r%   r   r   r  adapter	connectedr  r!  r   r   r   rd   s                 r   r	  r	    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'   rT  rv  HASS_URLrf   r  
HASS_TOKENz=Home Assistant not configured (HASS_URL, HASS_TOKEN required)z/api/services/notify/notifyr  r`  r  r\  r]  r  )r%   rR   rb  rd  zHome Assistant API error (rg  Trv   r  zHome Assistant send failed: )rk  r   rX   r   r   r  rl  rm  rn  ro  r"   r(   rA   )r  r   r   r%   rk  hass_urlrv  rc  ry  rz  r{  rd   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_URLrf   zkDingTalk not configured. Set DINGTALK_WEBHOOK_URL env var or webhook_url in dingtalk platform extra config.r  r  r"   ra  )r  r"   r  errcodezDingTalk API error: errmsgr  Trw   r  zDingTalk send failed: )r  r   rX   r   r   r  rn  r  rb   r(   rA   )	r   r   r%   r  r  r  rz  ri  rd   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.PlatformConfigr   NzWeCom: failed to connect - zunknown errorzWeCom send failed: Try   r:  )gateway.platforms.wecomr  r  r   r   r  r  r(   fatal_error_messagerL   r   r'   r  r;  rA   )r   r   r%   r  r  r  r   r  r  r   rd   s              r   r  r  I  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  rA   r(   )r   r   r%   r   r
  r  rd   s          r   r  r  d  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.r  r  Nz(BlueBubbles: failed to connect to serverzBlueBubbles send failed: Trr   r:  )gateway.platforms.bluebubblesr  r  r   r   r  r  r(   rL   r   r'   r  r;  rA   )r   r   r%   r  r  r  r   r  r  r   rd   s              r   r  r  y  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_namerx   larkr   Nr  zFeishu send failed: r  r   zFeishu media send failed: r8  Tr:  )r   r   r  r  r  r   r3   _build_lark_client_clientr   rL   r   r(   r'   r   r   rB  r   r9   r   r  r   rE  r   rF  r   rH  r;  rA   )r   r   r%   r   r   r   r  r  r  r  domain_namedomainr  r!  r   r   r   rd   s                     r   r  r    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   rf   localT)is_gateway_runningF)r   r   gateway.statusr  rA   )r   r   r  s      r   _check_send_messager    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_IDrf   client_secretQQ_CLIENT_SECRETz3QQBot: QQ_APP_ID / QQ_CLIENT_SECRET not configured.   r  z)https://bots.qq.com/app/getAppAccessToken)appIdclientSecretr  re  zQQBot token request failed: access_tokenz"QQBot: no access_token in responsezQQBotAccessToken r`  r  z#https://api.sgroup.qq.com/channels/rZ  i  )ra  msg_type)rb   rc  rd  Trs   rj  r:  zQQBot send failed:  )r  r   r(   r   rX   r   r   r  r  rn  r8   status_coderb   r"   rA   )r   r   r%   r  r   appidsecretr  
token_resp
token_datar(  rc  rv  r  rz  ri  rd   s                    r   r  r    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 "D\!C!C 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#)registryr   	messagingu   📨)rU   toolsetschemahandlercheck_fnemoji)NNr   )N)A__doc__rD   rb   loggingr   r=  r  r  agent.redactr   	getLogger__name__rB   compiler   r   r   r   r   r   r   r   
IGNORECASEr   r!   r8   r$   r   r(   rA   rA  r5   r:   rI   SEND_MESSAGE_SCHEMAr]   rY   rZ   r   r   r   r   r   r  r  r  r  r  r  r  r  r  r	  r  r  r  r  r  r  r  r  tools.registryr0  r   registerr>   r   r   <module>rA     so       				 				 



  . . . . . .		8	$	$&BJ'DEE BJfgg BJuvv - 888666777w!rzWM   'BJQM  #    4C 4D 4 4 4 4
y 3 54<    2 EF ' ' 'c ' ' ' '& 	5  !(  a  !  ` 
 !9 
 
 #   @  L L L~7 ~7 ~7BS c    4: : :&  3  QTW[Q[    >e e e eP~4 ~4 ~4 ~4BK3 K3 K3 K3\1 1 1.4 4 48!2 !2 !2H1 1 1@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1j 0 / / / / / / /  	 
     r   