1use crate::api::{ApiClient, ApiError, ApiMethod, ApiResponse};
4use crate::commands::guards::{check_write_allowed, confirm_destructive_with_hint};
5use serde_json::json;
6use std::collections::HashMap;
7
8pub async fn msg_post(
21 client: &ApiClient,
22 channel: String,
23 text: String,
24 thread_ts: Option<String>,
25 reply_broadcast: bool,
26) -> Result<ApiResponse, ApiError> {
27 check_write_allowed()?;
28
29 let mut params = HashMap::new();
30 params.insert("channel".to_string(), json!(channel));
31 params.insert("text".to_string(), json!(text));
32
33 if let Some(ts) = thread_ts {
34 params.insert("thread_ts".to_string(), json!(ts));
35 if reply_broadcast {
36 params.insert("reply_broadcast".to_string(), json!(true));
37 }
38 }
39
40 client.call_method(ApiMethod::ChatPostMessage, params).await
41}
42
43pub async fn msg_update(
57 client: &ApiClient,
58 channel: String,
59 ts: String,
60 text: String,
61 yes: bool,
62 non_interactive: bool,
63) -> Result<ApiResponse, ApiError> {
64 check_write_allowed()?;
65
66 let hint = format!(
68 "Example: slack-rs msg update {} {} \"new text\" --yes",
69 channel, ts
70 );
71 confirm_destructive_with_hint(yes, "update this message", non_interactive, Some(&hint))?;
72
73 let mut params = HashMap::new();
74 params.insert("channel".to_string(), json!(channel));
75 params.insert("ts".to_string(), json!(ts));
76 params.insert("text".to_string(), json!(text));
77
78 client.call_method(ApiMethod::ChatUpdate, params).await
79}
80
81pub async fn msg_delete(
94 client: &ApiClient,
95 channel: String,
96 ts: String,
97 yes: bool,
98 non_interactive: bool,
99) -> Result<ApiResponse, ApiError> {
100 check_write_allowed()?;
101
102 let hint = format!("Example: slack-rs msg delete {} {} --yes", channel, ts);
104 confirm_destructive_with_hint(yes, "delete this message", non_interactive, Some(&hint))?;
105
106 let mut params = HashMap::new();
107 params.insert("channel".to_string(), json!(channel));
108 params.insert("ts".to_string(), json!(ts));
109
110 client.call_method(ApiMethod::ChatDelete, params).await
111}
112
113#[cfg(test)]
114mod tests {
115 use super::*;
116 use serial_test::serial;
117
118 #[tokio::test]
119 #[serial(write_guard)]
120 async fn test_msg_post_with_env_false() {
121 std::env::set_var("SLACKCLI_ALLOW_WRITE", "false");
122 let client = ApiClient::with_token("test_token".to_string());
123 let result = msg_post(
124 &client,
125 "C123456".to_string(),
126 "test message".to_string(),
127 None,
128 false,
129 )
130 .await;
131 assert!(result.is_err());
132 assert!(matches!(result.unwrap_err(), ApiError::WriteNotAllowed));
133 std::env::remove_var("SLACKCLI_ALLOW_WRITE");
134 }
135
136 #[tokio::test]
137 #[serial(write_guard)]
138 async fn test_msg_update_with_env_false() {
139 std::env::set_var("SLACKCLI_ALLOW_WRITE", "false");
140 let client = ApiClient::with_token("test_token".to_string());
141 let result = msg_update(
142 &client,
143 "C123456".to_string(),
144 "1234567890.123456".to_string(),
145 "updated text".to_string(),
146 true,
147 false,
148 )
149 .await;
150 assert!(result.is_err());
151 assert!(matches!(result.unwrap_err(), ApiError::WriteNotAllowed));
152 std::env::remove_var("SLACKCLI_ALLOW_WRITE");
153 }
154
155 #[tokio::test]
156 #[serial(write_guard)]
157 async fn test_msg_delete_with_env_false() {
158 std::env::set_var("SLACKCLI_ALLOW_WRITE", "false");
159 let client = ApiClient::with_token("test_token".to_string());
160 let result = msg_delete(
161 &client,
162 "C123456".to_string(),
163 "1234567890.123456".to_string(),
164 true,
165 false,
166 )
167 .await;
168 assert!(result.is_err());
169 assert!(matches!(result.unwrap_err(), ApiError::WriteNotAllowed));
170 std::env::remove_var("SLACKCLI_ALLOW_WRITE");
171 }
172}