twapi_v2/api/
post_2_dm_conversations_dm_conversation_id_message.rs1use 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}