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