@8ms/helpers 1.24.0 → 1.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,26 @@
1
+ type BuildGoogleSerpUrl = {
2
+ country?: string;
3
+ device?: "mobile" | "android" | "androidTablet" | "iphone" | "ipad";
4
+ language?: string;
5
+ geoLocation?: string;
6
+ hotel?: {
7
+ dates?: string;
8
+ occupancy?: number;
9
+ };
10
+ pagination?: {
11
+ offset?: number;
12
+ perPage?: number;
13
+ };
14
+ searchType?: "images" | "jobs" | "news" | "shopping";
15
+ query: string;
16
+ googleDomain: string;
17
+ };
18
+ /**
19
+ * Construct the Google SERP url using Bright Data's API:
20
+ * https://brightdata.com/cp/serp_api/api/google/search?id=c_2cef083f
21
+ *
22
+ * For geolocation use value from:
23
+ * https://developers.google.com/google-ads/api/data/geotargets
24
+ */
25
+ declare const buildGoogleSerpUrl: (props: BuildGoogleSerpUrl) => string;
26
+ export default buildGoogleSerpUrl;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Construct the Google SERP url using Bright Data's API:
5
+ * https://brightdata.com/cp/serp_api/api/google/search?id=c_2cef083f
6
+ *
7
+ * For geolocation use value from:
8
+ * https://developers.google.com/google-ads/api/data/geotargets
9
+ */
10
+ const buildGoogleSerpUrl = (props) => {
11
+ let url = new URL(`https://www${props.googleDomain}/`);
12
+ url.searchParams.append("q", props.query);
13
+ // Two-letter country code used to define the country of search
14
+ if (props?.country) {
15
+ url.searchParams.append("gl", props.country);
16
+ }
17
+ // Define what device type to be represented in user-agent - Default desktop
18
+ switch (props?.device) {
19
+ case "mobile":
20
+ url.searchParams.append("brd_mobile", "1");
21
+ break;
22
+ case "android":
23
+ url.searchParams.append("brd_mobile", "android");
24
+ break;
25
+ case "androidTablet":
26
+ url.searchParams.append("brd_mobile", "android_tablet");
27
+ break;
28
+ case "ipad":
29
+ url.searchParams.append("brd_mobile", "ipad");
30
+ break;
31
+ case "iphone":
32
+ url.searchParams.append("brd_mobile", "ios");
33
+ break;
34
+ }
35
+ // Stands for the encoded location you want to use for your search
36
+ if (props?.geoLocation) {
37
+ url.searchParams.append("uule", props.country);
38
+ }
39
+ if (props?.hotel) {
40
+ if (props.hotel?.dates) {
41
+ url.searchParams.append("hotel_dates", props.hotel.dates);
42
+ }
43
+ if (props.hotel?.occupancy) {
44
+ url.searchParams.append("hotel_occupancy", props.hotel.occupancy.toString());
45
+ }
46
+ }
47
+ // Two-letter language code used to define the page language
48
+ if (props?.language) {
49
+ url.searchParams.append("hl", props.language);
50
+ }
51
+ // Define search type. For regular search
52
+ switch (props?.searchType) {
53
+ case "images":
54
+ url.searchParams.append("tbm", "isch");
55
+ break;
56
+ case "jobs":
57
+ url.searchParams.append("ibp", "htl;jobs");
58
+ break;
59
+ case "news":
60
+ url.searchParams.append("tbm", "shop");
61
+ break;
62
+ case "shopping":
63
+ url.searchParams.append("tbm", "nws");
64
+ break;
65
+ }
66
+ if (props?.pagination) {
67
+ // Define the result offset
68
+ if (props.pagination?.offset) {
69
+ url.searchParams.append("start", props.pagination.offset.toString());
70
+ }
71
+ // Defines the number of results to return
72
+ if (props.pagination?.perPage) {
73
+ url.searchParams.append("num", props.pagination.perPage.toString());
74
+ }
75
+ }
76
+ // Always return the JSON response with HTML field
77
+ url.searchParams.append("brn_json", "html");
78
+ return url.toString();
79
+ };
80
+ exports.default = buildGoogleSerpUrl;
@@ -0,0 +1,17 @@
1
+ type BuildGoogleTrendsUrl = {
2
+ country?: string;
3
+ language?: string;
4
+ category?: string;
5
+ date?: string;
6
+ searchType?: "images" | "news" | "shopping" | "youtube";
7
+ query: string;
8
+ };
9
+ /**
10
+ * Construct the Google Trends url using Bright Data's API:
11
+ * https://brightdata.com/cp/serp_api/api/google/trends?id=c_2cef083f
12
+ *
13
+ * For category use value from:
14
+ * https://trends.google.com/trends/api/explore/pickers/category?lang=en-US&tz=240
15
+ */
16
+ declare const buildGoogleTrendsUrl: (props: BuildGoogleTrendsUrl) => string;
17
+ export default buildGoogleTrendsUrl;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Construct the Google Trends url using Bright Data's API:
5
+ * https://brightdata.com/cp/serp_api/api/google/trends?id=c_2cef083f
6
+ *
7
+ * For category use value from:
8
+ * https://trends.google.com/trends/api/explore/pickers/category?lang=en-US&tz=240
9
+ */
10
+ const buildGoogleTrendsUrl = (props) => {
11
+ let url = new URL(`http://trends.google.com/trends/explore`);
12
+ url.searchParams.append("q", props.query);
13
+ // Location of interest, two-letter country code
14
+ if (props?.country) {
15
+ url.searchParams.append("geo", props.country);
16
+ }
17
+ // Preferred language, two-letter language code
18
+ if (props?.language) {
19
+ url.searchParams.append("hl", props.country);
20
+ }
21
+ if (props?.category) {
22
+ url.searchParams.append("cat", props.category);
23
+ }
24
+ if (props?.date) {
25
+ url.searchParams.append("date", props.date);
26
+ }
27
+ // Define search type. For regular search
28
+ switch (props?.searchType) {
29
+ case "images":
30
+ url.searchParams.append("gprop", "images");
31
+ break;
32
+ case "news":
33
+ url.searchParams.append("gprop", "news");
34
+ break;
35
+ case "shopping":
36
+ url.searchParams.append("gprop", "froogle");
37
+ break;
38
+ case "youtube":
39
+ url.searchParams.append("gprop", "youtube");
40
+ break;
41
+ }
42
+ return url.toString();
43
+ };
44
+ exports.default = buildGoogleTrendsUrl;
@@ -0,0 +1,14 @@
1
+ type GetRealtime = {
2
+ auth: {
3
+ host: string;
4
+ port: string;
5
+ username: string;
6
+ password: string;
7
+ };
8
+ url: string;
9
+ };
10
+ /**
11
+ * Make a request to the SERP API using the Bright Data proxy
12
+ */
13
+ declare const getRealtime: (props: GetRealtime) => Promise<{}>;
14
+ export default getRealtime;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const get_1 = __importDefault(require("../../axios/get"));
7
+ /**
8
+ * Make a request to the SERP API using the Bright Data proxy
9
+ */
10
+ const getRealtime = async (props) => {
11
+ let response = {};
12
+ // Prevent auth requests getting blocked
13
+ process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
14
+ // Use fetch with the agent option to make an HTTP request through the proxy
15
+ // Replace <target_url> with the URL you want to request
16
+ const apiResponse = await (0, get_1.default)({
17
+ config: {
18
+ proxy: {
19
+ protocol: "http",
20
+ host: props.auth.host,
21
+ port: props.auth.port,
22
+ auth: {
23
+ username: props.auth.username,
24
+ password: props.auth.password,
25
+ }
26
+ },
27
+ },
28
+ url: props.url,
29
+ });
30
+ if (apiResponse.isSuccess()) {
31
+ response = apiResponse.getBody();
32
+ }
33
+ return response;
34
+ };
35
+ exports.default = getRealtime;
@@ -0,0 +1,12 @@
1
+ type GetBatch = {
2
+ apiKey: string;
3
+ data?: object;
4
+ scraperId: string;
5
+ };
6
+ /**
7
+ * Depends on the Scraper setup!
8
+ *
9
+ * Make the request to trigger the scraper and let it do its job.
10
+ */
11
+ declare const getBatch: (props: GetBatch) => Promise<boolean>;
12
+ export default getBatch;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const post_1 = __importDefault(require("../../axios/post"));
7
+ /**
8
+ * Depends on the Scraper setup!
9
+ *
10
+ * Make the request to trigger the scraper and let it do its job.
11
+ */
12
+ const getBatch = async (props) => {
13
+ let response = false;
14
+ const requestUrl = `https://api.brightdata.com/dca/trigger?collector=${props.scraperId}&queue_next=1`;
15
+ const requestResponse = await (0, post_1.default)({
16
+ config: {
17
+ headers: {
18
+ Authorization: `Bearer ${props.apiKey}`
19
+ },
20
+ },
21
+ data: props?.data || {},
22
+ url: requestUrl,
23
+ });
24
+ if (requestResponse.isSuccess()) {
25
+ response = true;
26
+ }
27
+ return response;
28
+ };
29
+ exports.default = getBatch;
@@ -0,0 +1,12 @@
1
+ type GetRealtime = {
2
+ apiKey: string;
3
+ data?: object;
4
+ scraperId: string;
5
+ };
6
+ /**
7
+ * Depends on the Scraper setup!
8
+ *
9
+ * Make the request and pool the response until the data is available.
10
+ */
11
+ declare const getRealtime: (props: GetRealtime) => Promise<{}>;
12
+ export default getRealtime;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const post_1 = __importDefault(require("../../axios/post"));
7
+ const states_1 = __importDefault(require("../../api/states"));
8
+ const get_1 = __importDefault(require("../../axios/get"));
9
+ const sleep_1 = __importDefault(require("../../util/sleep"));
10
+ /**
11
+ * Depends on the Scraper setup!
12
+ *
13
+ * Make the request and pool the response until the data is available.
14
+ */
15
+ const getRealtime = async (props) => {
16
+ let response = {};
17
+ const requestUrl = `https://api.brightdata.com/dca/trigger_immediate?collector=${props.scraperId}`;
18
+ const requestResponse = await (0, post_1.default)({
19
+ config: {
20
+ headers: {
21
+ Authorization: `Bearer ${props.apiKey}`
22
+ },
23
+ },
24
+ data: props?.data || {},
25
+ url: requestUrl,
26
+ });
27
+ if (requestResponse.isSuccess()) {
28
+ const responseId = requestResponse.getBodyDefaultTo({
29
+ defaultValue: "",
30
+ keys: ["response_id"],
31
+ });
32
+ if ("" !== responseId) {
33
+ let state = states_1.default.PENDING;
34
+ while (states_1.default.PENDING === state) {
35
+ const resultUrl = `https://api.brightdata.com/dca/get_result?response_id=${responseId}`;
36
+ // Use fetch with the agent option to make an HTTP request through the proxy
37
+ // Replace <target_url> with the URL you want to request
38
+ const resultResponse = await (0, get_1.default)({
39
+ config: {
40
+ headers: {
41
+ Authorization: `Bearer ${props.apiKey}`
42
+ },
43
+ },
44
+ url: resultUrl,
45
+ });
46
+ if (resultResponse.isSuccess()) {
47
+ if (undefined !== resultResponse.body.pending &&
48
+ true === resultResponse.body.pending) {
49
+ state = states_1.default.PENDING;
50
+ }
51
+ else {
52
+ state = states_1.default.SUCCESS;
53
+ response = resultResponse.getBody();
54
+ }
55
+ }
56
+ await (0, sleep_1.default)({
57
+ seconds: 1
58
+ });
59
+ }
60
+ }
61
+ }
62
+ return response;
63
+ };
64
+ exports.default = getRealtime;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@8ms/helpers",
3
3
  "license": "UNLICENSED",
4
- "version": "1.24.0",
4
+ "version": "1.26.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/8millionstories-organisation/8ms-helpers-ts.git"