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