asimov_apify_module/
api.rs1use core::error::Error;
4
5use asimov_module::prelude::{Box, format, Result, String};
6pub use asimov_module::secrecy::{ExposeSecret, SecretString};
7use serde::Serialize;
8
9pub use google::*;
10pub use instagram::*;
11pub use linkedin::*;
12pub use twitter::*;
13
14mod google;
15mod twitter;
16mod linkedin;
17mod instagram;
18
19const GOOGLE_SEARCH_ACTOR: &str = "apify~google-search-scraper";
20const X_FOLLOWS_ACTOR: &str = "C2Wk3I6xAqC4Xi63f";
21const LINKEDIN_PROFILE_ACTOR: &str = "VhxlqQXRwhW8H5hNV";
22const INSTAGRAM_PROFILE_ACTOR: &str = "dSCLg0C3YEZ83HzYX";
23
24#[derive(Debug)]
26pub struct Apify {
27 pub(crate) api_key: SecretString,
28}
29
30impl Apify {
31 pub fn new(api_key: SecretString) -> Result<Self, Box<dyn Error>> {
34 if api_key.expose_secret().is_empty() {
35 return Err("Invalid API key".into());
36 }
37 Ok(Self { api_key })
38 }
39
40 fn make_request<T: Serialize>(
42 &self,
43 actor: &str,
44 request: &T,
45 ) -> Result<String, Box<dyn Error>> {
46 let url = format!("https://api.apify.com/v2/acts/{}/run-sync-get-dataset-items", actor);
49 let mut response = ureq::post(&url)
50 .header(
51 "Authorization",
52 format!("Bearer {}", self.api_key.expose_secret()),
53 )
54 .send_json(request)?;
55 let response_body = response.body_mut().read_to_string()?;
56 Ok(response_body)
57 }
58
59 pub fn google_search(&self, request: &GoogleSearchRequest) -> Result<String, Box<dyn Error>> {
62 self.make_request(GOOGLE_SEARCH_ACTOR, request)
63 }
64
65 pub fn x_follows(
68 &self,
69 request: &TwitterFollowingScrapeRequest,
70 ) -> Result<String, Box<dyn Error>> {
71 self.make_request(X_FOLLOWS_ACTOR, request)
72 }
73
74 pub fn linkedin_profile(
77 &self,
78 request: &LinkedInProfileScrapeRequest,
79 ) -> Result<String, Box<dyn Error>> {
80 self.make_request(LINKEDIN_PROFILE_ACTOR, request)
81 }
82
83 pub fn instagram_profile(
86 &self,
87 request: &InstagramProfileScrapeRequest,
88 ) -> Result<String, Box<dyn Error>> {
89 self.make_request(INSTAGRAM_PROFILE_ACTOR, request)
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn test_invalid_api_key() {
99 let result = Apify::new(SecretString::from(""));
100 assert!(result.is_err());
101 }
102}