Skip to main content

line_bot_sdk_rust/client/
mod.rs

1/*
2* Copyright 2023 nanato12
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8*     http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17//! LINE API client module.
18//!
19//! Provides the [`LINE`] struct, which bundles all LINE API clients into a single entry point.
20
21use std::sync::Arc;
22use std::time::Duration;
23
24use hyper_rustls::HttpsConnector;
25use hyper_rustls::HttpsConnectorBuilder;
26use hyper_util::client::legacy::connect::HttpConnector;
27use hyper_util::client::legacy::Client;
28use hyper_util::rt::TokioExecutor;
29use line_channel_access_token::apis::{
30    configuration::Configuration as ChannelAccessTokenApiConfiguration, ChannelAccessTokenApiClient,
31};
32use line_insight::apis::{configuration::Configuration as InsightConfiguration, InsightApiClient};
33use line_liff::apis::{configuration::Configuration as LiffConfiguration, LiffApiClient};
34use line_manage_audience::apis::{
35    configuration::Configuration as ManageAudienceConfiguration, ManageAudienceApiClient,
36    ManageAudienceBlobApiClient,
37};
38use line_messaging_api::apis::{
39    configuration::Configuration as MessagingApiConfiguration, MessagingApiApiClient,
40    MessagingApiBlobApiClient,
41};
42use line_module::apis::{
43    configuration::Configuration as LineModuleConfiguration, LineModuleApiClient,
44};
45use line_module_attach::apis::{
46    configuration::Configuration as LineModuleAttachConfiguration, LineModuleAttachApiClient,
47};
48use line_shop::apis::{configuration::Configuration as ShopConfiguration, ShopApiClient};
49use line_webhook::apis::{
50    configuration::Configuration as WebhookConfiguration, DummyApiClient as WebhookDummyApiClient,
51};
52
53type HttpsClient = HttpsConnector<HttpConnector>;
54
55/// A unified client for all LINE Platform APIs.
56///
57/// `LINE` bundles all API-specific clients, each configured with the same channel access token
58/// and sharing a single HTTPS connection pool via `hyper`.
59///
60/// # Example
61///
62/// ```no_run
63/// use line_bot_sdk_rust::client::LINE;
64/// use line_bot_sdk_rust::line_messaging_api::apis::MessagingApiApi;
65/// use line_bot_sdk_rust::line_messaging_api::models::{
66///     Message, ReplyMessageRequest, TextMessage,
67/// };
68///
69/// # async fn example() {
70/// let line = LINE::new("YOUR_CHANNEL_ACCESS_TOKEN".to_string());
71///
72/// let req = ReplyMessageRequest {
73///     reply_token: "reply_token".to_string(),
74///     messages: vec![Message::Text(TextMessage::new("Hello!".to_string()))],
75///     notification_disabled: Some(false),
76/// };
77/// let _ = line.messaging_api_client.reply_message(req).await;
78/// # }
79/// ```
80#[derive(Clone)]
81pub struct LINE {
82    pub channel_access_token_api_client: ChannelAccessTokenApiClient<HttpsClient>,
83    pub insight_api_client: InsightApiClient<HttpsClient>,
84    pub liff_api_client: LiffApiClient<HttpsClient>,
85    pub manage_audience_api_client: ManageAudienceApiClient<HttpsClient>,
86    pub manage_audience_blob_api_client: ManageAudienceBlobApiClient<HttpsClient>,
87    pub messaging_api_client: MessagingApiApiClient<HttpsClient>,
88    pub messaging_api_blob_client: MessagingApiBlobApiClient<HttpsClient>,
89    pub module_api_client: LineModuleApiClient<HttpsClient>,
90    pub module_attach_api_client: LineModuleAttachApiClient<HttpsClient>,
91    pub shop_api_client: ShopApiClient<HttpsClient>,
92    pub webhook_dummy_api_client: WebhookDummyApiClient<HttpsClient>,
93}
94
95impl LINE {
96    /// Creates a new `LINE` client with the given channel access token.
97    ///
98    /// All API-specific clients are initialized with the same token and share a single
99    /// HTTPS connection via `hyper` + `hyper-rustls`.
100    pub fn new(token: String) -> LINE {
101        LINEBuilder {
102            token,
103            timeout: None,
104        }
105        .build()
106    }
107
108    /// Returns a [`LINEBuilder`] for constructing a `LINE` client with custom settings.
109    ///
110    /// # Example
111    ///
112    /// ```no_run
113    /// use std::time::Duration;
114    /// use line_bot_sdk_rust::client::LINE;
115    ///
116    /// let line = LINE::builder("YOUR_CHANNEL_ACCESS_TOKEN".to_string())
117    ///     .timeout(Duration::from_secs(30))
118    ///     .build();
119    /// ```
120    pub fn builder(token: String) -> LINEBuilder {
121        LINEBuilder {
122            token,
123            timeout: None,
124        }
125    }
126
127    fn create_hyper_client() -> Client<HttpsClient, String> {
128        let https = HttpsConnectorBuilder::new()
129            .with_native_roots()
130            .expect("no native root certs found")
131            .https_only()
132            .enable_http1()
133            .build();
134        Client::builder(TokioExecutor::new()).build(https)
135    }
136}
137
138/// Builder for configuring a [`LINE`] client.
139///
140/// Obtained via [`LINE::builder`].
141pub struct LINEBuilder {
142    token: String,
143    timeout: Option<Duration>,
144}
145
146impl LINEBuilder {
147    /// Sets the request timeout for all API calls.
148    ///
149    /// When set, each HTTP request will fail with a timeout error if it does not
150    /// complete within the specified duration. By default there is no timeout.
151    pub fn timeout(mut self, duration: Duration) -> Self {
152        self.timeout = Some(duration);
153        self
154    }
155
156    /// Builds the [`LINE`] client with the configured settings.
157    pub fn build(self) -> LINE {
158        let client = LINE::create_hyper_client();
159        let timeout = self.timeout;
160        let token = self.token;
161
162        // channel_access_token_api
163        let mut channel_access_token_api_conf =
164            ChannelAccessTokenApiConfiguration::with_client(client.clone());
165        channel_access_token_api_conf.oauth_access_token = Some(token.to_owned());
166        channel_access_token_api_conf.timeout = timeout;
167        let channel_access_token_api_client =
168            ChannelAccessTokenApiClient::new(Arc::new(channel_access_token_api_conf));
169
170        // insight
171        let mut insight_conf = InsightConfiguration::with_client(client.clone());
172        insight_conf.oauth_access_token = Some(token.to_owned());
173        insight_conf.timeout = timeout;
174        let insight_api_client = InsightApiClient::new(Arc::new(insight_conf));
175
176        // liff
177        let mut liff_conf = LiffConfiguration::with_client(client.clone());
178        liff_conf.oauth_access_token = Some(token.to_owned());
179        liff_conf.timeout = timeout;
180        let liff_api_client = LiffApiClient::new(Arc::new(liff_conf));
181
182        // manage_audience
183        let mut manage_audience_conf = ManageAudienceConfiguration::with_client(client.clone());
184        manage_audience_conf.oauth_access_token = Some(token.to_owned());
185        manage_audience_conf.timeout = timeout;
186        let manage_audience_api_client =
187            ManageAudienceApiClient::new(Arc::new(manage_audience_conf));
188
189        // manage_audience_blob
190        let mut manage_audience_blob_conf =
191            ManageAudienceConfiguration::with_client(client.clone());
192        manage_audience_blob_conf.oauth_access_token = Some(token.to_owned());
193        manage_audience_blob_conf.timeout = timeout;
194        let manage_audience_blob_api_client =
195            ManageAudienceBlobApiClient::new(Arc::new(manage_audience_blob_conf));
196
197        // messaging_api
198        let mut messaging_api_conf = MessagingApiConfiguration::with_client(client.clone());
199        messaging_api_conf.oauth_access_token = Some(token.to_owned());
200        messaging_api_conf.timeout = timeout;
201        let messaging_api_client = MessagingApiApiClient::new(Arc::new(messaging_api_conf));
202
203        // messaging_api_blob
204        let mut messaging_api_blob_conf = MessagingApiConfiguration::with_client(client.clone());
205        messaging_api_blob_conf.oauth_access_token = Some(token.to_owned());
206        messaging_api_blob_conf.timeout = timeout;
207        let messaging_api_blob_client =
208            MessagingApiBlobApiClient::new(Arc::new(messaging_api_blob_conf));
209
210        // module
211        let mut module_conf = LineModuleConfiguration::with_client(client.clone());
212        module_conf.oauth_access_token = Some(token.to_owned());
213        module_conf.timeout = timeout;
214        let module_api_client = LineModuleApiClient::new(Arc::new(module_conf));
215
216        // module_attach
217        let mut module_attach_conf = LineModuleAttachConfiguration::with_client(client.clone());
218        module_attach_conf.oauth_access_token = Some(token.to_owned());
219        module_attach_conf.timeout = timeout;
220        let module_attach_api_client = LineModuleAttachApiClient::new(Arc::new(module_attach_conf));
221
222        // shop
223        let mut shop_conf = ShopConfiguration::with_client(client.clone());
224        shop_conf.oauth_access_token = Some(token.to_owned());
225        shop_conf.timeout = timeout;
226        let shop_api_client = ShopApiClient::new(Arc::new(shop_conf));
227
228        // webhook
229        let mut webhook_conf = WebhookConfiguration::with_client(client.clone());
230        webhook_conf.oauth_access_token = Some(token.to_owned());
231        webhook_conf.timeout = timeout;
232        let webhook_dummy_api_client = WebhookDummyApiClient::new(Arc::new(webhook_conf));
233
234        LINE {
235            channel_access_token_api_client,
236            insight_api_client,
237            liff_api_client,
238            manage_audience_api_client,
239            manage_audience_blob_api_client,
240            messaging_api_client,
241            messaging_api_blob_client,
242            module_api_client,
243            module_attach_api_client,
244            shop_api_client,
245            webhook_dummy_api_client,
246        }
247    }
248}