facebook_access_token_api/endpoints/
access_token.rs1use http_api_client_endpoint::{
4 http::{
5 header::{ACCEPT, USER_AGENT},
6 Method, StatusCode,
7 },
8 Body, Endpoint, Request, Response, MIME_APPLICATION_JSON,
9};
10use serde::{Deserialize, Serialize};
11use url::Url;
12
13use crate::{
14 endpoints::{
15 common::{EndpointError, EndpointRet},
16 URL_BASE, VERSION,
17 },
18 objects::ResponseBodyErrJson,
19};
20
21#[derive(Debug, Clone)]
23pub struct AccessTokenEndpoint {
24 pub grant_type: Box<str>,
25 pub app_id: u64,
26 pub app_secret: Option<Box<str>>,
27 pub fb_exchange_token: Option<Box<str>>,
28 pub version: Option<Box<str>>,
30}
31
32impl AccessTokenEndpoint {
33 pub fn new(
34 grant_type: impl AsRef<str>,
35 app_id: u64,
36 app_secret: impl Into<Option<Box<str>>>,
37 fb_exchange_token: impl Into<Option<Box<str>>>,
38 version: impl Into<Option<Box<str>>>,
39 ) -> Self {
40 Self {
41 grant_type: grant_type.as_ref().into(),
42 app_id,
43 app_secret: app_secret.into(),
44 fb_exchange_token: fb_exchange_token.into(),
45 version: version.into(),
46 }
47 }
48}
49
50impl Endpoint for AccessTokenEndpoint {
51 type RenderRequestError = EndpointError;
52
53 type ParseResponseOutput = EndpointRet<AccessTokenResponseBodyOkJson>;
54 type ParseResponseError = EndpointError;
55
56 fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
57 let url = format!(
58 "{}/{}/oauth/access_token",
59 URL_BASE,
60 self.version.as_deref().unwrap_or(VERSION),
61 );
62 let mut url = Url::parse(&url).map_err(EndpointError::MakeRequestUrlFailed)?;
63
64 url.query_pairs_mut()
65 .append_pair("grant_type", &self.grant_type);
66
67 url.query_pairs_mut()
68 .append_pair("client_id", &self.app_id.to_string());
69
70 if let Some(client_secret) = &self.app_secret {
71 url.query_pairs_mut()
72 .append_pair("client_secret", client_secret);
73 }
74
75 if let Some(fb_exchange_token) = &self.fb_exchange_token {
76 url.query_pairs_mut()
77 .append_pair("fb_exchange_token", fb_exchange_token);
78 }
79
80 let request = Request::builder()
81 .method(Method::GET)
82 .uri(url.as_str())
83 .header(USER_AGENT, "facebook-access-token-api")
84 .header(ACCEPT, MIME_APPLICATION_JSON)
85 .body(vec![])
86 .map_err(EndpointError::MakeRequestFailed)?;
87
88 Ok(request)
89 }
90
91 fn parse_response(
92 &self,
93 response: Response<Body>,
94 ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
95 let status = response.status();
96 match status {
97 StatusCode::OK => Ok(EndpointRet::Ok(
98 serde_json::from_slice(response.body())
99 .map_err(EndpointError::DeResponseBodyOkJsonFailed)?,
100 )),
101 status => match serde_json::from_slice::<ResponseBodyErrJson>(response.body()) {
102 Ok(err_json) => Ok(EndpointRet::Other((status, Ok(err_json)))),
103 Err(_) => Ok(EndpointRet::Other((
104 status,
105 Err(response.body().to_owned()),
106 ))),
107 },
108 }
109 }
110}
111
112#[derive(Deserialize, Serialize, Debug, Clone)]
116pub struct AccessTokenResponseBodyOkJson {
117 pub access_token: String,
118 pub token_type: String,
119 pub expires_in: Option<usize>,
120}