1use async_trait::async_trait;
5use serde::Deserialize;
6use std::sync::Arc;
7
8use super::traits::*;
9use crate::channels::telegram::TelegramChannel;
10
11pub struct MessageTool {
12 tg: Arc<TelegramChannel>,
13}
14
15impl MessageTool {
16 pub fn new(tg: Arc<TelegramChannel>) -> Self {
17 Self { tg }
18 }
19}
20
21#[derive(Deserialize)]
22struct MessageArgs {
23 action: String,
25 message: Option<String>,
27 message_id: Option<i64>,
29}
30
31#[async_trait]
32impl Tool for MessageTool {
33 fn name(&self) -> &str {
34 "message"
35 }
36
37 fn spec(&self) -> ToolSpec {
38 ToolSpec {
39 name: "message".to_string(),
40 description: "Send, edit, or delete Telegram messages. Actions: send, edit, delete."
41 .to_string(),
42 parameters: serde_json::json!({
43 "type": "object",
44 "properties": {
45 "action": {
46 "type": "string",
47 "enum": ["send", "edit", "delete"],
48 "description": "Message action"
49 },
50 "message": {
51 "type": "string",
52 "description": "Message text (for send/edit)"
53 },
54 "message_id": {
55 "type": "integer",
56 "description": "Message ID (for edit/delete)"
57 }
58 },
59 "required": ["action"]
60 }),
61 }
62 }
63
64 async fn execute(&self, arguments: &str) -> anyhow::Result<ToolResult> {
65 let args: MessageArgs = serde_json::from_str(arguments)?;
66
67 match args.action.as_str() {
68 "send" => {
69 let text = args.message.unwrap_or_default();
70 if text.is_empty() {
71 return Ok(ToolResult::error("Message text required for send action"));
72 }
73 let msg_id = self.tg.send_message(&text).await?;
74 Ok(ToolResult::success(format!(
75 "Sent message (id: {})",
76 msg_id
77 )))
78 }
79 "edit" => {
80 let msg_id = args.message_id.unwrap_or(0);
81 let text = args.message.unwrap_or_default();
82 if msg_id == 0 || text.is_empty() {
83 return Ok(ToolResult::error(
84 "message_id and message required for edit action",
85 ));
86 }
87 self.tg.edit_message(msg_id, &text).await?;
88 Ok(ToolResult::success(format!("Edited message {}", msg_id)))
89 }
90 "delete" => {
91 let msg_id = args.message_id.unwrap_or(0);
92 if msg_id == 0 {
93 return Ok(ToolResult::error("message_id required for delete action"));
94 }
95 self.tg.delete_message(msg_id).await?;
96 Ok(ToolResult::success(format!("Deleted message {}", msg_id)))
97 }
98 other => Ok(ToolResult::error(format!("Unknown action: {}", other))),
99 }
100 }
101}