facebook_api_rs/graph/batch/
request.rs1use crate::prelude::errors::{ClientErr, FacebookAPiError};
2use crate::prelude::HttpConnection;
3use serde::de::DeserializeOwned;
4use serde::Deserialize;
5use serde_json::{json, Value};
6use std::fmt::Debug;
7
8pub struct BatchApi {
9 pub base_url: String,
10 pub page_access_token: String,
11 pub page_id: String,
12}
13
14impl BatchApi {
15 pub fn new(base_url: String, page_access_token: String, page_id: String) -> Self {
16 BatchApi {
17 base_url,
18 page_access_token,
19 page_id,
20 }
21 }
22
23 pub async fn request(
24 self,
25 batch_items: BatchItems,
26 ) -> Result<Vec<BatchResponseBody>, ClientErr> {
27 let batch = serde_json::to_string(&batch_items.data).unwrap();
28
29 let url = self.base_url
30 + "?batch="
31 + &batch
32 + "&access_token="
33 + &self.page_access_token
34 + "&include_headers=false";
35
36 let resp =
37 HttpConnection::batch_post::<Vec<BatchResponseBody>, String>(url, "".to_string())
38 .await?;
39 Ok(resp)
40 }
41
42 pub async fn request_with_type<T>(
43 self,
44 batch_items: BatchItems,
45 ) -> Result<Vec<BatchResponseBodyWithType<T>>, ClientErr>
46 where
47 T: DeserializeOwned,
48 {
49 let batch = serde_json::to_string(&batch_items.data).unwrap();
50
51 let url = self.base_url
52 + "?batch="
53 + &batch
54 + "&access_token="
55 + &self.page_access_token
56 + "&include_headers=false";
57
58 let resp: Vec<BatchResponseBody> =
59 HttpConnection::batch_post::<Vec<BatchResponseBody>, String>(url, "".to_string())
60 .await?;
61
62 let mut resp_body: Vec<BatchResponseBodyWithType<T>> = Vec::new();
63
64 for body in resp {
65 if let Some(data) = body.body {
66 if body.code == 200 {
67 let data: T = serde_json::from_str(&data.as_str())?;
68
69 resp_body.push(BatchResponseBodyWithType {
70 code: body.code,
71 body: Some(data),
72 error: None,
73 })
74 } else {
75 let data: FacebookAPiError = serde_json::from_str(&data.as_str())?;
76
77 resp_body.push(BatchResponseBodyWithType {
78 code: body.code,
79 body: None,
80 error: Some(data),
81 })
82 }
83 } else {
84 resp_body.push(BatchResponseBodyWithType {
85 code: body.code,
86 body: None,
87 error: None,
88 })
89 }
90 }
91 Ok(resp_body)
92 }
93}
94
95#[derive(Deserialize, Debug, Clone, Default)]
96pub struct BatchItems {
97 pub data: Vec<Value>,
98}
99
100impl BatchItems {
101 pub fn add_batch_item_with_body(
102 mut self,
103 method: &str,
104 body: String,
105 relative_url: &str,
106 ) -> Self {
107 let data = json!(
108 {
109 "method": method.to_uppercase(),
110 "relative_url":relative_url,
111 "body": body
112 }
113 );
114
115 self.data.push(data);
116 self
117 }
118
119 pub fn add_batch_item_with_body_access_token(
120 mut self,
121 method: &str,
122 body: String,
123 relative_url: &str,
124 access_token: String,
125 ) -> Self {
126 let data = json!(
127 {
128 "method": method.to_uppercase(),
129 "relative_url":relative_url.to_owned() + "?access_token=" + &access_token,
130 "body": body
131 }
132 );
133 self.data.push(data);
134 self
135 }
136
137 pub fn add_batch_item_without_body(mut self, method: &str, relative_url: &str) -> Self {
138 let data = json!(
139 {
140 "method": method.to_uppercase(),
141 "relative_url":relative_url,
142 }
143 );
144 self.data.push(data);
145 self
146 }
147
148 pub fn add_batch_item_with_access_token(
149 mut self,
150 method: &str,
151 relative_url: &str,
152 access_token: String,
153 ) -> Self {
154 let data = json!(
155 {
156 "method": method.to_uppercase(),
157 "relative_url":relative_url.to_owned() + "?access_token=" + &access_token,
158 }
159 );
160 self.data.push(data);
161 self
162 }
163}
164
165#[derive(Deserialize, Debug, Clone)]
166pub struct BatchResponseBody {
167 pub code: u64,
168 pub body: Option<String>,
169}
170
171#[derive(Deserialize, Debug, Clone)]
172pub struct BatchResponseBodyWithType<T> {
173 pub code: u64,
174 pub body: Option<T>,
175 pub error: Option<FacebookAPiError>,
176}