Skip to content

Commit e64f510

Browse files
committed
created the verify_custom_api endpoint
1 parent 4063ddf commit e64f510

File tree

10 files changed

+95
-0
lines changed

10 files changed

+95
-0
lines changed

src/endpoints/admin/balance/create_balance.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ pub async fn handler(
7272
discord_guild_id: None,
7373
quiz_name: None,
7474
contracts: Some(parsed_contracts),
75+
api_url: None,
76+
regex: None,
7577
};
7678

7779
// insert document to boost collection

src/endpoints/admin/custom/create_custom.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub async fn handler(
6363
discord_guild_id: None,
6464
quiz_name: None,
6565
contracts: None,
66+
api_url: None,
67+
regex: None,
6668
};
6769

6870
// insert document to boost collection

src/endpoints/admin/discord/create_discord.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ pub async fn handler(
6262
quiz_name: None,
6363
verify_redirect: None,
6464
contracts: None,
65+
api_url: None,
66+
regex: None,
6567
};
6668

6769
// insert document to boost collection

src/endpoints/admin/domain/create_domain.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ pub async fn handler(
5959
quiz_name: None,
6060
verify_redirect: None,
6161
contracts: None,
62+
api_url: None,
63+
regex: None,
6264
};
6365

6466
// insert document to boost collection

src/endpoints/admin/quiz/create_quiz.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ pub async fn handler(
9090
discord_guild_id: None,
9191
verify_redirect: None,
9292
contracts: None,
93+
api_url: None,
94+
regex: None,
9395
};
9496

9597
return match tasks_collection.insert_one(new_document, None).await {

src/endpoints/admin/twitter/create_twitter_fw.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ pub async fn handler(
6363
discord_guild_id: None,
6464
quiz_name: None,
6565
contracts: None,
66+
api_url: None,
67+
regex: None,
6668
};
6769

6870
// insert document to boost collection

src/endpoints/admin/twitter/create_twitter_rw.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ pub async fn handler(
6161
discord_guild_id: None,
6262
quiz_name: None,
6363
contracts: None,
64+
api_url: None,
65+
regex: None,
6466
};
6567

6668
// insert document to boost collection

src/endpoints/quests/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub mod starknet;
1010
pub mod starknetid;
1111
pub mod uri;
1212
pub mod verify_balance;
13+
pub mod verify_custom_api;
1314
pub mod verify_quiz;
1415
pub mod verify_twitter_fw;
1516
pub mod verify_twitter_rw;
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use std::{sync::Arc, str::FromStr};
2+
use crate::{
3+
models::{AppState, QuestTaskDocument},
4+
utils::{get_error, CompletedTasksTrait},
5+
};
6+
use axum::{
7+
extract::{Query, State},
8+
http::StatusCode,
9+
response::IntoResponse,
10+
Json,
11+
};
12+
use axum_auto_routes::route;
13+
use mongodb::bson::doc;
14+
use serde::{Deserialize, Serialize};
15+
use serde_json::json;
16+
use regex::Regex;
17+
use reqwest::get;
18+
use starknet::core::types::FieldElement;
19+
20+
#[derive(Debug, Serialize, Deserialize, Default)]
21+
pub struct VerifyCustomApiQuery {
22+
pub addr: String,
23+
pub task_id: u32,
24+
}
25+
26+
#[route(get, "/quests/verify_custom_api")]
27+
pub async fn handler(
28+
State(state): State<Arc<AppState>>,
29+
Query(query): Query<VerifyCustomApiQuery>,
30+
) -> impl IntoResponse {
31+
let task_id = query.task_id;
32+
33+
// Get task in db
34+
let task_collection = state.db.collection("tasks");
35+
let task: QuestTaskDocument = task_collection
36+
.find_one(doc! {"id": task_id}, None)
37+
.await
38+
.unwrap()
39+
.unwrap();
40+
41+
// Check if the task type is "custom_api"
42+
if task.task_type != Some("custom_api".to_string()) {
43+
return get_error("Invalid task type.".to_string());
44+
}
45+
46+
// Check if the task has the required fields (api_url and regex)
47+
let api_url = match &task.api_url {
48+
Some(url) => url,
49+
None => return get_error("API URL not found.".to_string()),
50+
};
51+
52+
let regex_str = match &task.regex {
53+
Some(rgx) => rgx,
54+
None => return get_error("Regex not found.".to_string()),
55+
};
56+
57+
// Call the specified API
58+
let response = get(api_url).await;
59+
60+
match response {
61+
Ok(res) => {
62+
let res_text = res.text().await.unwrap();
63+
64+
// Check response against the regex
65+
let re = Regex::new(regex_str).unwrap();
66+
if re.is_match(&res_text) {
67+
// Mark the task as completed
68+
match state.upsert_completed_task(FieldElement::from_str(&query.addr).unwrap(), task_id).await {
69+
Ok(_) => (StatusCode::OK, Json(json!({"res": true}))).into_response(),
70+
Err(e) => get_error(format!("{}", e)),
71+
}
72+
} else {
73+
get_error("Response did not match the required pattern.".to_string())
74+
}
75+
}
76+
Err(e) => get_error(format!("Failed to fetch API: {}", e)),
77+
}
78+
}

src/models.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ pub struct QuestTaskDocument {
118118
pub verify_endpoint: String,
119119
pub href: String,
120120
pub verify_endpoint_type: String,
121+
pub api_url: Option<String>,
122+
pub regex: Option<String>,
121123
#[serde(default)]
122124
pub verify_redirect: Option<String>,
123125
#[serde(default)]

0 commit comments

Comments
 (0)