Skip to main content

twapi_v2/api/
post_2_dm_conversations_dm_conversation_id_message.rs

1use crate::{
2    api::{Authentication, TwapiOptions, execute_twitter, make_url},
3    error::Error,
4    headers::Headers,
5};
6use reqwest::RequestBuilder;
7use serde::{Deserialize, Serialize};
8
9const URL: &str = "/2/dm_conversations/:dm_conversation_id/messages";
10
11#[derive(Serialize, Deserialize, Debug, Default, Clone)]
12pub struct Attachment {
13    pub media_id: String,
14}
15
16#[derive(Serialize, Deserialize, Debug, Default, Clone)]
17pub struct Body {
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub attachments: Option<Vec<Attachment>>,
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub text: Option<String>,
22}
23
24#[derive(Debug, Clone, Default)]
25pub struct Api {
26    dm_conversation_id: String,
27    body: Body,
28    twapi_options: Option<TwapiOptions>,
29}
30
31impl Api {
32    pub fn new(dm_conversation_id: &str, body: Body) -> Self {
33        Self {
34            dm_conversation_id: dm_conversation_id.to_owned(),
35            body,
36            ..Default::default()
37        }
38    }
39
40    pub fn twapi_options(mut self, value: TwapiOptions) -> Self {
41        self.twapi_options = Some(value);
42        self
43    }
44
45    pub fn build(&self, authentication: &impl Authentication) -> RequestBuilder {
46        let client = reqwest::Client::new();
47        let url = make_url(
48            &self.twapi_options,
49            &URL.replace(":dm_conversation_id", &self.dm_conversation_id),
50        );
51        let builder = client.post(&url).json(&self.body);
52        authentication.execute(builder, "POST", &url, &[])
53    }
54
55    pub async fn execute(
56        &self,
57        authentication: &impl Authentication,
58    ) -> Result<(Response, Headers), Error> {
59        execute_twitter(|| self.build(authentication), &self.twapi_options).await
60    }
61}
62
63#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
64pub struct Response {
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub data: Option<Data>,
67    #[serde(flatten)]
68    pub extra: std::collections::HashMap<String, serde_json::Value>,
69}
70
71impl Response {
72    pub fn is_empty_extra(&self) -> bool {
73        let res = self.extra.is_empty()
74            && self
75                .data
76                .as_ref()
77                .map(|it| it.is_empty_extra())
78                .unwrap_or(true);
79        if !res {
80            println!("Response {:?}", self.extra);
81        }
82        res
83    }
84}
85
86#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
87pub struct Data {
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub dm_conversation_id: Option<String>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub dm_event_id: Option<String>,
92    #[serde(flatten)]
93    pub extra: std::collections::HashMap<String, serde_json::Value>,
94}
95
96impl Data {
97    pub fn is_empty_extra(&self) -> bool {
98        let res = self.extra.is_empty();
99        if !res {
100            println!("Data {:?}", self.extra);
101        }
102        res
103    }
104}