
    KiS                        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 ej        e          Z	 ej
        d          Z ej
        d          Zh dZh dZh dZdd	h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d!edz  fd"Zd6d#Zd6d$Zd% Zd& Zd' Zd( Zd) Z d* Z!d+ Z"d, Z#d- Z$d. Z%d/ Z&d6d0Z'd1 Z(dd2l)m*Z*  e*j+        d
d3eee(d45           dS )7a$  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.
    Nz^\s*(-?\d+)(?::(\d+))?\s*$zD^\s*((?:oc|ou|on|chat|open)_[-A-Za-z0-9]+)(?::([-A-Za-z0-9_]+))?\s*$>   .gif.jpg.png.jpeg.webp>   .3gp.avi.mkv.mov.mp4>   .m4a.mp3.wav.ogg.opusr   r   send_messagea  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 Telegram topic 'telegram:chat_id:thread_id'. Examples: 'telegram', 'telegram:-1001234567890:17585', 'discord:#bot-home', 'slack:#engineering', 'signal:+15551234567')r   r   zThe message text to send)actiontargetmessage)r   
propertiesrequired)namer   
parametersc                 t    |                      dd          }|dk    rt                      S t          |           S )z-Handle cross-channel send_message tool calls.r   r   r   )get_handle_list_handle_send)argskwr   s      4/home/ubuntu/hermes-agent/tools/send_message_tool.pysend_message_toolr(   9   s8    XXh''F~~    c                      	 ddl m}  t          j        d |             i          S # t          $ r#}t          j        dd| i          cY d}~S d}~ww xY w)z5Return formatted list of available messaging targets.r   )format_directory_for_displaytargetserrorz"Failed to load channel directory: N)gateway.channel_directoryr+   jsondumps	Exception)r+   es     r'   r#   r#   C   s    OJJJJJJz9&B&B&D&DEFFF O O Oz7$L$L$LMNNNNNNNNOs   #& 
AAAAc                    |                      dd          }|                      dd          }|r|st          j        ddi          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          j        ddi          S 	 ddlm}m}  |            }n0# t          $ r#}t          j        dd| i          cY d	}~S d	}~ww xY w|j        |j        |j        |j        |j        |j        |j        |j        |j        |j        |j        |j        |j        d}|                     |          }|sCd                    |                                          }t          j        dd| d| i          S |j                             |          }|r|j         st          j        dd| di          S ddl!m"} |#                    |          \  }}|                                ptI          |          }d
}|sS|%                    |          }|r
|j&        }d}n2t          j        dd| d| d|'                                 di          S tQ          |||          }|rt          j        |          S 	 dd l)m*}  |tW          ||||||!                    }|r6tY          |tZ                    r!|                     d"          rd#| d$| d%|d&<   tY          |tZ                    rY|                     d"          rD|rB	 dd'l.m/} ta          j1        d(d)          } ||||||*          rd|d+<   n# t          $ r Y nw xY wt          j        |          S # t          $ r#}t          j        dd,| i          cY d	}~S d	}~ww xY w)-z$Send a message to a platform target.r    r   r-   z;Both 'target' and 'message' are required when action='send':   r   NF)resolve_channel_namez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matrix
mattermosthomeassistantdingtalkfeishuwecom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HERMES_SESSION_PLATFORMcli)source_labelrL   mirroredzSend failed: )2r"   r/   r0   splitstriplowerlen_parse_target_refr.   r7   r1   tools.interruptr8   gateway.configr:   r;   TELEGRAMDISCORDSLACKWHATSAPPSIGNALMATRIX
MATTERMOSTHOMEASSISTANTDINGTALKFEISHUWECOMEMAILSMSjoinkeys	platformsenabledgateway.platforms.baserJ   extract_media_describe_media_for_mirrorget_home_channelchat_idupper_maybe_skip_cron_duplicate_sendmodel_toolsrK   _send_to_platform
isinstancedictgateway.mirrorrQ   osgetenv) r%   r   r   partsplatform_name
target_refrr   rL   is_explicitr7   resolved_r8   r:   r;   configr2   platform_mapplatformavailpconfigrJ   rM   cleaned_messagemirror_textused_home_channelhomeduplicate_skiprK   resultrQ   rT   s                                    r'   r$   r$   L   sT   XXh##Fhhy"%%G d dz7$abccc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 ; ; ; ; ;     	 /.....~ 4z7M2333L@@@@@@@@$$&& L L Lz7$Ia$I$IJKKKKKKKKL %#%//)!/%/| L ..H _		,++--..z7$\$\$\UZ$\$\]^^^""8,,G ]'/ ]z7  %[  %[  %[  %[  \  ]  ]  	]::::::#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.))):******#'  	
 	
  	ZFD!9!9 	Zfjj>S>S 	ZYYYwYYYF6N fd## 	

9(=(= 	+ 	<<<<<<!y)BEJJ$$]G[Wcoxyyy .)-F:&    z&!!! : : :z7$7A$7$7899999999:st   AD! !'E
E5F 
F5F0*F50F5 BP> )0P P> 
P'$P> &P''P> >
Q+Q& Q+&Q+r}   r~   c                    | dk    rGt                               |          }|r+|                    d          |                    d          dfS | dk    rGt                              |          }|r+|                    d          |                    d          dfS |                    d                                          r|ddfS dS )	zFParse a tool target into chat_id/thread_id and whether it is explicit.r<   r6      TrE   -N)NNF)_TELEGRAM_TOPIC_TARGET_RE	fullmatchgroup_FEISHU_TARGET_RElstripisdigit)r}   r~   matchs      r'   rZ   rZ      s    
"")33J?? 	8;;q>>5;;q>>477  !++J77 	8;;q>>5;;q>>477%%'' &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.r4   r6   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])	rY   rz   pathsplitextrX   _VOICE_EXTS_IMAGE_EXTS_VIDEO_EXTS_AUDIO_EXTS)rM   
media_pathis_voiceexts       r'   rp   rp      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_PLATFORMr4    HERMES_CRON_AUTO_DELIVER_CHAT_IDN"HERMES_CRON_AUTO_DELIVER_THREAD_IDr   rr   rL   )rz   r{   rW   rX   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)   rr   rL   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   rr   rL   r5   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.)rN   skippedreasonr   rP   )r   strr"   )r}   rr   rL   auto_targetsame_targettarget_labels         r'   rt   rt      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} ddlm} ddlm} ddlm}	 ddlm	}
 	 ddl
m} d}n# t          $ r d	}Y nw xY w|pg }|j        |j        |j        |	j        |j        |
j        i}|r|j        ||j        <   |                    |           }|r|                    ||          }n|g}| |j        k    rd
}t)          |          D ]n\  }}|t+          |          dz
  k    }t-          |j        |||r|ng |           d
{V }t1          |t2                    r|                    d          r|c S |}o|S |r!|                                sdd| j         diS d
}|rd| j         d}d
}|D ]4}| |j        k    rt9          |j        ||           d
{V }n| |j        k    rt;          |j        ||           d
{V }n| |j        k    rt?          |j         ||           d
{V }n| |j!        k    rtE          |j         ||           d
{V }n]| |j#        k    rtI          |j         ||           d
{V }n4| |j%        k    rtM          |j'        ||           d
{V }n| |j(        k    r#tS          |j        |j         ||           d
{V }n| |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 }nY| |j        k    rta          ||||           d
{V }n4| |j1        k    rte          |j         ||           d
{V }ndd| j         i}t1          |t2                    r|                    d          r|c S |}6|rgt1          |t2                    rR|                    d          r=tg          |                    dg                     }|4                    |           ||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   )r;   rI   )TelegramAdapter)DiscordAdapter)SlackAdapter)FeishuAdapterTFNr6   )rM   rL   r-   zMsend_message MEDIA delivery is currently only supported for telegram; target z had only media attachmentsz#MEDIA attachments were omitted for zM; native send_message media delivery is currently only supported for telegram)rL   z'Direct sending not yet implemented for rN   warnings)5r\   r;   rn   rJ   gateway.platforms.telegramr   gateway.platforms.discordr   gateway.platforms.slackr   gateway.platforms.feishur   ImportErrorr]   MAX_MESSAGE_LENGTHr^   r_   rf   r"   truncate_message	enumeraterY   _send_telegramtokenrw   rx   rW   value_send_discord_send_slackr`   _send_whatsappextrara   _send_signalrh   _send_emailri   	_send_smsapi_keyrc   _send_mattermostrb   _send_matrixrd   _send_homeassistantre   _send_dingtalk_send_feishurg   _send_wecomr   append)r   r   rr   r   rL   rM   r;   rJ   r   r   r   r   _feishu_available_MAX_LENGTHSmax_lenchunkslast_resultichunkis_lastr   warningr   s                          r'   rv   rv     s      ('''''::::::::::::888888444444"::::::  " " "!" #K 	?=.;7L
  I(5(HX_% x((G $55gwGG 8$$$!&)) 	! 	!HAuCKK!O+G)+2:KK#        F &$'' FJJw,?,?  KK  
7==?? 
F".F F F
 	
 G 
Z(. Z Z Z 	
 K  x'''(GGGGGGGGFF''&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YYYZFfd## 	

7(;(; 	MMM +:k400 +[__Y5O5O +
B7788   "*Js   + ::c                   K   	 ddl m} ddlm} t	          t          j        d|                    }|r
|}|j        }	nM	 ddlm	}
m
} |
                    |
          }|                    |          }n# t          $ r |}Y nw xY w|j        }	 ||           }t          |          }|pg }i }|t          |          |d<   d}g }|                                r	  |j        d"|||	d	| d{V }n# t          $ r}d
t%          |                                          v sFdt%          |                                          v s#dt%          |                                          v r]t(                              d|	|           |s%	 ddlm
}  ||          }n# t          $ r |}Y nw xY w|} |j        d"||dd	| d{V }n Y d}~nd}~ww xY w|D ]\  }}t,          j                            |          s5d| }t(                              |           |                    |           Zt,          j                            |          d                                         }	 t7          |d          5 }|t8          v r |j        d"||d| d{V }nx|t<          v r |j        d"||d| d{V }nX|t@          v r|r |j!        d"||d| d{V }n6|tD          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          $ rB}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 # tN          $ r dd icY S t          $ r}dd!| i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   _strip_mdv2)r   Nmessage_thread_id)rr   text
parse_modeparsemarkdownhtmlzFParse mode %s failed in _send_telegram, falling back to plain text: %s)r   z Media file not found, skipping: r6   rb)rr   photo)rr   video)rr   voice)rr   audio)rr   documentzFailed to send media z: ANo deliverable text or media remained after processing MEDIA tags)r-   r   r-   Tr<   rN   r   rr   
message_idr   zGpython-telegram-bot not installed. Run: pip install python-telegram-botzTelegram send failed:  )(r<   r   telegram.constantsr   boolresearchHTMLr   r   r   __new__format_messager1   MARKDOWN_V2intrW   r   r   rX   loggerr   rz   r   existsr   r   openr   
send_photor   
send_videor   
send_voicer   
send_audiosend_documentr-   r   r   )r   rr   r   rM   rL   r   r   	_has_html	formattedsend_parse_moder   r   _adapterbotint_chat_idthread_kwargslast_msgr   md_errorplainr   r   r   r   fr2   r-   r   s                               r'   r   r     s     n7      000000 #6@@AA	 	4I'nOO$SSSSSSSS*22?CC$33G<<		 $ $ $#			$ (3Oc'll!'R 14YM-.?? 	!1!1 "'i." "2?" "          c(mm113333zS]]EXEXEZEZ7Z7Z^dhklthuhuh{h{h}h}^}^}NN#km|  G  H  H  H$ (,NNNNNN$/K	$:$:EE( , , ,$+EEE, !(%5S%5 & +%#'& &+8& &            HH
  HHHH& %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* * $ $ $ $ $ $%              *  ) ) )C*CCCCW%%%(((((((()
 WE >!&H===U## "h122	
 
  	*!)F: d d dbcccc 7 7 75!5566666667s   :N% 2A2 1N% 2B>N%  BAN% C1 0N% 1
G;BGFGF$!G#F$$GN% GBN% #L%3BLL%L	L%L	 L%#N% %
M1/7M,&N% ,M11N% ?N% !N% %O5	O>O
O
Oc                   K   	 ddl }n# t          $ r ddicY S w xY w	 d| d}d|  dd	}|                    |                    d
                    4 d{V }|                    ||d|i          4 d{V }|j        dvrM|                                 d{V }dd|j         d| i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}
dd|
 icY d}
~
S d}
~
ww xY w)zSend a single message via Discord REST API (no websocket client needed).

    Chunking is handled by _send_to_platform() before this is called.
    r   Nr-   /aiohttp not installed. Run: pip install aiohttpz%https://discord.com/api/v10/channels/z	/messageszBot application/jsonAuthorizationzContent-Type   totaltimeoutcontentheadersr/         zDiscord API error (): Tr=   idr   zDiscord send failed: )
aiohttpr   ClientSessionClientTimeoutpoststatusr   r/   r"   r1   )r   rr   r   r  urlr  sessionrespbodydatar2   s              r'   r   r     se     
L L L LJKKKKL6HgHHH$25NNDVWW((1F1FR1F1P1P(QQ 	) 	) 	) 	) 	) 	) 	)U\||C	7?S|TT ) ) ) ) ) ) )X\;j00!%,,,,,,D#%Q4;%Q%Q4%Q%QR) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)
 "YY[[((((((	) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)  Y7Z^ZbZbcgZhZhiii 6 6 644455555556s   	 >E !D#=2D /D#E D .D# 
D
	
D#D
	D#E #
D--E 0D-1E 
E)E$E)$E)c                   K   	 ddl }n# t          $ r ddicY S w xY w	 d}d|  dd}|                    |                    d	
                    4 d{V }|                    ||||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 dd|                    dd           i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}	dd|	 icY d}	~	S d}	~	ww xY w)zSend via Slack Web API.r   Nr-   r	  z&https://slack.com/api/chat.postMessageBearer r
  r  r  r  r  )channelr   r  okTr>   tsr   zSlack API error: unknownzSlack send failed: )r  r   r  r  r  r/   r"   r1   )
r   rr   r   r  r  r  r   r!  r#  r2   s
             r'   r   r     s     L L L LJKKKKL
46$5e$5$5GYZZ((1F1FR1F1P1P(QQ 	U 	U 	U 	U 	U 	U 	UU\||C7\c?d?d|ee U U U U U U Uim!YY[[((((((88D>> t'+WdhdldlmqdrdrssU U U U U U U U U U U U U	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U
  !STXXgy5Q5Q!S!ST	U U U U U U U U U U U U U	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	UU U U U U U U U U U U U U U U	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U 	U  4 4 42q2233333334s   	 :E "E:A	D'EE (D'EE '
D1	1E4D1	5E9E 
EE EE 
E:)E5/E:5E:c                    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 }dd|j         d| i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}	dd|	 i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  )r/   r  r  Tr?   	messageIdr   zWhatsApp bridge error (r  zWhatsApp send failed: )
r  r   r"   r  r  r  r  r/   r   r1   )
r   rr   r   r  r+  r   r!  r#  r"  r2   s
             r'   r   r   '  s9     L L L LJKKKKL7iit44((** 	S 	S 	S 	S 	S 	S 	Sg||6K666 'G<<--B-77 $   S S S S S S S S ;#%%!%,,,,,,D#'$.#*&*hh{&;&;	 S S S S S S S S S S S S S	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S "YY[[((((((!Q4;!Q!Q4!Q!QRS S S S S S S S S S S S S	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	SS S S S S S S S S S S S S S S	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S 	S   7 7 75!5566666667s   	 0E2 :E	?D:EE2 -(D:E'E2 :
E	EE	EE2 
E))E2 ,E)-E2 2
F<FFFc                   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dd|
d          i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}dd| i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/accountr4   zSignal account not configured)r2  r   zgroup:   groupId	recipientz2.0r   send_  )jsonrpcmethodparamsr        >@r  z/api/v1/rpcr/   zSignal RPC error: Tr@   rN   r   rr   zSignal send failed: )httpxr   r"   rstrip
startswithr   timeAsyncClientr  raise_for_statusr/   r1   )r   rr   r   r>  r0  r2  r:  payloadclientr!  r#  r2   s               r'   r   r   C  s     0 0 0 0.////05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$!Ed7m!E!EF	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  5 5 533344444445sb   	 AE/ #A5E/ AE1E/ E	E/ 
E&&E/ )E&*E/ /
F
9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                    }t          |||g          sddiS 	  ||dd          }	||	d<   ||	d<   d|	d<   |                    ||          }
|
	                    t          j                               |
                    ||           |
                    |	           |
                                 dd|dS # t          $ r}dd| i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_ADDRESSr4   EMAIL_PASSWORD	smtp_hostEMAIL_SMTP_HOSTEMAIL_SMTP_PORT587r-   zNEmail not configured (EMAIL_ADDRESS, EMAIL_PASSWORD, EMAIL_SMTP_HOST required)r  zutf-8FromTozHermes AgentSubject)contextTrG   r=  zEmail send failed: )smtplibemail.mime.textrG  r"   rz   r{   r   allSMTPstarttlssslcreate_default_contextloginr   quitr1   )r   rr   r   rS  rG  rH  passwordrK  	smtp_portmsgserverr2   s               r'   r   r   g  s     NNN((((((ii	""Dbi&D&DGy)2..H		+&&J")4Er*J*JIBI/7788I9-.. kijj4hw11FD	'Ii33 : < <===Wh'''C   WIII 4 4 42q2233333334s   /BE 
E(E#E(#E(c                   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                                        d          }d| d}	dd| i}
|                    |                    d                    4 d{V }|                                }|                    d|           |                    d|           |                    d |           |                    |	||
!          4 d{V }|                                 d{V }|j        d"k    rV|                    d#t+          |                    }dd$|j         d%| i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 # t,          $ r}dd*| i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_SIDr4   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

r5   asciiz+https://api.twilio.com/2010-04-01/Accounts/z/Messages.jsonr  zBasic r  r  r  rO  rP  Body)r#  r  i  r   zTwilio API error (r  sidTrH   r   zSMS send failed: )r  r   base64rz   r{   r   subDOTALL	MULTILINErW   	b64encodeencodedecoder  r  FormData	add_fieldr  r/   r  r"   r   r1   )
auth_tokenrr   r   r  rg  account_sidfrom_numbercredsencodedr  r  r   	form_datar!  r"  	error_msgmsg_sidr2   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2----""5<<#8#899@@IIWKWWW"$6W$6$67((1F1FR1F1P1P(QQ 	g 	g 	g 	g 	g 	g 	gU\((**I444g...000||Ci|II g g g g g g gT!YY[[((((((;#%% $CII > >I#%U$+%U%U)%U%UV	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  2 2 20Q0011111112s   	 ,A?M +A5M AL7M	M L8M
M 
L'	'M*L'	+M/M 
MM MM 
M0M+%M0+M0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rM|	
                                 d{V }
dd|	j	         d|
 i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}dd| icY d}~S d}~ww xY w)zSend via Mattermost REST API.r   Nr-   r	  r  MATTERMOST_URLr4   r1  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  TrB   r  r   zMattermost send failed: )r  r   r"   rz   r{   r?  r  r  r  r  r   r/   r1   )r   r   rr   r   r  base_urlr  r  r   r!  r"  r#  r2   s                r'   r   r     s     L L L LJKKKKL9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#%Tdk%T%Td%T%TU) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)
 "YY[[((((((	) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)  \g]a]e]efj]k]klll 9 9 97A7788888889s   	 AF* :=F* 7"E?2EE?F* 0E
E?
E&	&E?)E&	*E?-F* ?
F		F* F	F* *
G4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| d| }d|  dd}|                    |	                    d                    4 d{V }	|	
                    ||d|d          4 d{V }
|
j        dvrM|
                                 d{V }dd|
j         d| i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}dd| icY d}~S d}~ww xY w) z"Send via Matrix Client-Server API.r   Nr-   r	  
homeserverMATRIX_HOMESERVERr4   r1  MATRIX_ACCESS_TOKENzGMatrix not configured (MATRIX_HOMESERVER, MATRIX_ACCESS_TOKEN required)hermes_r7  z/_matrix/client/v3/rooms/z/send/m.room.message/r%  r
  r  r  r  r  zm.text)msgtyper"  r  r  zMatrix API error (r  TrA   event_idr   zMatrix send failed: )r  r   r"   rz   r{   r?  r   rA  r  r  putr  r   r/   r1   )r   r   rr   r   r  r~  txn_idr  r  r   r!  r"  r#  r2   s                 r'   r   r     s     L L L LJKKKKL5ii--S;NPR1S1S[[\_``
=#8"== 	h 	hfgg43ty{{T12244\\g\\TZ\\$5e$5$5GYZZ((1F1FR1F1P1P(QQ 	) 	) 	) 	) 	) 	) 	)U\{{3(\c>d>d{ee ) ) ) ) ) ) )im;j00!%,,,,,,D#%P$+%P%P$%P%PQ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)
 "YY[[((((((	) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)  X'Y]YaYablYmYmnnn 5 5 533344444445s   	 AG :A(G ""F*2F6F*G F5F*
F	F*F	F*G *
F44G 7F48G 
G0G+%G0+G0c                 6  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rM|	
                                 d{V }
dd|	j	         d|
 i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}dd| icY d}~S d}~ww xY w)z'Send via Home Assistant notify service.r   Nr-   r	  r  HASS_URLr4   r1  
HASS_TOKENz=Home Assistant not configured (HASS_URL, HASS_TOKEN required)z/api/services/notify/notifyr%  r
  r  r  r  r  )r   r   r  r  zHome Assistant API error (r  TrC   r=  zHome Assistant send failed: )r  r   r"   rz   r{   r?  r  r  r  r  r   r1   )r   r   rr   r   r  hass_urlr  r  r   r!  r"  r2   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 	Z 	Z 	Z 	Z 	Z 	Z 	ZU\||C7^e?f?f|gg Z Z Z Z Z Z Zko;j00!%,,,,,,D#%X$+%X%XRV%X%XYZ Z Z Z Z Z Z Z Z Z Z Z Z	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z0Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z Z	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z 	Z
  _QQQ = = =;;;<<<<<<<=s   	 AE= :=E= 7"E&2EE&E= 1E&
E	E&E	E&E= &
E00E= 3E04E= =
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    r-dd|                    dd           i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}dd| i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_URLr4   zkDingTalk not configured. Set DINGTALK_WEBHOOK_URL env var or webhook_url in dingtalk platform extra config.r;  r  r   r  )r  r   r<  errcodezDingTalk API error: errmsgr)  TrD   r=  zDingTalk send failed: )
r>  r   r"   rz   r{   rB  r  rC  r/   r1   )	r   rr   r   r>  r  rE  r!  r#  r2   s	            r'   r   r     s     0 0 0 0.////07ii..W")<RTV2W2W 	L  K  L  L$$T$22 	Y 	Y 	Y 	Y 	Y 	Y 	Yf!')W1EFF %        D !!###99;;Dxx	1%%**!W98U8U!W!WX	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y +	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y 	Y  ZGLLL 7 7 75!5566666667sZ   	 /D& D& *A?D)D& =D& 
DD& DD& &
E0D<6E<Ec                 H  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dd	|j        pd
 iS 	 |                    ||           d{V }	|	j	        s&dd|	j
         i|                                 d{V  S dd||	j        d|                                 d{V  S # |                                 d{V  w xY w# t          $ r}
dd|
 i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   Nu   WeCom: failed to connect — zunknown errorzWeCom send failed: TrF   r   )gateway.platforms.wecomr  r  r   r\   r  connectfatal_error_messager   rN   r-   
disconnectr   r1   )r   rr   r   r  r  r  r   adapter	connectedr   r2   s              r'   r   r      s     9RRRRRRRR'')) 	`^__	` 9 9 97888894111111 .u---,w''!//++++++++	 	omW=X=k\kmmnn	'"<<99999999F> G!Ev|!E!EF $$&&&&&&&&&&  $W\b\mnn$$&&&&&&&&&&'$$&&&&&&&&&& 4 4 42q2233333334sN    ,,AD 8.C' &D C' D 'DD 
D!DD!D!c                 b  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
}|	                                r1|	
                    |||           d
{V }|j        sdd|j         iS |D ]:\  }}t          j                            |          s	dd| ic S t          j                            |          d                                         }|t$          v r|	                    |||           d
{V }n|t(          v r|	                    |||           d
{V }np|t,          v r!|r|	                    |||           d
{V }nF|t0          v r|	                    |||           d
{V }n|	                    |||           d
{V }|j        sdd|j         ic S <|ddiS dd||j        dS # t6          $ r}dd| i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_namerE   larkrL   N)metadatazFeishu send failed: zMedia file not found: r6   zFeishu media send failed: r   Tr   )r   r   r  r  r  r   getattr_build_lark_client_clientrW   r   rN   r-   rz   r   r   r   rX   r   send_image_filer   r   r   r   r   r   r   r1   )r   rr   r   rM   rL   r   r  r  r  r  domain_namedomainr  r   r   r   r   r2   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*5-((g~x@@"-"7"7[!44V<</8BK++d==?? 	M 'Wg Q QQQQQQQK& M!K8I!K!KLL$/ 	S 	S J7>>*-- H!F*!F!FGGGG'"":..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& S!Qk>O!Q!QRRRRS `aa  %0	
 
 	
  5 5 533344444445sG     ,,BH /H 3DH ?H H 
H.H)#H.)H.c                      t          j        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).rR   r4   localTr   )is_gateway_runningF)rz   r{   gateway.statusr  r1   )r   r  s     r'   _check_send_messager  t  ss    y2B77H H''t555555!!###   uus   1 
??)registry	messagingu   📨)r   toolsetschemahandlercheck_fnemoji)NN),__doc__r/   loggingrz   r   rX  rA  	getLogger__name__r   compiler   r   r   r   r   r   SEND_MESSAGE_SCHEMAr(   r#   r$   r   rZ   rp   r   rt   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r  tools.registryr  registerr   r)   r'   <module>r     s      				 				 



 		8	$	$&BJ'DEE BJfgg 888666777w 	5  !(  a  !  p 
 !9 
 
 #   @  O O Ow: w: w:tS c    : : :&  3  QTW[Q[    >l l l l^v7 v7 v7 v7r6 6 6.4 4 4&7 7 78!5 !5 !5H4 4 4:22 22 22j9 9 905 5 52= = =.7 7 7>4 4 4665 65 65 65r	 	 	 $ # # # # #  	 
     r)   