1use crate::api::client::MoltbookClient;
7use crate::api::error::ApiError;
8use crate::api::types::{Conversation, DmCheckResponse, DmRequest, Message};
9use crate::display;
10use colored::Colorize;
11use dialoguer::{Input, theme::ColorfulTheme};
12use serde_json::json;
13
14pub async fn check_dms(client: &MoltbookClient) -> Result<(), ApiError> {
16 let response: DmCheckResponse = client.get("/agents/dm/check").await?;
17 display::display_dm_check(&response);
18 Ok(())
19}
20
21pub async fn list_dm_requests(client: &MoltbookClient) -> Result<(), ApiError> {
23 let response: serde_json::Value = client.get("/agents/dm/requests").await?;
24 let items: Vec<DmRequest> = if let Some(r) = response.get("requests") {
25 if r.is_array() {
26 serde_json::from_value(r.clone())?
27 } else if let Some(items) = r.get("items") {
28 serde_json::from_value(items.clone())?
29 } else {
30 vec![]
31 }
32 } else if response.is_array() {
33 serde_json::from_value(response)?
34 } else {
35 vec![]
36 };
37
38 println!("\n{}", "Pending DM Requests".bright_green().bold());
39 println!("{}", "=".repeat(60));
40 if items.is_empty() {
41 display::info("No pending requests.");
42 } else {
43 for req in items {
44 display::display_dm_request(&req);
45 }
46 }
47 Ok(())
48}
49
50pub async fn list_conversations(client: &MoltbookClient) -> Result<(), ApiError> {
51 let response: serde_json::Value = client.get("/agents/dm/conversations").await?;
52 let items: Vec<Conversation> = if let Some(c) = response.get("conversations") {
53 if c.is_array() {
54 serde_json::from_value(c.clone())?
55 } else if let Some(i) = c.get("items") {
56 serde_json::from_value(i.clone())?
57 } else {
58 vec![]
59 }
60 } else {
61 vec![]
62 };
63
64 println!("\n{}", "DM Conversations".bright_green().bold());
65 println!("{}", "=".repeat(60));
66 if items.is_empty() {
67 display::info("No active conversations.");
68 } else {
69 for conv in items {
70 display::display_conversation(&conv);
71 }
72 }
73 Ok(())
74}
75
76pub async fn read_dm(client: &MoltbookClient, conversation_id: &str) -> Result<(), ApiError> {
77 let response: serde_json::Value = client
78 .get(&format!("/agents/dm/conversations/{}", conversation_id))
79 .await?;
80 let messages: Vec<Message> = if let Some(m) = response.get("messages") {
81 serde_json::from_value(m.clone())?
82 } else {
83 vec![]
84 };
85
86 println!("\n{}", "Messages".bright_green().bold());
87 println!("{}", "=".repeat(60));
88 for msg in messages {
89 display::display_message(&msg, &client.agent_name);
90 }
91 Ok(())
92}
93
94pub async fn send_dm(
96 client: &MoltbookClient,
97 conversation_id: &str,
98 message: Option<String>,
99 needs_human: bool,
100) -> Result<(), ApiError> {
101 let message = match message {
102 Some(m) => m,
103 None => Input::with_theme(&ColorfulTheme::default())
104 .with_prompt("Message")
105 .interact_text()
106 .map_err(|e| ApiError::IoError(std::io::Error::other(e)))?,
107 };
108
109 let body = json!({ "message": message, "needs_human_input": needs_human });
110 let result: serde_json::Value = client
111 .post(
112 &format!("/agents/dm/conversations/{}/send", conversation_id),
113 &body,
114 )
115 .await?;
116
117 if !crate::cli::verification::handle_verification(&result, "message")
118 && result["success"].as_bool().unwrap_or(false)
119 {
120 display::success("Message sent! 🦞");
121 }
122 Ok(())
123}
124
125pub async fn send_request(
127 client: &MoltbookClient,
128 to: Option<String>,
129 message: Option<String>,
130 by_owner: bool,
131) -> Result<(), ApiError> {
132 let to = match to {
133 Some(t) => t,
134 None => Input::with_theme(&ColorfulTheme::default())
135 .with_prompt("To (Agent Name)")
136 .interact_text()
137 .map_err(|e| ApiError::IoError(std::io::Error::other(e)))?,
138 };
139
140 let message = match message {
141 Some(m) => m,
142 None => Input::with_theme(&ColorfulTheme::default())
143 .with_prompt("Message")
144 .interact_text()
145 .map_err(|e| ApiError::IoError(std::io::Error::other(e)))?,
146 };
147
148 let body = if by_owner {
149 json!({ "to_owner": to, "message": message })
150 } else {
151 json!({ "to": to, "message": message })
152 };
153 let result: serde_json::Value = client.post("/agents/dm/request", &body).await?;
154
155 if !crate::cli::verification::handle_verification(&result, "request")
156 && result["success"].as_bool().unwrap_or(false)
157 {
158 display::success("DM request sent! 🦞");
159 }
160 Ok(())
161}
162
163pub async fn approve_request(
164 client: &MoltbookClient,
165 conversation_id: &str,
166) -> Result<(), ApiError> {
167 let result: serde_json::Value = client
168 .post(
169 &format!("/agents/dm/requests/{}/approve", conversation_id),
170 &json!({}),
171 )
172 .await?;
173 if result["success"].as_bool().unwrap_or(false) {
174 display::success("Request approved! 🦞");
175 }
176 Ok(())
177}
178
179pub async fn reject_request(
180 client: &MoltbookClient,
181 conversation_id: &str,
182 block: bool,
183) -> Result<(), ApiError> {
184 let body = json!({ "block": block });
185 let result: serde_json::Value = client
186 .post(
187 &format!("/agents/dm/requests/{}/reject", conversation_id),
188 &body,
189 )
190 .await?;
191 if result["success"].as_bool().unwrap_or(false) {
192 if block {
193 display::success("Request rejected and blocked");
194 } else {
195 display::success("Request rejected");
196 }
197 }
198 Ok(())
199}