modrinth_api/apis/
notifications_api.rs

1/*
2 * Labrinth
3 *
4 * This documentation doesn't provide a way to test our API. In order to facilitate testing, we recommend the following tools:  - [cURL](https://curl.se/) (recommended, command-line) - [ReqBIN](https://reqbin.com/) (recommended, online) - [Postman](https://www.postman.com/downloads/) - [Insomnia](https://insomnia.rest/) - Your web browser, if you don't need to send headers or a request body  Once you have a working client, you can test that it works by making a `GET` request to `https://staging-api.modrinth.com/`:  ```json {   \"about\": \"Welcome traveler!\",   \"documentation\": \"https://docs.modrinth.com\",   \"name\": \"modrinth-labrinth\",   \"version\": \"2.7.0\" } ```  If you got a response similar to the one above, you can use the Modrinth API! When you want to go live using the production API, use `api.modrinth.com` instead of `staging-api.modrinth.com`.  ## Authentication This API has two options for authentication: personal access tokens and [OAuth2](https://en.wikipedia.org/wiki/OAuth). All tokens are tied to a Modrinth user and use the `Authorization` header of the request.  Example: ``` Authorization: mrp_RNtLRSPmGj2pd1v1ubi52nX7TJJM9sznrmwhAuj511oe4t1jAqAQ3D6Wc8Ic ```  You do not need a token for most requests. Generally speaking, only the following types of requests require a token: - those which create data (such as version creation) - those which modify data (such as editing a project) - those which access private data (such as draft projects, notifications, emails, and payout data)  Each request requiring authentication has a certain scope. For example, to view the email of the user being requested, the token must have the `USER_READ_EMAIL` scope. You can find the list of available scopes [on GitHub](https://github.com/modrinth/labrinth/blob/master/src/models/pats.rs#L15). Making a request with an invalid scope will return a 401 error.  Please note that certain scopes and requests cannot be completed with a personal access token or using OAuth. For example, deleting a user account can only be done through Modrinth's frontend.  ### OAuth2 Applications interacting with the authenticated API should create an OAuth2 application. You can do this in [the developer settings](https://modrinth.com/settings/applications).  Once you have created a client, use the following URL to have a user authorize your client: ``` https://modrinth.com/auth/authorize?client_id=<CLIENT_ID>&redirect_uri=<CALLBACK_URL>&scope=<SCOPE_ONE>+<SCOPE_TWO>+<SCOPE_THREE> ```  Then, use the following URL to get the token: ``` https://api.modrinth.com/_internal/oauth/token ```  This route will be changed in the future to move the `_internal` part to `v3`.  ### Personal access tokens Personal access tokens (PATs) can be generated in from [the user settings](https://modrinth.com/settings/account).  ### GitHub tokens For backwards compatibility purposes, some types of GitHub tokens also work for authenticating a user with Modrinth's API, granting all scopes. **We urge any application still using GitHub tokens to start using personal access tokens for security and reliability purposes.** GitHub tokens will cease to function to authenticate with Modrinth's API as soon as version 3 of the API is made generally available.  ## Cross-Origin Resource Sharing This API features Cross-Origin Resource Sharing (CORS) implemented in compliance with the [W3C spec](https://www.w3.org/TR/cors/). This allows for cross-domain communication from the browser. All responses have a wildcard same-origin which makes them completely public and accessible to everyone, including any code on any site.  ## Identifiers The majority of items you can interact with in the API have a unique eight-digit base62 ID. Projects, versions, users, threads, teams, and reports all use this same way of identifying themselves. Version files use the sha1 or sha512 file hashes as identifiers.  Each project and user has a friendlier way of identifying them; slugs and usernames, respectively. While unique IDs are constant, slugs and usernames can change at any moment. If you want to store something in the long term, it is recommended to use the unique ID.  ## Ratelimits The API has a ratelimit defined per IP. Limits and remaining amounts are given in the response headers. - `X-Ratelimit-Limit`: the maximum number of requests that can be made in a minute - `X-Ratelimit-Remaining`: the number of requests remaining in the current ratelimit window - `X-Ratelimit-Reset`: the time in seconds until the ratelimit window resets  Ratelimits are the same no matter whether you use a token or not. The ratelimit is currently 300 requests per minute. If you have a use case requiring a higher limit, please [contact us](mailto:admin@modrinth.com).  ## User Agents To access the Modrinth API, you **must** use provide a uniquely-identifying `User-Agent` header. Providing a user agent that only identifies your HTTP client library (such as \"okhttp/4.9.3\") increases the likelihood that we will block your traffic. It is recommended, but not required, to include contact information in your user agent. This allows us to contact you if we would like a change in your application's behavior without having to block your traffic. - Bad: `User-Agent: okhttp/4.9.3` - Good: `User-Agent: project_name` - Better: `User-Agent: github_username/project_name/1.56.0` - Best: `User-Agent: github_username/project_name/1.56.0 (launcher.com)` or `User-Agent: github_username/project_name/1.56.0 (contact@launcher.com)`  ## Versioning Modrinth follows a simple pattern for its API versioning. In the event of a breaking API change, the API version in the URL path is bumped, and migration steps will be published below.  When an API is no longer the current one, it will immediately be considered deprecated. No more support will be provided for API versions older than the current one. It will be kept for some time, but this amount of time is not certain.  We will exercise various tactics to get people to update their implementation of our API. One example is by adding something like `STOP USING THIS API` to various data returned by the API.  Once an API version is completely deprecated, it will permanently return a 410 error. Please ensure your application handles these 410 errors.  ### Migrations Inside the following spoiler, you will be able to find all changes between versions of the Modrinth API, accompanied by tips and a guide to migrate applications to newer versions.  Here, you can also find changes for [Minotaur](https://github.com/modrinth/minotaur), Modrinth's official Gradle plugin. Major versions of Minotaur directly correspond to major versions of the Modrinth API.  <details><summary>API v1 to API v2</summary>  These bullet points cover most changes in the v2 API, but please note that fields containing `mod` in most contexts have been shifted to `project`.  For example, in the search route, the field `mod_id` was renamed to `project_id`.  - The search route has been moved from `/api/v1/mod` to `/v2/search` - New project fields: `project_type` (may be `mod` or `modpack`), `moderation_message` (which has a `message` and `body`), `gallery` - New search facet: `project_type` - Alphabetical sort removed (it didn't work and is not possible due to limits in MeiliSearch) - New search fields: `project_type`, `gallery`   - The gallery field is an array of URLs to images that are part of the project's gallery - The gallery is a new feature which allows the user to upload images showcasing their mod to the CDN which will be displayed on their mod page - Internal change: Any project file uploaded to Modrinth is now validated to make sure it's a valid Minecraft mod, Modpack, etc.   - For example, a Forge 1.17 mod with a JAR not containing a mods.toml will not be allowed to be uploaded to Modrinth - In project creation, projects may not upload a mod with no versions to review, however they can be saved as a draft   - Similarly, for version creation, a version may not be uploaded without any files - Donation URLs have been enabled - New project status: `archived`. Projects with this status do not appear in search - Tags (such as categories, loaders) now have icons (SVGs) and specific project types attached - Dependencies have been wiped and replaced with a new system - Notifications now have a `type` field, such as `project_update`  Along with this, project subroutes (such as `/v2/project/{id}/version`) now allow the slug to be used as the ID. This is also the case with user routes.  </details><details><summary>Minotaur v1 to Minotaur v2</summary>  Minotaur 2.x introduced a few breaking changes to how your buildscript is formatted.  First, instead of registering your own `publishModrinth` task, Minotaur now automatically creates a `modrinth` task. As such, you can replace the `task publishModrinth(type: TaskModrinthUpload) {` line with just `modrinth {`.  To declare supported Minecraft versions and mod loaders, the `gameVersions` and `loaders` arrays must now be used. The syntax for these are pretty self-explanatory.  Instead of using `releaseType`, you must now use `versionType`. This was actually changed in v1.2.0, but very few buildscripts have moved on from v1.1.0.  Dependencies have been changed to a special DSL. Create a `dependencies` block within the `modrinth` block, and then use `scope.type(\"project/version\")`. For example, `required.project(\"fabric-api\")` adds a required project dependency on Fabric API.  You may now use the slug anywhere that a project ID was previously required.  </details> 
5 *
6 * The version of the OpenAPI document: v2.7.0/15cf3fc
7 * Contact: support@modrinth.com
8 * Generated by: https://openapi-generator.tech
9 */
10
11
12use reqwest;
13use serde::{Deserialize, Serialize};
14use crate::{apis::ResponseContent, models};
15use super::{Error, configuration};
16
17
18/// struct for typed errors of method [`delete_notification`]
19#[derive(Debug, Clone, Serialize, Deserialize)]
20#[serde(untagged)]
21pub enum DeleteNotificationError {
22    Status401(models::AuthError),
23    Status404(),
24    UnknownValue(serde_json::Value),
25}
26
27/// struct for typed errors of method [`delete_notifications`]
28#[derive(Debug, Clone, Serialize, Deserialize)]
29#[serde(untagged)]
30pub enum DeleteNotificationsError {
31    Status401(models::AuthError),
32    Status404(),
33    UnknownValue(serde_json::Value),
34}
35
36/// struct for typed errors of method [`get_notification`]
37#[derive(Debug, Clone, Serialize, Deserialize)]
38#[serde(untagged)]
39pub enum GetNotificationError {
40    Status401(models::AuthError),
41    Status404(),
42    UnknownValue(serde_json::Value),
43}
44
45/// struct for typed errors of method [`get_notifications`]
46#[derive(Debug, Clone, Serialize, Deserialize)]
47#[serde(untagged)]
48pub enum GetNotificationsError {
49    Status401(models::AuthError),
50    Status404(),
51    UnknownValue(serde_json::Value),
52}
53
54/// struct for typed errors of method [`get_user_notifications`]
55#[derive(Debug, Clone, Serialize, Deserialize)]
56#[serde(untagged)]
57pub enum GetUserNotificationsError {
58    Status401(models::AuthError),
59    Status404(),
60    UnknownValue(serde_json::Value),
61}
62
63/// struct for typed errors of method [`read_notification`]
64#[derive(Debug, Clone, Serialize, Deserialize)]
65#[serde(untagged)]
66pub enum ReadNotificationError {
67    Status401(models::AuthError),
68    Status404(),
69    UnknownValue(serde_json::Value),
70}
71
72/// struct for typed errors of method [`read_notifications`]
73#[derive(Debug, Clone, Serialize, Deserialize)]
74#[serde(untagged)]
75pub enum ReadNotificationsError {
76    Status401(models::AuthError),
77    Status404(),
78    UnknownValue(serde_json::Value),
79}
80
81
82pub async fn delete_notification(configuration: &configuration::Configuration, id: &str) -> Result<(), Error<DeleteNotificationError>> {
83    let local_var_configuration = configuration;
84
85    let local_var_client = &local_var_configuration.client;
86
87    let local_var_uri_str = format!("{}/notification/{id}", local_var_configuration.base_path, id=crate::apis::urlencode(id));
88    let mut local_var_req_builder = local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
89
90    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
91        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
92    }
93    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
94        let local_var_key = local_var_apikey.key.clone();
95        let local_var_value = match local_var_apikey.prefix {
96            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
97            None => local_var_key,
98        };
99        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
100    };
101
102    let local_var_req = local_var_req_builder.build()?;
103    let local_var_resp = local_var_client.execute(local_var_req).await?;
104
105    let local_var_status = local_var_resp.status();
106    let local_var_content = local_var_resp.text().await?;
107
108    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
109        Ok(())
110    } else {
111        let local_var_entity: Option<DeleteNotificationError> = serde_json::from_str(&local_var_content).ok();
112        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
113        Err(Error::ResponseError(local_var_error))
114    }
115}
116
117pub async fn delete_notifications(configuration: &configuration::Configuration, ids: &str) -> Result<(), Error<DeleteNotificationsError>> {
118    let local_var_configuration = configuration;
119
120    let local_var_client = &local_var_configuration.client;
121
122    let local_var_uri_str = format!("{}/notifications", local_var_configuration.base_path);
123    let mut local_var_req_builder = local_var_client.request(reqwest::Method::DELETE, local_var_uri_str.as_str());
124
125    local_var_req_builder = local_var_req_builder.query(&[("ids", &ids.to_string())]);
126    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
127        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
128    }
129    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
130        let local_var_key = local_var_apikey.key.clone();
131        let local_var_value = match local_var_apikey.prefix {
132            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
133            None => local_var_key,
134        };
135        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
136    };
137
138    let local_var_req = local_var_req_builder.build()?;
139    let local_var_resp = local_var_client.execute(local_var_req).await?;
140
141    let local_var_status = local_var_resp.status();
142    let local_var_content = local_var_resp.text().await?;
143
144    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
145        Ok(())
146    } else {
147        let local_var_entity: Option<DeleteNotificationsError> = serde_json::from_str(&local_var_content).ok();
148        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
149        Err(Error::ResponseError(local_var_error))
150    }
151}
152
153pub async fn get_notification(configuration: &configuration::Configuration, id: &str) -> Result<models::Notification, Error<GetNotificationError>> {
154    let local_var_configuration = configuration;
155
156    let local_var_client = &local_var_configuration.client;
157
158    let local_var_uri_str = format!("{}/notification/{id}", local_var_configuration.base_path, id=crate::apis::urlencode(id));
159    let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
160
161    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
162        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
163    }
164    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
165        let local_var_key = local_var_apikey.key.clone();
166        let local_var_value = match local_var_apikey.prefix {
167            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
168            None => local_var_key,
169        };
170        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
171    };
172
173    let local_var_req = local_var_req_builder.build()?;
174    let local_var_resp = local_var_client.execute(local_var_req).await?;
175
176    let local_var_status = local_var_resp.status();
177    let local_var_content = local_var_resp.text().await?;
178
179    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
180        serde_json::from_str(&local_var_content).map_err(Error::from)
181    } else {
182        let local_var_entity: Option<GetNotificationError> = serde_json::from_str(&local_var_content).ok();
183        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
184        Err(Error::ResponseError(local_var_error))
185    }
186}
187
188pub async fn get_notifications(configuration: &configuration::Configuration, ids: &str) -> Result<Vec<models::Notification>, Error<GetNotificationsError>> {
189    let local_var_configuration = configuration;
190
191    let local_var_client = &local_var_configuration.client;
192
193    let local_var_uri_str = format!("{}/notifications", local_var_configuration.base_path);
194    let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
195
196    local_var_req_builder = local_var_req_builder.query(&[("ids", &ids.to_string())]);
197    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
198        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
199    }
200    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
201        let local_var_key = local_var_apikey.key.clone();
202        let local_var_value = match local_var_apikey.prefix {
203            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
204            None => local_var_key,
205        };
206        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
207    };
208
209    let local_var_req = local_var_req_builder.build()?;
210    let local_var_resp = local_var_client.execute(local_var_req).await?;
211
212    let local_var_status = local_var_resp.status();
213    let local_var_content = local_var_resp.text().await?;
214
215    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
216        serde_json::from_str(&local_var_content).map_err(Error::from)
217    } else {
218        let local_var_entity: Option<GetNotificationsError> = serde_json::from_str(&local_var_content).ok();
219        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
220        Err(Error::ResponseError(local_var_error))
221    }
222}
223
224pub async fn get_user_notifications(configuration: &configuration::Configuration, id_pipe_username: &str) -> Result<Vec<models::Notification>, Error<GetUserNotificationsError>> {
225    let local_var_configuration = configuration;
226
227    let local_var_client = &local_var_configuration.client;
228
229    let local_var_uri_str = format!("{}/user/{term_2}/notifications", local_var_configuration.base_path, term_2=crate::apis::urlencode(id_pipe_username));
230    let mut local_var_req_builder = local_var_client.request(reqwest::Method::GET, local_var_uri_str.as_str());
231
232    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
233        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
234    }
235    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
236        let local_var_key = local_var_apikey.key.clone();
237        let local_var_value = match local_var_apikey.prefix {
238            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
239            None => local_var_key,
240        };
241        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
242    };
243
244    let local_var_req = local_var_req_builder.build()?;
245    let local_var_resp = local_var_client.execute(local_var_req).await?;
246
247    let local_var_status = local_var_resp.status();
248    let local_var_content = local_var_resp.text().await?;
249
250    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
251        serde_json::from_str(&local_var_content).map_err(Error::from)
252    } else {
253        let local_var_entity: Option<GetUserNotificationsError> = serde_json::from_str(&local_var_content).ok();
254        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
255        Err(Error::ResponseError(local_var_error))
256    }
257}
258
259pub async fn read_notification(configuration: &configuration::Configuration, id: &str) -> Result<(), Error<ReadNotificationError>> {
260    let local_var_configuration = configuration;
261
262    let local_var_client = &local_var_configuration.client;
263
264    let local_var_uri_str = format!("{}/notification/{id}", local_var_configuration.base_path, id=crate::apis::urlencode(id));
265    let mut local_var_req_builder = local_var_client.request(reqwest::Method::PATCH, local_var_uri_str.as_str());
266
267    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
268        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
269    }
270    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
271        let local_var_key = local_var_apikey.key.clone();
272        let local_var_value = match local_var_apikey.prefix {
273            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
274            None => local_var_key,
275        };
276        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
277    };
278
279    let local_var_req = local_var_req_builder.build()?;
280    let local_var_resp = local_var_client.execute(local_var_req).await?;
281
282    let local_var_status = local_var_resp.status();
283    let local_var_content = local_var_resp.text().await?;
284
285    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
286        Ok(())
287    } else {
288        let local_var_entity: Option<ReadNotificationError> = serde_json::from_str(&local_var_content).ok();
289        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
290        Err(Error::ResponseError(local_var_error))
291    }
292}
293
294pub async fn read_notifications(configuration: &configuration::Configuration, ids: &str) -> Result<(), Error<ReadNotificationsError>> {
295    let local_var_configuration = configuration;
296
297    let local_var_client = &local_var_configuration.client;
298
299    let local_var_uri_str = format!("{}/notifications", local_var_configuration.base_path);
300    let mut local_var_req_builder = local_var_client.request(reqwest::Method::PATCH, local_var_uri_str.as_str());
301
302    local_var_req_builder = local_var_req_builder.query(&[("ids", &ids.to_string())]);
303    if let Some(ref local_var_user_agent) = local_var_configuration.user_agent {
304        local_var_req_builder = local_var_req_builder.header(reqwest::header::USER_AGENT, local_var_user_agent.clone());
305    }
306    if let Some(ref local_var_apikey) = local_var_configuration.api_key {
307        let local_var_key = local_var_apikey.key.clone();
308        let local_var_value = match local_var_apikey.prefix {
309            Some(ref local_var_prefix) => format!("{} {}", local_var_prefix, local_var_key),
310            None => local_var_key,
311        };
312        local_var_req_builder = local_var_req_builder.header("Authorization", local_var_value);
313    };
314
315    let local_var_req = local_var_req_builder.build()?;
316    let local_var_resp = local_var_client.execute(local_var_req).await?;
317
318    let local_var_status = local_var_resp.status();
319    let local_var_content = local_var_resp.text().await?;
320
321    if !local_var_status.is_client_error() && !local_var_status.is_server_error() {
322        Ok(())
323    } else {
324        let local_var_entity: Option<ReadNotificationsError> = serde_json::from_str(&local_var_content).ok();
325        let local_var_error = ResponseContent { status: local_var_status, content: local_var_content, entity: local_var_entity };
326        Err(Error::ResponseError(local_var_error))
327    }
328}
329