twapi_v2/api/
post_2_dm_conversations_with_participant_id_message.rs1use crate::{
2 api::{Authentication, TwapiOptions, apply_options, 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/with/:participant_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 participant_id: String,
27 body: Body,
28 twapi_options: Option<TwapiOptions>,
29}
30
31impl Api {
32 pub fn new(participant_id: &str, body: Body) -> Self {
33 Self {
34 participant_id: participant_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(":participant_id", &self.participant_id),
50 );
51 let builder = client.post(&url).json(&self.body);
52 authentication.execute(
53 apply_options(builder, &self.twapi_options),
54 "POST",
55 &url,
56 &[],
57 )
58 }
59
60 pub async fn execute(
61 self,
62 authentication: &impl Authentication,
63 ) -> Result<(Response, Headers), Error> {
64 execute_twitter(self.build(authentication)).await
65 }
66}
67
68#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
69pub struct Response {
70 #[serde(skip_serializing_if = "Option::is_none")]
71 pub data: Option<Data>,
72 #[serde(flatten)]
73 pub extra: std::collections::HashMap<String, serde_json::Value>,
74}
75
76impl Response {
77 pub fn is_empty_extra(&self) -> bool {
78 let res = self.extra.is_empty()
79 && self
80 .data
81 .as_ref()
82 .map(|it| it.is_empty_extra())
83 .unwrap_or(true);
84 if !res {
85 println!("Response {:?}", self.extra);
86 }
87 res
88 }
89}
90
91#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)]
92pub struct Data {
93 #[serde(skip_serializing_if = "Option::is_none")]
94 pub dm_conversation_id: Option<String>,
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub dm_event_id: Option<String>,
97 #[serde(flatten)]
98 pub extra: std::collections::HashMap<String, serde_json::Value>,
99}
100
101impl Data {
102 pub fn is_empty_extra(&self) -> bool {
103 let res = self.extra.is_empty();
104 if !res {
105 println!("Data {:?}", self.extra);
106 }
107 res
108 }
109}