valorant_api/
lib.rs

1#![deny(warnings)]
2#![deny(unused)]
3#![deny(clippy::expect_used)]
4#![deny(clippy::get_unwrap)]
5#![deny(clippy::exit)]
6#![deny(clippy::indexing_slicing)]
7#![deny(clippy::panic)]
8#![deny(clippy::panic_in_result_fn)]
9#![deny(clippy::unreachable)]
10#![deny(clippy::unwrap_used)]
11#![deny(clippy::unwrap_in_result)]
12#![deny(clippy::print_stdout)]
13#![allow(clippy::upper_case_acronyms)]
14
15//! # Valorant API
16//! This crate is a wrapper for the In-Game Valorant API.
17//!
18//! ## Usage
19//!
20//! ### 1. Authenticate
21//!
22//! To use this crate, you need to authenticate with your Riot Games account.
23//! Currently, the only way to do this is by using a username and password (no 2FA).
24//!
25//! ```rust no_run
26//! use valorant_api::utils::credentials_manager::CredentialsManager;
27//! use valorant_api::utils::network::http_client::SimpleHttpClient;
28//!
29//! #[tokio::main]
30//! async fn main() {
31//!     let http_client = SimpleHttpClient::new();
32//!     let mut credentials_manager = valorant_api::utils::credentials_manager::CredentialsManager::new();
33//!     let result = credentials_manager
34//!         .authenticate(&http_client, "username", "password")
35//!         .await;
36//!     match result {
37//!         Ok(_) => println!("Authenticated"),
38//!         Err(_) => println!("Error while authenticating"),
39//!     }
40//! }
41//! ```
42//!
43//! ### 2. Use the API
44//!
45//! ```rust no_run
46//! use valorant_api::enums::region::Region;
47//! use uuid::Uuid;
48//! use std::collections::HashMap;
49//!
50//! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
51//! let region = Region::EU;
52//! let queries = HashMap::new();
53//! let result = valorant_api::get_competitve_updates_v1(credentials_manager, &http_client, region, &puuid, queries).await;
54//! println!("Result: {:#?}", result);
55//! ```
56//!
57//! ## Endpoints
58//!
59//! ### Competitive Updates V1
60//!
61//! Function: [`get_competitive_updates_v1`]
62//!
63//! Result Type: [`CompetitiveUpdatesV1`]
64//!
65//! ### Match Details V1
66//!
67//! Function: [`get_match_details_v1`]
68//!
69//! Result Type: [`MatchDetailsV1`]
70//!
71//! ### Match History V1
72//!
73//! Function: [`get_match_history_v1`]
74//!
75//! Result Type: [`MatchHistoryV1`]
76//!
77//! ### MMRV1
78//!
79//! Function: [`get_mmr_details_v1`]
80//!
81//! Result Type: [`MMRDetailsV1`]
82//!
83//! ### Leaderboard V1
84//!
85//! Function: [`get_leaderboard_v1`]
86//!
87//! Result Type: [`LeaderboardV1`]
88//!
89//! ### Content V3
90//!
91//! Function: [`get_content_v3`]
92//!
93//! Result Type: [`ContentV3`]
94//!
95//! ### Store Offers V1
96//!
97//! Function: [`get_store_offers_v1`]
98//!
99//! Result Type: [`StoreOffersV1`]
100//!
101//! ### Store Front V2
102//!
103//! Function: [`get_store_front_v2`]
104//!
105//! Result Type: [`StoreFrontV2`]
106//!
107
108use std::collections::HashMap;
109use std::str::FromStr;
110use std::string::ToString;
111
112use reqwest::{Client, Method};
113use url::Url;
114use uuid::Uuid;
115
116use crate::enums::esport_locales::EsportsLocales;
117use crate::enums::platform::Platform;
118use crate::enums::query_arg::{
119    CompetitiveUpdateQueryArg, LeaderboardQueryArg, MatchHistoryQueryArg,
120};
121use crate::enums::region::Region;
122use crate::errors::response_error::RequestError;
123use crate::response_types::account_aliases_v1::AccountAliasesV1;
124use crate::response_types::competitive_updates_v1::CompetitiveUpdatesV1;
125use crate::response_types::content_v3::ContentV3;
126use crate::response_types::esports_service_leagues::EsportsLeagues;
127use crate::response_types::esports_service_schedule::EsportsSchedule;
128use crate::response_types::esports_service_vods::EsportsVod;
129use crate::response_types::leaderboard_v1::LeaderboardV1;
130use crate::response_types::matchdetails_v1::MatchDetailsV1;
131use crate::response_types::matchhistory_v1::MatchHistoryV1;
132use crate::response_types::mmrdetails_v1::MMRDetailsV1;
133use crate::response_types::store_front_v2::StoreFrontV2;
134use crate::response_types::store_offers_v1::StoreOffersV1;
135use crate::utils::credentials_manager::CredentialsManager;
136use crate::utils::fetch::fetch_endpoint;
137use crate::utils::functions::set_query_args;
138
139pub mod enums;
140pub mod errors;
141pub mod response_types;
142pub mod utils;
143
144const ESPORTS_API_KEY: &str = "0TvQnueqKa5mxJntVWt0w4LpLfEkrV1Ta8rQBb9Z";
145
146pub async fn get_match_history_v1(
147    credentials_manager: &CredentialsManager,
148    http_client: &Client,
149    region: Region,
150    puuid: &Uuid,
151    query_args: HashMap<MatchHistoryQueryArg, String>,
152) -> Result<MatchHistoryV1, RequestError> {
153    //! Get the match history of a player
154    //! # Arguments
155    //! * `credentials_manager` - The credentials manager
156    //! * `region` - The region of the player
157    //! * `puuid` - The puuid of the player
158    //! * `query_args` - The query arguments
159    //! # Example
160    //! ```rust no_run
161    //! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
162    //! let region = Region::EU;
163    //! let queries = HashMap::new();
164    //! let result = valorant_api::get_match_history_v1(credentials_manager, &http_client, region, &puuid, queries).await;
165    //! println!("Result: {:#?}", result);
166    //! ```
167
168    let mut url = Url::from_str(&format!(
169        "https://pd.{}.a.pvp.net/match-history/v1/history/{}",
170        region.to_shard(),
171        puuid
172    ))?;
173    set_query_args(&mut url, query_args.into_iter());
174
175    fetch_endpoint(
176        credentials_manager,
177        http_client,
178        url,
179        Method::GET,
180        "",
181        &HashMap::new(),
182    )
183    .await
184}
185
186pub async fn get_match_details_v1(
187    credentials_manager: &CredentialsManager,
188    http_client: &Client,
189    region: Region,
190    match_id: &Uuid,
191) -> Result<MatchDetailsV1, RequestError> {
192    //! Get the match details of a match
193    //! # Arguments
194    //! * `credentials_manager` - The credentials manager
195    //! * `region` - The region of the match
196    //! * `match_id` - The match id of the match
197    //! # Example
198    //! ```rust no_run
199    //! let match_id = Uuid::parse_str("3100c02b-17d2-4adb-97b5-e45dee67d292").expect("Invalid UUID");
200    //! let region = Region::EU;
201    //! let result = valorant_api::get_match_details_v1(credentials_manager, &http_client, region, &match_id).await;
202    //! println!("Result: {:#?}", result);
203    //! ```
204
205    let url = Url::from_str(&format!(
206        "https://pd.{}.a.pvp.net/match-details/v1/matches/{}",
207        region.to_shard(),
208        match_id
209    ))?;
210
211    fetch_endpoint(
212        credentials_manager,
213        http_client,
214        url,
215        Method::GET,
216        "",
217        &HashMap::new(),
218    )
219    .await
220}
221
222pub async fn get_mmr_details_v1(
223    credentials_manager: &CredentialsManager,
224    http_client: &Client,
225    region: Region,
226    puuid: &Uuid,
227) -> Result<MMRDetailsV1, RequestError> {
228    //! Get the mmr of a player
229    //! # Arguments
230    //! * `credentials_manager` - The credentials manager
231    //! * `region` - The region of the player
232    //! * `puuid` - The puuid of the player
233    //! # Example
234    //! ```rust no_run
235    //! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
236    //! let region = Region::EU;
237    //! let result = valorant_api::get_mmr_details_v1(credentials_manager, &http_client, region, &puuid).await;
238    //! println!("Result: {:#?}", result);
239    //! ```
240
241    let url = Url::from_str(&format!(
242        "https://pd.{}.a.pvp.net/mmr/v1/players/{}",
243        region.to_shard(),
244        puuid
245    ))?;
246
247    fetch_endpoint(
248        credentials_manager,
249        http_client,
250        url,
251        Method::GET,
252        "",
253        &HashMap::new(),
254    )
255    .await
256}
257
258pub async fn get_competitive_updates_v1(
259    credentials_manager: &CredentialsManager,
260    http_client: &Client,
261    region: Region,
262    puuid: &Uuid,
263    query_args: HashMap<CompetitiveUpdateQueryArg, String>,
264) -> Result<CompetitiveUpdatesV1, RequestError> {
265    //! Get the competitve updates of a player
266    //! # Arguments
267    //! * `credentials_manager` - The credentials manager
268    //! * `region` - The region of the player
269    //! * `puuid` - The puuid of the player
270    //! * `query_args` - The query arguments
271    //! # Example
272    //! ```rust no_run
273    //! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
274    //! let region = Region::EU;
275    //! let queries = HashMap::new();
276    //! let result = valorant_api::get_competitve_updates_v1(credentials_manager, &http_client, region, &puuid, queries).await;
277    //! println!("Result: {:#?}", result);
278    //! ```
279
280    let mut url = Url::from_str(&format!(
281        "https://pd.{}.a.pvp.net/mmr/v1/players/{}/competitiveupdates",
282        region.to_shard(),
283        puuid
284    ))?;
285    set_query_args(&mut url, query_args.into_iter());
286
287    fetch_endpoint(
288        credentials_manager,
289        http_client,
290        url,
291        Method::GET,
292        "",
293        &HashMap::new(),
294    )
295    .await
296}
297
298pub async fn get_content_v3(
299    credentials_manager: &CredentialsManager,
300    http_client: &Client,
301    region: Region,
302) -> Result<ContentV3, RequestError> {
303    //! Get the content of the game
304    //! # Arguments
305    //! * `credentials_manager` - The credentials manager
306    //! * `region` - The region of the player
307    //! # Example
308    //! ```rust no_run
309    //! let region = Region::EU;
310    //! let result = valorant_api::get_content_v1(credentials_manager, &http_client, region).await;
311    //! println!("Result: {:#?}", result);
312    //! ```
313
314    let url = Url::from_str(&format!(
315        "https://shared.{}.a.pvp.net/content-service/v3/content",
316        region.to_shard(),
317    ))?;
318
319    fetch_endpoint(
320        credentials_manager,
321        http_client,
322        url,
323        Method::GET,
324        "",
325        &HashMap::new(),
326    )
327    .await
328}
329
330pub async fn get_leaderboard_v1(
331    credentials_manager: &CredentialsManager,
332    http_client: &Client,
333    region: Region,
334    season: &Uuid,
335    query_args: HashMap<LeaderboardQueryArg, String>,
336) -> Result<LeaderboardV1, RequestError> {
337    //! Get the leaderboard of a region
338    //! # Arguments
339    //! * `credentials_manager` - The credentials manager
340    //! * `region` - The region of the leaderboard
341    //! * `season` - The season of the leaderboard
342    //! * `query_args` - The query arguments
343    //! # Errors
344    //! `RequestError` - If the request failed
345    //! # Example
346    //! ```rust no_run
347    //! let season = Uuid::parse_str("34093c29-4306-43de-452f-3f944bde22be").expect("Invalid UUID");
348    //! let region = Region::EU;
349    //! let queries = HashMap::new();
350    //! let result = valorant_api::get_leaderboard_v1(credentials_manager, &http_client, region, &season, queries).await;
351    //! println!("Result: {:#?}", result);
352    //! ```
353
354    let queue = match credentials_manager.platform {
355        Platform::PC => "competitive",
356        Platform::XBOX | Platform::PlayStation => "console_competitive",
357    };
358    let mut url = Url::from_str(&format!(
359        "https://pd.{}.a.pvp.net/mmr/v1/leaderboards/affinity/{}/queue/{}/season/{}",
360        region.to_shard(),
361        region,
362        queue,
363        season
364    ))?;
365    set_query_args(&mut url, query_args.into_iter());
366
367    fetch_endpoint(
368        credentials_manager,
369        http_client,
370        url,
371        Method::GET,
372        "",
373        &HashMap::new(),
374    )
375    .await
376}
377
378pub async fn get_store_offers_v1(
379    credentials_manager: &CredentialsManager,
380    http_client: &Client,
381    region: Region,
382) -> Result<StoreOffersV1, RequestError> {
383    //! Get the store offers of a region
384    //! # Arguments
385    //! * `credentials_manager` - The credentials manager
386    //! * `region` - The region of the leaderboard
387    //! # Errors
388    //! `RequestError` - If the request failed
389    //! # Example
390    //! ```rust no_run
391    //! let season = Uuid::parse_str("34093c29-4306-43de-452f-3f944bde22be").expect("Invalid UUID");
392    //! let region = Region::EU;
393    //! let result = valorant_api::get_store_offers_v1(credentials_manager, &http_client, region).await;
394    //! println!("Result: {:#?}", result);
395    //! ```
396
397    let url = Url::from_str(&format!(
398        "https://pd.{}.a.pvp.net/store/v1/offers/",
399        region.to_shard(),
400    ))?;
401
402    fetch_endpoint(
403        credentials_manager,
404        http_client,
405        url,
406        Method::GET,
407        "",
408        &HashMap::new(),
409    )
410    .await
411}
412
413pub async fn get_store_front_v2(
414    credentials_manager: &CredentialsManager,
415    http_client: &Client,
416    region: Region,
417    puuid: Uuid,
418) -> Result<StoreFrontV2, RequestError> {
419    //! Get the store front of a player
420    //! # Arguments
421    //! * `credentials_manager` - The credentials manager
422    //! * `region` - The region of the leaderboard
423    //! * `puuid` - The puuid of the player
424    //! # Errors
425    //! `RequestError` - If the request failed
426    //! # Example
427    //! ```rust no_run
428    //! let puuid = Uuid::parse_str("34093c29-4306-43de-452f-3f944bde22be").expect("Invalid UUID");
429    //! let region = Region::EU;
430    //! let result = valorant_api::get_store_front_v1(credentials_manager, &http_client, region, puuid).await;
431    //! println!("Result: {:#?}", result);
432    //! ```
433
434    let url = Url::from_str(&format!(
435        "https://pd.{}.a.pvp.net/store/v2/storefront/{}",
436        region.to_shard(),
437        puuid,
438    ))?;
439
440    fetch_endpoint(
441        credentials_manager,
442        http_client,
443        url,
444        Method::GET,
445        "",
446        &HashMap::new(),
447    )
448    .await
449}
450
451pub async fn get_account_aliases(
452    credentials_manager: &CredentialsManager,
453    http_client: &Client,
454    cluster: &str,
455    game_name: Option<&str>,
456    tag_line: Option<&str>,
457) -> Result<AccountAliasesV1, RequestError> {
458    //! Get the account aliases of a player.
459    //! This can be used to search for an account by game name and/or tag_line and get their puuid.
460    //! # Arguments
461    //! * `credentials_manager` - The credentials manager
462    //! * `http_client` - The http client
463    //! * `cluster` - The cluster of the player
464    //! * `game_name` - The game name of the player
465    //! * `tag_line` - The tag line of the player
466    //! # Errors
467    //! `RequestError` - If the request failed
468    //! # Example
469    //! ```rust no_run
470    //! let result = valorant_api::get_account_aliases(credentials_manager, &http_client, "eu", None, None).await;
471    //! println!("Result: {:#?}", result);
472    //! ```
473    let mut url = Url::from_str(&format!(
474        "https://{}.api.account.riotgames.com/aliases/v1/aliases",
475        cluster
476    ))?;
477    if let Some(game_name) = game_name {
478        url.query_pairs_mut().append_pair("gameName", game_name);
479    }
480    if let Some(tag_line) = tag_line {
481        url.query_pairs_mut().append_pair("tagLine", tag_line);
482    }
483
484    fetch_endpoint(
485        credentials_manager,
486        http_client,
487        url,
488        Method::GET,
489        "",
490        &HashMap::new(),
491    )
492    .await
493}
494
495pub async fn get_esports_leagues(
496    credentials_manager: &CredentialsManager,
497    http_client: &Client,
498    locale: EsportsLocales,
499) -> Result<EsportsLeagues, RequestError> {
500    //! Get all active valorant esports leagues.
501    //! # Arguments
502    //! * `credentials_manager` - The credentials manager
503    //! * `http_client` - The http client
504    //! * `locale` - The locale in which the leagues should be returned
505    //! # Errors
506    //! `RequestError` - If the request failed
507    //! # Example
508    //! ```rust no_run
509    //! let result = valorant_api::get_esports_leagues(&credential_manager, &http_client, EsportsLocales::US).await;
510    //! println!("Result: {:#?}", result);
511    //! ```
512    let url = Url::from_str(&format!(
513        "https://esports-api.service.valorantesports.com/persisted/val/getLeagues?hl={}&sport=val",
514        locale
515    ))?;
516    fetch_endpoint(
517        credentials_manager,
518        http_client,
519        url,
520        Method::GET,
521        "",
522        &HashMap::from([("x-api-key".to_string(), ESPORTS_API_KEY.to_string())]),
523    )
524    .await
525}
526
527pub async fn get_esports_schedule(
528    credentials_manager: &CredentialsManager,
529    http_client: &Client,
530    locale: EsportsLocales,
531) -> Result<EsportsSchedule, RequestError> {
532    //! Get the schedule for all professional valorant games.
533    //! # Arguments
534    //! * `credentials_manager` - The credentials manager
535    //! * `http_client` - The http client
536    //! * `locale` - The locale in which the schedules should be returned
537    //! # Errors
538    //! `RequestError` - If the request failed
539    //! # Example
540    //! ```rust no_run
541    //! let result = valorant_api::get_esports_schedule(&credential_manager, &http_client, EsportsLocales::US).await;
542    //! println!("Result: {:#?}", result);
543    //! ```
544    let url = Url::from_str(&format!(
545        "https://esports-api.service.valorantesports.com/persisted/val/getSchedule?hl={}&sport=val",
546        locale
547    ))?;
548
549    fetch_endpoint(
550        credentials_manager,
551        http_client,
552        url,
553        Method::GET,
554        "",
555        &HashMap::from([("x-api-key".to_string(), ESPORTS_API_KEY.to_string())]),
556    )
557    .await
558}
559
560pub async fn get_esports_vods(
561    credentials_manager: &CredentialsManager,
562    http_client: &Client,
563    locale: EsportsLocales,
564) -> Result<EsportsVod, RequestError> {
565    //! Get the vod data for each game.
566    //! # Arguments
567    //! * `credentials_manager` - The credentials manager
568    //! * `http_client` - The http client
569    //! * `locale` - The locale in which the vod data should be returned
570    //! # Errors
571    //! `RequestError` - If the request failed
572    //! # Example
573    //! ```rust no_run
574    //! let result = valorant_api::get_esports_vods(&credential_manager, &http_client, EsportsLocales::US).await;
575    //! println!("Result: {:#?}", result);
576    //! ```
577    let url = Url::from_str(&format!(
578        "https://esports-api.service.valorantesports.com/persisted/val/getVods?hl={}&sport=val",
579        locale
580    ))?;
581
582    fetch_endpoint(
583        credentials_manager,
584        http_client,
585        url,
586        Method::GET,
587        "",
588        &HashMap::from([("x-api-key".to_string(), ESPORTS_API_KEY.to_string())]),
589    )
590    .await
591}