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 #[allow(dead_code)]
31 emoji: Option<String>,
32}
33
34#[async_trait]
35impl Tool for MessageTool {
36 fn name(&self) -> &str {
37 "message"
38 }
39
40 fn spec(&self) -> ToolSpec {
41 ToolSpec {
42 name: "message".to_string(),
43 description: "Send, edit, or delete Telegram messages. Actions: send, edit, delete."
44 .to_string(),
45 parameters: serde_json::json!({
46 "type": "object",
47 "properties": {
48 "action": {
49 "type": "string",
50 "enum": ["send", "edit", "delete"],
51 "description": "Message action"
52 },
53 "message": {
54 "type": "string",
55 "description": "Message text (for send/edit)"
56 },
57 "message_id": {
58 "type": "integer",
59 "description": "Message ID (for edit/delete)"
60 }
61 },
62 "required": ["action"]
63 }),
64 }
65 }
66
67 async fn execute(&self, arguments: &str) -> anyhow::Result<ToolResult> {
68 let args: MessageArgs = serde_json::from_str(arguments)?;
69
70 match args.action.as_str() {
71 "send" => {
72 let text = args.message.unwrap_or_default();
73 if text.is_empty() {
74 return Ok(ToolResult::error("Message text required for send action"));
75 }
76 let msg_id = self.tg.send_message(&text).await?;
77 Ok(ToolResult::success(format!(
78 "Sent message (id: {})",
79 msg_id
80 )))
81 }
82 "edit" => {
83 let msg_id = args.message_id.unwrap_or(0);
84 let text = args.message.unwrap_or_default();
85 if msg_id == 0 || text.is_empty() {
86 return Ok(ToolResult::error(
87 "message_id and message required for edit action",
88 ));
89 }
90 self.tg.edit_message(msg_id, &text).await?;
91 Ok(ToolResult::success(format!("Edited message {}", msg_id)))
92 }
93 "delete" => {
94 let msg_id = args.message_id.unwrap_or(0);
95 if msg_id == 0 {
96 return Ok(ToolResult::error("message_id required for delete action"));
97 }
98 self.tg.delete_message(msg_id).await?;
99 Ok(ToolResult::success(format!("Deleted message {}", msg_id)))
100 }
101 other => Ok(ToolResult::error(format!("Unknown action: {}", other))),
102 }
103 }
104}