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(
23 client: &ApiClient,
24 channel: String,
25 text: String,
26 thread_ts: Option<String>,
27 reply_broadcast: bool,
28 yes: bool,
29 non_interactive: bool,
30) -> Result<ApiResponse, ApiError> {
31 check_write_allowed()?;
32
33 let hint = format!("Example: slack-rs msg post {} \"{}\" --yes", channel, text);
35 confirm_destructive_with_hint(yes, "post this message", non_interactive, Some(&hint))?;
36
37 let mut params = HashMap::new();
38 params.insert("channel".to_string(), json!(channel));
39 params.insert("text".to_string(), json!(text));
40
41 if let Some(ts) = thread_ts {
42 params.insert("thread_ts".to_string(), json!(ts));
43 if reply_broadcast {
44 params.insert("reply_broadcast".to_string(), json!(true));
45 }
46 }
47
48 client.call_method(ApiMethod::ChatPostMessage, params).await
49}
50
51pub async fn msg_update(
65 client: &ApiClient,
66 channel: String,
67 ts: String,
68 text: String,
69 yes: bool,
70 non_interactive: bool,
71) -> Result<ApiResponse, ApiError> {
72 check_write_allowed()?;
73
74 let hint = format!(
76 "Example: slack-rs msg update {} {} \"new text\" --yes",
77 channel, ts
78 );
79 confirm_destructive_with_hint(yes, "update this message", non_interactive, Some(&hint))?;
80
81 let mut params = HashMap::new();
82 params.insert("channel".to_string(), json!(channel));
83 params.insert("ts".to_string(), json!(ts));
84 params.insert("text".to_string(), json!(text));
85
86 client.call_method(ApiMethod::ChatUpdate, params).await
87}
88
89pub async fn msg_delete(
102 client: &ApiClient,
103 channel: String,
104 ts: String,
105 yes: bool,
106 non_interactive: bool,
107) -> Result<ApiResponse, ApiError> {
108 check_write_allowed()?;
109
110 let hint = format!("Example: slack-rs msg delete {} {} --yes", channel, ts);
112 confirm_destructive_with_hint(yes, "delete this message", non_interactive, Some(&hint))?;
113
114 let mut params = HashMap::new();
115 params.insert("channel".to_string(), json!(channel));
116 params.insert("ts".to_string(), json!(ts));
117
118 client.call_method(ApiMethod::ChatDelete, params).await
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124 use serial_test::serial;
125
126 #[tokio::test]
127 #[serial(write_guard)]
128 async fn test_msg_post_with_env_false() {
129 std::env::set_var("SLACKCLI_ALLOW_WRITE", "false");
130 let client = ApiClient::with_token("test_token".to_string());
131 let result = msg_post(
132 &client,
133 "C123456".to_string(),
134 "test message".to_string(),
135 None,
136 false,
137 true,
138 false,
139 )
140 .await;
141 assert!(result.is_err());
142 assert!(matches!(result.unwrap_err(), ApiError::WriteNotAllowed));
143 std::env::remove_var("SLACKCLI_ALLOW_WRITE");
144 }
145
146 #[tokio::test]
147 #[serial(write_guard)]
148 async fn test_msg_update_with_env_false() {
149 std::env::set_var("SLACKCLI_ALLOW_WRITE", "false");
150 let client = ApiClient::with_token("test_token".to_string());
151 let result = msg_update(
152 &client,
153 "C123456".to_string(),
154 "1234567890.123456".to_string(),
155 "updated text".to_string(),
156 true,
157 false,
158 )
159 .await;
160 assert!(result.is_err());
161 assert!(matches!(result.unwrap_err(), ApiError::WriteNotAllowed));
162 std::env::remove_var("SLACKCLI_ALLOW_WRITE");
163 }
164
165 #[tokio::test]
166 #[serial(write_guard)]
167 async fn test_msg_delete_with_env_false() {
168 std::env::set_var("SLACKCLI_ALLOW_WRITE", "false");
169 let client = ApiClient::with_token("test_token".to_string());
170 let result = msg_delete(
171 &client,
172 "C123456".to_string(),
173 "1234567890.123456".to_string(),
174 true,
175 false,
176 )
177 .await;
178 assert!(result.is_err());
179 assert!(matches!(result.unwrap_err(), ApiError::WriteNotAllowed));
180 std::env::remove_var("SLACKCLI_ALLOW_WRITE");
181 }
182}