Skip to main content

quantum_sdk/
contact.rs

1use reqwest::header::CONTENT_TYPE;
2use serde::{Deserialize, Serialize};
3
4use crate::client::Client;
5use crate::error::Result;
6use crate::keys::StatusResponse;
7
8/// Request body for the public contact form.
9#[derive(Debug, Clone, Serialize, Default)]
10pub struct ContactRequest {
11    /// Sender name.
12    pub name: String,
13
14    /// Sender email address.
15    pub email: String,
16
17    /// Message subject.
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub subject: Option<String>,
20
21    /// Message body.
22    pub message: String,
23}
24
25/// Response from the contact form endpoint.
26#[derive(Debug, Clone, Deserialize)]
27pub struct ContactResponse {
28    /// Status message (e.g. "ok", "sent").
29    pub status: String,
30
31    /// Optional detail message.
32    #[serde(default)]
33    pub message: Option<String>,
34}
35
36impl Client {
37    /// Sends a contact form message.
38    ///
39    /// This endpoint does not require authentication. A separate HTTP client
40    /// is used to avoid sending API key headers.
41    pub async fn contact(&self, req: &ContactRequest) -> Result<StatusResponse> {
42        let url = format!("{}/qai/v1/contact", self.base_url());
43
44        let http = reqwest::Client::new();
45        let resp = http
46            .post(&url)
47            .header(CONTENT_TYPE, "application/json")
48            .json(req)
49            .send()
50            .await?;
51
52        if !resp.status().is_success() {
53            let status_code = resp.status().as_u16();
54            let body = resp.text().await.unwrap_or_default();
55            return Err(crate::error::Error::Api(crate::error::ApiError {
56                status_code,
57                code: "contact_error".to_string(),
58                message: body,
59                request_id: String::new(),
60            }));
61        }
62
63        let result: StatusResponse = resp.json().await?;
64        Ok(result)
65    }
66}