google_indexing_api/
lib.rs

1//! # GoogleIndexingAPI
2//!
3//! This is a general-purpose library for using the GoogleIndex API.
4//!
5//! Since it defines the structures needed for the API, it can simplify API access.
6//!
7//! ※ Token generation is not supported in this API.
8//!
9//! ## Batch API
10//! With the batch API, you can make multiple publish requests in bulk. When processing a large number of job listings consecutively, batch requests are processed faster.
11//! ```rust
12//! use google_indexing_api::{GoogleIndexingApi, ResponseGoogleIndexingBatch, UrlNotificationsType};
13//! async fn example_batch(token: &str)   {
14//!     GoogleIndexingApi::url_notifications()
15//!         .batch(
16//!             token,
17//!             vec![
18//!                 "http://!example.com/widgets/1".to_string(),
19//!                 "http://!example.com/widgets/2".to_string(),
20//!             ],
21//!             UrlNotificationsType::UPDATED,
22//!         )
23//!         .await;
24//! }
25//! ```
26//!
27//! ## Metadata API
28//! The metadata API allows you to check the status of a URL notification.
29//! ```rust
30//! use google_indexing_api::{GoogleIndexingApi, ResponseUrlNotificationMetadata};
31//!  async fn example_metadata(token: &str) {
32//!     GoogleIndexingApi::url_notifications()
33//!         .get_metadata(
34//!             token,
35//!             "http://!example.com/widgets/1",
36//!         )
37//!         .await;
38//! }
39//! ```
40mod error;
41mod http;
42
43use crate::http::HttpClient;
44use crate::GoogleApiError;
45pub use error::*;
46use serde::{Deserialize, Serialize};
47use serde_json::{json, Value};
48use urlencoding::encode;
49
50/// API Access Endpoint
51pub struct GoogleIndexingApi {}
52
53impl GoogleIndexingApi {
54    pub fn url_notifications() -> UrlNotificationsApi {
55        UrlNotificationsApi::default()
56    }
57}
58
59/// URL Notification Type
60/// UPDATE or DELETE
61#[derive(Default, Debug, Serialize, Deserialize, Clone)]
62pub enum UrlNotificationsType {
63    #[serde(rename = "URL_NOTIFICATION_TYPE_UNSPECIFIED")]
64    #[default]
65    UrlNotificationTypeUnspecified,
66    #[serde(rename = "URL_UPDATED")]
67    UPDATED,
68    #[serde(rename = "URL_DELETED")]
69    DELETED,
70}
71
72impl ToString for UrlNotificationsType {
73    fn to_string(&self) -> String {
74        match self {
75            UrlNotificationsType::UPDATED => "URL_UPDATED".to_string(),
76            UrlNotificationsType::DELETED => "URL_DELETED".to_string(),
77            UrlNotificationsType::UrlNotificationTypeUnspecified => {
78                "URL_NOTIFICATION_TYPE_UNSPECIFIED".to_string()
79            }
80        }
81    }
82}
83
84// https://developers.go
85// ogle.com/search/apis/indexing-api/v3/reference/indexing/rest/v3/urlNotifications?hl=ja
86/// urlNotifications API
87#[derive(Default)]
88pub struct UrlNotificationsApi {}
89
90impl UrlNotificationsApi {
91    pub async fn publish(
92        &self,
93        token: &str,
94        url: &str,
95        url_type: UrlNotificationsType,
96    ) -> Result<Value, GoogleApiError> {
97        Ok(HttpClient::post(
98            token,
99            format!(r#"https://indexing.googleapis.com/v3/urlNotifications:publish"#,).as_str(),
100            json!({
101                "url": url,
102                "type": url_type.to_string(),
103            }),
104        )
105        .await?)
106    }
107    pub async fn get_metadata(
108        &self,
109        token: &str,
110        url: &str,
111    ) -> Result<ResponseUrlNotificationMetadata, GoogleApiError> {
112        Ok(HttpClient::get(
113            token,
114            format!(
115                r#"https://indexing.googleapis.com/v3/urlNotifications/metadata?url={}"#,
116                encode(url),
117            )
118            .as_str(),
119        )
120        .await?)
121    }
122    pub async fn batch(
123        &self,
124        token: &str,
125        urls: Vec<String>,
126        url_type: UrlNotificationsType,
127    ) -> Result<Vec<ResponseGoogleIndexingBatch>, GoogleApiError> {
128        Ok(HttpClient::execute(token, urls, url_type).await?)
129    }
130}
131
132/// Response Url Notification Metadata
133#[derive(Default, Debug, Serialize, Deserialize, Clone)]
134pub struct ResponseUrlNotificationMetadata {
135    pub url: String,
136    #[serde(rename = "latestUpdate")]
137    pub latest_update: Option<ResponseUrlNotification>,
138    #[serde(rename = "latestRemove")]
139    pub latest_remove: Option<ResponseUrlNotification>,
140}
141
142/// Response Url Notification
143#[derive(Debug, Serialize, Deserialize, Clone)]
144pub struct ResponseUrlNotification {
145    pub url: String,
146    #[serde(rename = "type")]
147    pub url_type: UrlNotificationsType,
148    #[serde(rename = "notifyTime")]
149    pub notify_time: String,
150}
151
152/// Google Index Batch Response
153#[derive(Debug, Default)]
154pub struct ResponseGoogleIndexingBatch {
155    url: String,
156    status_code: u16,
157    value: String,
158}
159
160impl ResponseGoogleIndexingBatch {
161    pub fn url(&self) -> &str {
162        self.url.as_str()
163    }
164    pub fn status_code(&self) -> u16 {
165        self.status_code
166    }
167    pub fn value(&self) -> &str {
168        self.value.as_str()
169    }
170    pub fn json(&self) -> Value {
171        let v = serde_json::from_str(self.value.as_str());
172        if v.is_ok() {
173            return v.unwrap();
174        }
175        Value::default()
176    }
177}