cx_sdk/client/
webhooks.rs

1// Copyright 2024 Coralogix Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::str::FromStr;
16
17use crate::{
18    auth::AuthContext,
19    error::{
20        Result,
21        SdkApiError,
22        SdkError,
23    },
24    metadata::CallProperties,
25    util::make_request_with_metadata,
26};
27
28use cx_api::proto::com::coralogix::outgoing_webhooks::v1::{
29    CreateOutgoingWebhookRequest,
30    CreateOutgoingWebhookResponse,
31    DeleteOutgoingWebhookRequest,
32    DeleteOutgoingWebhookResponse,
33    GetOutgoingWebhookRequest,
34    GetOutgoingWebhookResponse,
35    GetOutgoingWebhookTypeDetailsRequest,
36    GetOutgoingWebhookTypeDetailsResponse,
37    ListAllOutgoingWebhooksRequest,
38    ListAllOutgoingWebhooksResponse,
39    ListOutgoingWebhookTypesRequest,
40    ListOutgoingWebhookTypesResponse,
41    ListOutgoingWebhooksRequest,
42    ListOutgoingWebhooksResponse,
43    OutgoingWebhookInputData,
44    TestExistingOutgoingWebhookRequest,
45    TestOutgoingWebhookRequest,
46    TestOutgoingWebhookResponse,
47    UpdateOutgoingWebhookRequest,
48    UpdateOutgoingWebhookResponse,
49    outgoing_webhooks_service_client::OutgoingWebhooksServiceClient,
50};
51use tokio::sync::Mutex;
52use tonic::{
53    metadata::MetadataMap,
54    transport::{
55        Channel,
56        ClientTlsConfig,
57        Endpoint,
58    },
59};
60
61pub use cx_api::proto::com::coralogix::outgoing_webhooks::v1::{
62    AwsEventBridgeConfig,
63    DemistoConfig,
64    EmailGroupConfig,
65    GenericWebhookConfig,
66    IbmEventNotificationsConfig,
67    JiraConfig,
68    MicrosoftTeamsConfig,
69    OpsgenieConfig,
70    PagerDutyConfig,
71    SendLogConfig,
72    SlackConfig,
73    WebhookType,
74    generic_webhook_config,
75    outgoing_webhook_input_data::Config,
76    slack_config,
77    test_outgoing_webhook_response::Result as WebhookTestResult,
78};
79use url::Url;
80
81use crate::CoralogixRegion;
82
83const WEBHOOKS_FEATURE_GROUP_ID: &str = "integrations";
84
85/// The Webhooks API client.
86/// Read more at <https://coralogix.com/docs/webhooks-api/>
87pub struct WebhooksClient {
88    metadata_map: MetadataMap,
89    service_client: Mutex<OutgoingWebhooksServiceClient<Channel>>,
90}
91
92impl WebhooksClient {
93    /// Creates a new client for the Webhooks API.
94    ///
95    /// # Arguments
96    /// * `auth_context` - The [`AuthContext`] to use for authentication.
97    /// * `region` - The [`CoralogixRegion`] to connect to.
98    pub fn new(auth_context: AuthContext, region: CoralogixRegion) -> Result<Self> {
99        let channel: Channel = Endpoint::from_str(region.grpc_endpoint().as_str())?
100            .tls_config(ClientTlsConfig::new().with_native_roots())?
101            .connect_lazy();
102        let request_metadata: CallProperties = (&auth_context.team_level_api_key).into();
103        Ok(Self {
104            metadata_map: request_metadata.to_metadata_map(),
105            service_client: Mutex::new(OutgoingWebhooksServiceClient::new(channel)),
106        })
107    }
108
109    /// Creates a new Outgoing Webhook.
110    ///
111    /// # Arguments
112    /// * `webhook_type` - The [`WebhookType`].
113    /// * `name` - The name of the webhook.
114    /// * `url` - The [`Url`] of the webhook.
115    /// * `config` - The [`Config`] of the webhook.
116    pub async fn create(
117        &self,
118        webhook_type: WebhookType,
119        name: Option<String>,
120        url: Url,
121        config: Config,
122    ) -> Result<CreateOutgoingWebhookResponse> {
123        let request = make_request_with_metadata(
124            CreateOutgoingWebhookRequest {
125                data: Some(OutgoingWebhookInputData {
126                    r#type: webhook_type.into(),
127                    name,
128                    url: Some(url.into()),
129                    config: Some(config),
130                }),
131            },
132            &self.metadata_map,
133        );
134        self.service_client
135            .lock()
136            .await
137            .create_outgoing_webhook(request)
138            .await
139            .map(|r| r.into_inner())
140            .map_err(
141                |status| SdkError::ApiError(SdkApiError {
142                    status,
143                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/CreateOutgoingWebhook".into(),
144                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
145                }),
146            )
147    }
148
149    /// Update the Outgoing Webhook identified by its id.
150    ///
151    /// # Arguments
152    /// * `webhook_id` - The id of the webhook to update.
153    /// * `webhook_type` - The [`WebhookType`].
154    /// * `name` - The name of the webhook.
155    /// * `url` - The [`Url`] of the webhook.
156    /// * `config` - The [`Config`] of the webhook.
157    pub async fn replace(
158        &self,
159        webhook_id: String,
160        name: Option<String>,
161        webhook_type: WebhookType,
162        url: Url,
163        config: Config,
164    ) -> Result<UpdateOutgoingWebhookResponse> {
165        let request = make_request_with_metadata(
166            UpdateOutgoingWebhookRequest {
167                id: webhook_id,
168                data: Some(OutgoingWebhookInputData {
169                    r#type: webhook_type.into(),
170                    name,
171                    url: Some(url.into()),
172                    config: Some(config),
173                }),
174            },
175            &self.metadata_map,
176        );
177        self.service_client
178            .lock()
179            .await
180            .update_outgoing_webhook(request)
181            .await
182            .map(|r| r.into_inner())
183            .map_err(
184                |status| SdkError::ApiError(SdkApiError {
185                    status,
186                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/UpdateOutgoingWebhook".into(),
187                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
188                }),
189            )
190    }
191
192    /// Deletes the Outgoing Webhook.
193    ///
194    /// # Arguments
195    /// * `webhook_id` - The id of the webhook to delete.
196    pub async fn delete(&self, webhook_id: String) -> Result<DeleteOutgoingWebhookResponse> {
197        let request = make_request_with_metadata(
198            DeleteOutgoingWebhookRequest {
199                id: Some(webhook_id),
200            },
201            &self.metadata_map,
202        );
203        self.service_client
204            .lock()
205            .await
206            .delete_outgoing_webhook(request)
207            .await
208            .map(|r| r.into_inner())
209            .map_err(
210                |status| SdkError::ApiError(SdkApiError {
211                    status,
212                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/DeleteOutgoingWebhook".into(),
213                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
214                }),
215            )
216    }
217
218    /// Retrieves the Outgoing Webhook by id.
219    ///
220    /// # Arguments
221    /// * `webhook_id` - The id of the webhook to get.
222    pub async fn get(&self, webhook_id: String) -> Result<GetOutgoingWebhookResponse> {
223        let request = make_request_with_metadata(
224            GetOutgoingWebhookRequest {
225                id: Some(webhook_id),
226            },
227            &self.metadata_map,
228        );
229
230        self.service_client
231            .lock()
232            .await
233            .get_outgoing_webhook(request)
234            .await
235            .map(|r| r.into_inner())
236            .map_err(
237                |status| SdkError::ApiError(SdkApiError {
238                    status,
239                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/GetOutgoingWebhook".into(),
240                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
241                }),
242            )
243    }
244
245    /// Get outgoing [`WebhookType`] details.
246    ///
247    /// # Arguments
248    /// * `webhook_type` - The type of the webhook.
249    pub async fn get_outgoing_webhook_type_details(
250        &self,
251        webhook_type: WebhookType,
252    ) -> Result<GetOutgoingWebhookTypeDetailsResponse> {
253        let request = make_request_with_metadata(
254            GetOutgoingWebhookTypeDetailsRequest {
255                r#type: webhook_type.into(),
256            },
257            &self.metadata_map,
258        );
259
260        self.service_client
261            .lock()
262            .await
263            .get_outgoing_webhook_type_details(request)
264            .await
265            .map(|r| r.into_inner())
266            .map_err(
267                |status| SdkError::ApiError(SdkApiError {
268                    status,
269                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/GetOutgoingWebhookTypeDetails".into(),
270                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
271                }),
272            )
273    }
274
275    /// Tests the provided outgoing webhook
276    ///
277    /// # Arguments
278    /// * `webhook_type` - The [`WebhookType`].
279    /// * `name` - The name of the webhook.
280    /// * `url` - The [`Url`] of the webhook.
281    /// * `config` - The [`Config`] of the webhook.
282    pub async fn test_webhook(
283        &self,
284        webhook_type: WebhookType,
285        name: Option<String>,
286        url: Url,
287        config: Config,
288    ) -> Result<TestOutgoingWebhookResponse> {
289        let request = make_request_with_metadata(
290            TestOutgoingWebhookRequest {
291                data: Some(OutgoingWebhookInputData {
292                    r#type: webhook_type.into(),
293                    name,
294                    url: Some(url.into()),
295                    config: Some(config),
296                }),
297            },
298            &self.metadata_map,
299        );
300
301        self.service_client
302            .lock()
303            .await
304            .test_outgoing_webhook(request)
305            .await
306            .map(|r| r.into_inner())
307            .map_err(
308                |status| SdkError::ApiError(SdkApiError {
309                    status,
310                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/TestOutgoingWebhook".into(),
311                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
312                }),
313            )
314    }
315
316    /// Tests the existing outgoing webhook
317    ///
318    /// # Arguments
319    /// * `webhook_id` - The id of the webhook to test.
320    pub async fn test_webhook_by_id(
321        &self,
322        webhook_id: String,
323    ) -> Result<TestOutgoingWebhookResponse> {
324        let request = make_request_with_metadata(
325            TestExistingOutgoingWebhookRequest {
326                id: Some(webhook_id),
327            },
328            &self.metadata_map,
329        );
330
331        self.service_client
332            .lock()
333            .await
334            .test_existing_outgoing_webhook(request)
335            .await
336            .map(|r| r.into_inner())
337            .map_err(
338                |status| SdkError::ApiError(SdkApiError {
339                    status,
340                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/TestExistingOutgoingWebhook".into(),
341                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
342                }),
343            )
344    }
345
346    /// Get [`WebhookType`] details.
347    ///     
348    /// # Arguments
349    /// * `webhook_type` - The [`WebhookType`].
350    pub async fn get_type(
351        &self,
352        webhook_type: WebhookType,
353    ) -> Result<ListOutgoingWebhooksResponse> {
354        let request = make_request_with_metadata(
355            ListOutgoingWebhooksRequest {
356                r#type: webhook_type.into(),
357            },
358            &self.metadata_map,
359        );
360
361        self.service_client
362            .lock()
363            .await
364            .list_outgoing_webhooks(request)
365            .await
366            .map(|r| r.into_inner())
367            .map_err(
368                |status| SdkError::ApiError(SdkApiError {
369                    status,
370                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/ListOutgoingWebhooks".into(),
371                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
372                }),
373            )
374    }
375
376    /// Retrieves a list of all outgoing webhooks.
377    ///     
378    /// # Returns  
379    /// A list of all outgoing webhooks.
380    pub async fn list(&self) -> Result<ListAllOutgoingWebhooksResponse> {
381        let request =
382            make_request_with_metadata(ListAllOutgoingWebhooksRequest {}, &self.metadata_map);
383
384        self.service_client
385            .lock()
386            .await
387            .list_all_outgoing_webhooks(request)
388            .await
389            .map(|r| r.into_inner())
390            .map_err(
391                |status| SdkError::ApiError(SdkApiError {
392                    status,
393                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/ListAllOutgoingWebhooks".into(),
394                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
395                }),
396            )
397    }
398
399    /// Retrieves a list of all [`WebhookType`]s.
400    ///     
401    /// # Returns
402    /// A list of all webhook types.
403    pub async fn list_webhook_types(&self) -> Result<ListOutgoingWebhookTypesResponse> {
404        let request =
405            make_request_with_metadata(ListOutgoingWebhookTypesRequest {}, &self.metadata_map);
406
407        self.service_client
408            .lock()
409            .await
410            .list_outgoing_webhook_types(request)
411            .await
412            .map(|r| r.into_inner())
413            .map_err(
414                |status| SdkError::ApiError(SdkApiError {
415                    status,
416                    endpoint: "/com.coralogixapis.outgoing_webhooks.v1.OutgoingWebhooksService/ListOutgoingWebhookTypes".into(),
417                    feature_group: WEBHOOKS_FEATURE_GROUP_ID.into(),
418                }),
419            )
420    }
421}