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 if result["success"].as_bool().unwrap_or(false) {
121 display::success("Message sent! 🦞");
122 }
123 Ok(())
124}
125
126pub async fn send_request(
128 client: &MoltbookClient,
129 to: Option<String>,
130 message: Option<String>,
131 by_owner: bool,
132) -> Result<(), ApiError> {
133
134 let to = match to {
135 Some(t) => t,
136 None => Input::with_theme(&ColorfulTheme::default())
137 .with_prompt("To (Agent Name)")
138 .interact_text()
139 .map_err(|e| ApiError::IoError(std::io::Error::other(e)))?,
140 };
141
142 let message = match message {
143 Some(m) => m,
144 None => Input::with_theme(&ColorfulTheme::default())
145 .with_prompt("Message")
146 .interact_text()
147 .map_err(|e| ApiError::IoError(std::io::Error::other(e)))?,
148 };
149
150 let body = if by_owner {
151 json!({ "to_owner": to, "message": message })
152 } else {
153 json!({ "to": to, "message": message })
154 };
155 let result: serde_json::Value = client.post("/agents/dm/request", &body).await?;
156 if result["success"].as_bool().unwrap_or(false) {
157 display::success("DM request sent! 🦞");
158 }
159 Ok(())
160}
161
162pub async fn approve_request(
163 client: &MoltbookClient,
164 conversation_id: &str,
165) -> Result<(), ApiError> {
166 let result: serde_json::Value = client
167 .post(
168 &format!("/agents/dm/requests/{}/approve", conversation_id),
169 &json!({}),
170 )
171 .await?;
172 if result["success"].as_bool().unwrap_or(false) {
173 display::success("Request approved! 🦞");
174 }
175 Ok(())
176}
177
178pub async fn reject_request(
179 client: &MoltbookClient,
180 conversation_id: &str,
181 block: bool,
182) -> Result<(), ApiError> {
183 let body = json!({ "block": block });
184 let result: serde_json::Value = client
185 .post(
186 &format!("/agents/dm/requests/{}/reject", conversation_id),
187 &body,
188 )
189 .await?;
190 if result["success"].as_bool().unwrap_or(false) {
191 if block {
192 display::success("Request rejected and blocked");
193 } else {
194 display::success("Request rejected");
195 }
196 }
197 Ok(())
198}