1use super::client::DiscourseClient;
2use super::error::http_error;
3use anyhow::{Context, Result};
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6
7#[derive(Debug, Deserialize, Serialize, Clone)]
9pub struct InviteResult {
10 pub id: u64,
11 #[serde(default)]
13 pub link: Option<String>,
14 #[serde(default)]
15 pub email: Option<String>,
16}
17
18impl DiscourseClient {
19 pub fn create_invite(
26 &self,
27 email: &str,
28 group_ids: &[u64],
29 topic_id: Option<u64>,
30 custom_message: Option<&str>,
31 ) -> Result<InviteResult> {
32 let mut payload: Vec<(&str, String)> = vec![("email", email.to_string())];
33 if !group_ids.is_empty() {
34 payload.push((
35 "group_ids",
36 group_ids
37 .iter()
38 .map(|id| id.to_string())
39 .collect::<Vec<_>>()
40 .join(","),
41 ));
42 }
43 if let Some(topic) = topic_id {
44 payload.push(("topic_id", topic.to_string()));
45 }
46 if let Some(msg) = custom_message {
47 if !msg.trim().is_empty() {
48 payload.push(("custom_message", msg.to_string()));
49 }
50 }
51 let response = self.send_retrying(|| Ok(self.post("/invites.json")?.form(&payload)))?;
52 let status = response.status();
53 let text = response.text().context("reading invite response")?;
54 if !status.is_success() {
55 return Err(http_error("invite create request", status, &text));
56 }
57 let value: Value =
60 serde_json::from_str(&text).context("parsing invite response json")?;
61 let target = value.get("invite").unwrap_or(&value);
62 let result: InviteResult =
63 serde_json::from_value(target.clone()).context("deserialising invite")?;
64 Ok(result)
65 }
66}