canvas_lms_api/resources/
conversation.rs1use crate::error::Result;
2use crate::http::Requester;
3use crate::params::wrap_params;
4use serde::{Deserialize, Serialize};
5use std::sync::Arc;
6
7#[derive(Debug, Clone, Deserialize, Serialize)]
8pub struct ConversationParticipant {
9 pub id: u64,
10 pub name: Option<String>,
11 pub avatar_url: Option<String>,
12}
13
14#[derive(Debug, Clone, Deserialize, Serialize)]
15pub struct ConversationMessage {
16 pub id: u64,
17 pub created_at: Option<String>,
18 pub body: Option<String>,
19 pub author_id: Option<u64>,
20 pub generated: Option<bool>,
21}
22
23#[derive(Debug, Clone, Deserialize, Serialize, canvas_lms_api_derive::CanvasResource)]
24pub struct Conversation {
25 pub id: u64,
26 pub subject: Option<String>,
27 pub workflow_state: Option<String>,
28 pub last_message: Option<String>,
29 pub last_message_at: Option<String>,
30 pub message_count: Option<u64>,
31 pub subscribed: Option<bool>,
32 pub private: Option<bool>,
33 pub starred: Option<bool>,
34 pub audience: Option<Vec<u64>>,
35 pub participants: Option<Vec<ConversationParticipant>>,
36 pub messages: Option<Vec<ConversationMessage>>,
37 #[serde(skip)]
38 pub(crate) requester: Option<Arc<Requester>>,
39}
40
41#[derive(Debug, Clone, Default, Serialize)]
42pub struct ConversationParams {
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub subject: Option<String>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub force_new: Option<bool>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub group_conversation: Option<bool>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub context_code: Option<String>,
51}
52
53impl Conversation {
54 fn endpoint(&self) -> String {
55 format!("conversations/{}", self.id)
56 }
57
58 pub async fn add_message(&self, body: &str) -> Result<Conversation> {
62 let params = vec![("body".into(), body.to_string())];
63 let endpoint = format!("{}/add_message", self.endpoint());
64 let mut c: Conversation = self.req().post(&endpoint, ¶ms).await?;
65 c.requester = self.requester.clone();
66 Ok(c)
67 }
68
69 pub async fn add_recipients(&self, recipients: &[&str]) -> Result<Conversation> {
73 let params: Vec<(String, String)> = recipients
74 .iter()
75 .map(|r| ("recipients[]".into(), r.to_string()))
76 .collect();
77 let endpoint = format!("{}/add_recipients", self.endpoint());
78 let mut c: Conversation = self.req().post(&endpoint, ¶ms).await?;
79 c.requester = self.requester.clone();
80 Ok(c)
81 }
82
83 pub async fn delete(&self) -> Result<Conversation> {
87 let mut c: Conversation = self.req().delete(&self.endpoint(), &[]).await?;
88 c.requester = self.requester.clone();
89 Ok(c)
90 }
91
92 pub async fn delete_messages(&self, message_ids: &[u64]) -> Result<serde_json::Value> {
96 let params: Vec<(String, String)> = message_ids
97 .iter()
98 .map(|id| ("remove[]".into(), id.to_string()))
99 .collect();
100 let endpoint = format!("{}/remove_messages", self.endpoint());
101 self.req().post(&endpoint, ¶ms).await
102 }
103
104 pub async fn edit(&self, params: &[(String, String)]) -> Result<Conversation> {
108 let mut c: Conversation = self.req().put(&self.endpoint(), params).await?;
109 c.requester = self.requester.clone();
110 Ok(c)
111 }
112
113 pub async fn set_workflow_state(&self, state: &str) -> Result<Conversation> {
117 let params = wrap_params(
118 "conversation",
119 &serde_json::json!({ "workflow_state": state }),
120 );
121 self.edit(¶ms).await
122 }
123}