diff --git a/build.gradle b/build.gradle index 2f3af03..75006a2 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'java' apply plugin: 'maven-publish' group = 'com.github.outscraper' -version = '2.1.4' +version = '2.1.5' repositories { mavenCentral() diff --git a/examples/Businesses.md b/examples/Businesses.md index fe01c09..a2e9e59 100644 --- a/examples/Businesses.md +++ b/examples/Businesses.md @@ -74,6 +74,8 @@ OutscraperClient client = new OutscraperClient("SECRET_API_KEY"); ### 1) Search with structured parameters (JSON) ```java +OutscraperClient client = new OutscraperClient("SECRET_API_KEY"); + HashMap params = new HashMap<>(); HashMap filters = new HashMap<>(); @@ -96,18 +98,28 @@ System.out.println(page); ### 2) AI-powered search (plain text) +Just put `query` into the request payload. + ```java -String query = +HashMap params = new HashMap<>(); + +params.put( + "query", "Find restaurants and cafes in California and Illinois with rating 4.2+ and status operational. " + "Return fields name, address, rating and reviews. " + - "Limit results to 15."; + "Limit results to 15." +); -JSONObject page = client.businessesSearch(new HashMap<>(), query); +JSONObject page = client.businessesSearch(params); System.out.println(page); ``` ### 3) Combine JSON + plain text (merge rules) +When both `filters/fields` and `query` are provided, the server merges them: +- `filters` and `fields` are merged +- for `limit`, `cursor`, `include_total` the plain text values have priority (if explicitly specified) + ```java HashMap params = new HashMap<>(); @@ -120,33 +132,135 @@ params.put("filters", filters); params.put("fields", new String[] {"name", "phone"}); params.put("limit", 15); -String query = +params.put( + "query", "Add cafes too. " + "Return address and reviews. " + "Limit 20. " + - "Include total."; + "Include total." +); -JSONObject page = client.businessesSearch(params, query); +JSONObject page = client.businessesSearch(params); System.out.println(page); - -// Result behavior: -// - filters merged (restaurant + cafe, plus JSON filters) -// - fields merged (name, phone, address, reviews, ...) -// - limit/include_total taken from plain text when present ``` -### 4) Iterate over all results (auto-pagination) +### 4) Search with enrichments + +`enrichments` can be provided as: +- **Object** (recommended): `{ "contacts_n_leads": {...}, "company_insights": {} }` +- **List**: `["contacts_n_leads", "company_insights"]` +- **String**: `"contacts_n_leads"` + +#### 4.1) Enrichments as object (recommended) ```java HashMap params = new HashMap<>(); + HashMap filters = new HashMap<>(); filters.put("country_code", "US"); filters.put("states", new String[] {"NY"}); -filters.put("business_statuses", new String[] {"operational"}); +filters.put("types", new String[] {"restaurant", "cafe"}); params.put("filters", filters); -params.put("limit", 100); +params.put("limit", 10); +params.put("fields", new String[] {"name", "phone"}); + +// enrichments object +HashMap enrichments = new HashMap<>(); + +HashMap contacts = new HashMap<>(); +contacts.put("contacts_per_company", 4); +contacts.put("emails_per_contact", 2); + +enrichments.put("contacts_n_leads", contacts); +enrichments.put("company_insights", new HashMap<>()); + +params.put("enrichments", enrichments); + +JSONObject page = client.businessesSearch(params); +System.out.println(page); +``` + +#### 4.2) Enrichments as list + +```java +HashMap params = new HashMap<>(); +params.put("filters", new HashMap() {{ + put("country_code", "US"); + put("states", new String[] {"NY"}); +}}); +params.put("limit", 10); +params.put("enrichments", new String[] {"contacts_n_leads", "company_insights"}); + +JSONObject page = client.businessesSearch(params); +System.out.println(page); +``` + +#### 4.3) Enrichments as single string + +```java +HashMap params = new HashMap<>(); +params.put("filters", new HashMap() {{ + put("country_code", "US"); + put("states", new String[] {"NY"}); +}}); +params.put("limit", 10); +params.put("enrichments", "contacts_n_leads"); + +JSONObject page = client.businessesSearch(params); +System.out.println(page); +``` + +#### 4.4) Full JSON-style payload (filters + fields + enrichments + query) + +This is equivalent to the JSON payload you described: + +```java +HashMap params = new HashMap<>(); -JSONArray all = client.businessesIterSearch(params); +params.put("filters", new HashMap() {{ + put("country_code", "US"); + put("states", new String[] {"CA", "NY"}); + put("types", new String[] {"restaurant", "cafe"}); +}}); +params.put("limit", 900); +params.put("cursor", null); +params.put("include_total", false); +params.put("fields", new String[] { + "name", "types", "address", "country", "website", "phone", "rating", "reviews" +}); + +// enrichments dict +params.put("enrichments", new HashMap() {{ + put("contacts_n_leads", new HashMap() {{ + put("contacts_per_company", 4); + put("emails_per_contact", 2); + }}); + put("company_insights", new HashMap()); +}}); + +params.put( + "query", + "Find hotels in California and Illinois with rating 4.2+ and status operational. " + + "Return fields: name, address, rating and reviews. " + + "Limit results to 6. " + + "Enrich data with contacts_n_leads. Contact per company set to 8" +); + +JSONObject page = client.businessesSearch(params); +System.out.println(page); +``` + +### 5) Iterate over all results (auto-pagination) + +```java +HashMap filters = new HashMap<>(); +filters.put("country_code", "US"); +filters.put("states", new String[] {"NY"}); +filters.put("business_statuses", new String[] {"operational"}); + +// Using the convenience overload (query/enrichments are optional) +JSONArray all = client.businessesIterSearch(filters, 100, new String[] {"name", "phone"}, false, null, null); System.out.println(all.length()); -``` \ No newline at end of file +``` + diff --git a/src/main/java/OutscraperClient.java b/src/main/java/OutscraperClient.java index 4508ca1..ccc9512 100644 --- a/src/main/java/OutscraperClient.java +++ b/src/main/java/OutscraperClient.java @@ -380,6 +380,50 @@ public JSONObject businessesSearch(HashMap parameters) { return response; } + /** + * Convenience overload for /businesses search with explicit parameters. + * + * @param filters Map of filters (will be sent as "filters") + * @param limit Page size + * @param includeTotal Whether to include total count ("include_total") + * @param cursor Pagination cursor + * @param fields Fields to return (List or String or JSONArray) + * @param asyncRequest Whether to run request asynchronously ("async") + * @param ui Whether to enable UI mode ("ui") + * @param webhook Webhook URL (String) or null + * @param query AI plain text query or null + * @param enrichments Enrichments definition: HashMap / JSONObject / List / String / null + */ + public JSONObject businessesSearch( + HashMap filters, + int limit, + boolean includeTotal, + String cursor, + Object fields, + boolean asyncRequest, + boolean ui, + String webhook, + String query, + Object enrichments + ) { + HashMap parameters = new HashMap<>(); + parameters.put("filters", filters != null ? filters : new HashMap<>()); + parameters.put("limit", limit); + parameters.put("include_total", includeTotal); + + if (cursor != null) parameters.put("cursor", cursor); + if (fields != null) parameters.put("fields", fields); + if (query != null) parameters.put("query", query); + if (enrichments != null) parameters.put("enrichments", enrichments); + if (webhook != null) parameters.put("webhook", webhook); + + parameters.put("async", asyncRequest); + parameters.put("ui", ui); + + return businessesSearch(parameters); + } + + public JSONArray businessesIterSearch(HashMap parameters) { if (parameters == null) parameters = new HashMap<>(); @@ -428,6 +472,37 @@ public JSONArray businessesIterSearch(HashMap parameters) { return all; } + /** + * Convenience overload for /businesses iterator search (auto-pagination). + * + * @param filters Map of filters (will be sent as "filters") + * @param limit Page size + * @param fields Fields to return (List or String or JSONArray) + * @param includeTotal Whether to include total count ("include_total") + * @param query AI plain text query or null + * @param enrichments Enrichments definition: HashMap / JSONObject / List / String / null + */ + public JSONArray businessesIterSearch( + HashMap filters, + int limit, + Object fields, + boolean includeTotal, + String query, + Object enrichments + ) { + HashMap parameters = new HashMap<>(); + parameters.put("filters", filters != null ? filters : new HashMap<>()); + parameters.put("limit", limit); + parameters.put("include_total", includeTotal); + + if (fields != null) parameters.put("fields", fields); + if (query != null) parameters.put("query", query); + if (enrichments != null) parameters.put("enrichments", enrichments); + + return businessesIterSearch(parameters); + } + + public JSONObject businessesGet(String businessId, HashMap parameters) { if (businessId == null || businessId.isBlank()) { throw new IllegalArgumentException("businessId is required");