n8n-nodes-scrapeunblocker-google-maps-local 0.1.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.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ScrapeUnblocker
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,181 @@
1
+ # n8n-nodes-scrapeunblocker-google-maps-local
2
+
3
+ This is an n8n community node. It lets you search **Google Maps** for local businesses in your n8n workflows and get the places Google shows as JSON: name, category, rating, review count, price level and address.
4
+
5
+ The node runs the [Google Maps Scraper](https://apify.com/scrapeunblocker/google-maps-local-scraper) Actor by ScrapeUnblocker on the [Apify](https://apify.com) platform with **your own Apify account**, waits for the run to finish and returns every scraped record as an n8n item.
6
+
7
+ [n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/sustainable-use-license/) workflow automation platform.
8
+
9
+ [Installation](#installation)
10
+ [Credentials](#credentials)
11
+ [Operations](#operations)
12
+ [Output](#output)
13
+ [Example workflow](#example-workflow)
14
+ [Pricing](#pricing)
15
+ [Compatibility](#compatibility)
16
+ [Resources](#resources)
17
+ [Version history](#version-history)
18
+
19
+ ## Installation
20
+
21
+ Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes/installation/) in the n8n community nodes documentation. The npm package name is `n8n-nodes-scrapeunblocker-google-maps-local`.
22
+
23
+ ## Credentials
24
+
25
+ The node authenticates with an **Apify API token**. Every run starts on the Apify account that owns the token and is billed to that account (see [Pricing](#pricing)).
26
+
27
+ ### 1. Create an Apify account (skip if you already have one)
28
+
29
+ 1. Go to [console.apify.com/sign-up](https://console.apify.com/sign-up) and sign up with email, Google or GitHub.
30
+ 2. Confirm your email address if Apify asks you to.
31
+
32
+ The free Apify plan needs no credit card and includes a monthly usage credit, which is enough to try the node. Current plan limits are listed on [apify.com/pricing](https://apify.com/pricing).
33
+
34
+ ### 2. Get your API token
35
+
36
+ 1. Open [Apify Console](https://console.apify.com) and go to **Settings** → **API & Integrations**, or open [console.apify.com/settings/integrations](https://console.apify.com/settings/integrations) directly.
37
+ 2. Find the **Personal API tokens** section.
38
+ 3. Either use the existing token (the one marked *Default API token created on sign up*): click the eye icon to reveal it or the copy icon to copy it.
39
+ 4. Or create a dedicated token for n8n (recommended, so you can revoke it without affecting anything else):
40
+ 1. Click **+ Add new token** (the button may read **Create new token**).
41
+ 2. In the **Create a new personal API token** dialog, enter a **Description** such as `n8n`.
42
+ 3. Optionally switch on **Set expiration date** and pick a date.
43
+ 4. Leave **Limit token permissions** switched off. A token with limited permissions may not be allowed to run this Actor or read its results.
44
+ 5. Click **Create** and copy the new token.
45
+
46
+ The token starts with `apify_api_`. Treat it like a password: anyone who has it can run Actors on your account. You can revoke or rotate it on the same page at any time.
47
+
48
+ > Working in an Apify **organization**? Switch to the organization in Apify Console first and copy a token from its **API & Integrations** page, so runs are billed to the organization.
49
+
50
+ ### 3. Add the credential in n8n
51
+
52
+ 1. Add the **Google Maps Scraper** node to a workflow and open it.
53
+ 2. In **Credential to connect with**, choose **Create new credential**. (You can also create an **Apify API** credential from the n8n credentials list.)
54
+ 3. Paste the token into **API Key** and click **Save**. n8n checks the token right away; an invalid token shows *Authorization failed - please check your credentials*.
55
+
56
+ Already have an **Apify API** credential in n8n (for example from the official Apify node)? This node uses the same credential type, so you can simply select it.
57
+
58
+ ## Operations
59
+
60
+ Pick a **Resource** and an **Operation**. Each n8n input item starts one Apify run. List fields accept several values separated by commas or new lines, or an array returned by an expression.
61
+
62
+ | Resource | Operation | Fields | Returns |
63
+ |---|---|---|---|
64
+ | **Place** | Search | **Search Query** (required) - The local search phrase, e.g. 'coffee shops in Austin' or 'dentists in Berlin'. Include the location for best results | One item per place, about 20 per search |
65
+
66
+ ### Options
67
+
68
+ | Option | Description |
69
+ |---|---|
70
+ | **Language** | Google interface language as an ISO code, e.g. en, de or fr. It affects labels and formatting. |
71
+ | **Proxy Country** | Exit-IP country (ISO-2, e.g. US). Leave empty to pick one for the query. |
72
+ | **Search From Country** | Country to run the search from as a lowercase ISO-2 code, e.g. us, de or gb. It changes which local results Google shows. |
73
+ | **Timeout (Seconds)** | Maximum run time of the Apify run. `0` keeps the Actor default. A run that times out fails the node. |
74
+
75
+ ### How a run works
76
+
77
+ 1. The node starts the Actor on your Apify account with the fields you set.
78
+ 2. It waits for the run to finish.
79
+ 3. It returns every record from the run's dataset as a separate n8n item.
80
+
81
+ The run is also visible in Apify Console under **Runs**. If a run fails or times out, the node error links to the run log and tells you whether any results were saved before it stopped.
82
+
83
+ Stopping the n8n execution only stops the node from waiting: the Apify run keeps going and its results are still charged. To stop it, abort the run in Apify Console under **Runs**, and use **Timeout (Seconds)** to cap long runs up front.
84
+
85
+ ### Use as an AI Agent tool
86
+
87
+ The node can be attached to an n8n **AI Agent** as a tool, so the agent can call it on its own.
88
+
89
+ ## Output
90
+
91
+ - One item per place (about 20 per search), with its rank in the results, name, category, rating and review count, price level, address, a sponsored flag and a review snippet, plus phone, website and hours when Google shows them.
92
+
93
+ Fields of a returned item: `name`, `sponsored`, `rating`, `reviews`, `price`, `category`, `address`, `phone`, `website`, `hours`, `review_snippet`, `position`.
94
+
95
+ Example item (shortened):
96
+
97
+ ```json
98
+ {
99
+ "name": "Epoch Coffee",
100
+ "sponsored": false,
101
+ "rating": 4.5,
102
+ "reviews": 2500,
103
+ "price": "1–10 $",
104
+ "category": "Coffee shop",
105
+ "address": "221 W N Loop Blvd",
106
+ "phone": null,
107
+ "website": null,
108
+ "hours": null,
109
+ "review_snippet": "Great coffee , friendly people, classic Austin hospitality.",
110
+ "position": 1
111
+ }
112
+ ```
113
+
114
+ ## Example workflow
115
+
116
+ To try the node in a minute, copy the workflow below, paste it into the n8n editor (Ctrl+V / Cmd+V), open the **Google Maps Scraper** node, select your **Apify API** credential and click **Execute workflow**.
117
+
118
+ ```json
119
+ {
120
+ "nodes": [
121
+ {
122
+ "parameters": {},
123
+ "name": "When clicking 'Execute workflow'",
124
+ "type": "n8n-nodes-base.manualTrigger",
125
+ "typeVersion": 1,
126
+ "position": [
127
+ 0,
128
+ 0
129
+ ]
130
+ },
131
+ {
132
+ "parameters": {
133
+ "resource": "place",
134
+ "operation": "search",
135
+ "keyword": "coffee shops in Austin",
136
+ "options": {}
137
+ },
138
+ "name": "Google Maps Scraper",
139
+ "type": "n8n-nodes-scrapeunblocker-google-maps-local.googleMapsScraper",
140
+ "typeVersion": 1,
141
+ "position": [
142
+ 220,
143
+ 0
144
+ ]
145
+ }
146
+ ],
147
+ "connections": {
148
+ "When clicking 'Execute workflow'": {
149
+ "main": [
150
+ [
151
+ {
152
+ "node": "Google Maps Scraper",
153
+ "type": "main",
154
+ "index": 0
155
+ }
156
+ ]
157
+ ]
158
+ }
159
+ }
160
+ }
161
+ ```
162
+
163
+ ## Pricing
164
+
165
+ The node itself is free. The Actor is paid per result on Apify: **$0.80 per 1,000 places** plus a tiny start fee per run ($0.00005), charged to the Apify account of your token. Every item the node returns counts as one result. The current price is always shown on the [Actor page](https://apify.com/scrapeunblocker/google-maps-local-scraper), and your spending is visible in Apify Console.
166
+
167
+ ## Compatibility
168
+
169
+ Tested with n8n 2.40 (self-hosted).
170
+
171
+ ## Resources
172
+
173
+ - [Google Maps Scraper Actor on Apify](https://apify.com/scrapeunblocker/google-maps-local-scraper)
174
+ - [Apify API tokens documentation](https://docs.apify.com/platform/integrations/api#api-token)
175
+ - [n8n community nodes documentation](https://docs.n8n.io/integrations/#community-nodes)
176
+ - [ScrapeUnblocker](https://www.scrapeunblocker.com/?utm_source=n8n&utm_medium=integration&utm_campaign=n8n-google-maps-local-node) - the anti-bot scraping API behind the Actor
177
+
178
+ ## Version history
179
+
180
+ - 0.1.0: Initial release
181
+ - 0.1.1: First release published from GitHub Actions with an npm provenance statement
@@ -0,0 +1,10 @@
1
+ import type { IAuthenticateGeneric, Icon, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class ApifyApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ icon: Icon;
6
+ documentationUrl: string;
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApifyApi = void 0;
4
+ class ApifyApi {
5
+ constructor() {
6
+ this.name = 'apifyApi';
7
+ this.displayName = 'Apify API';
8
+ this.icon = { light: 'file:apify.svg', dark: 'file:apify.dark.svg' };
9
+ this.documentationUrl = 'https://github.com/ScrapeUnblocker/n8n-nodes-scrapeunblocker-google-maps-local#credentials';
10
+ this.properties = [
11
+ {
12
+ displayName: 'Runs are billed to this Apify account at the Actor\'s pay-per-result price. Get your token in Apify Console under <a href="https://console.apify.com/settings/integrations" target="_blank">Settings → API &amp; Integrations</a>. No Apify account yet? <a href="https://console.apify.com/sign-up" target="_blank">Sign up for free</a>.',
13
+ name: 'notice',
14
+ type: 'notice',
15
+ default: '',
16
+ },
17
+ {
18
+ displayName: 'API Key',
19
+ name: 'apiKey',
20
+ type: 'string',
21
+ typeOptions: { password: true },
22
+ required: true,
23
+ default: '',
24
+ description: 'Your Apify API token (starts with "apify_api_")',
25
+ },
26
+ ];
27
+ this.authenticate = {
28
+ type: 'generic',
29
+ properties: {
30
+ headers: {
31
+ Authorization: '=Bearer {{$credentials.apiKey}}',
32
+ },
33
+ },
34
+ };
35
+ this.test = {
36
+ request: {
37
+ baseURL: 'https://api.apify.com',
38
+ url: '/v2/users/me',
39
+ },
40
+ };
41
+ }
42
+ }
43
+ exports.ApifyApi = ApifyApi;
44
+ //# sourceMappingURL=ApifyApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApifyApi.credentials.js","sourceRoot":"","sources":["../../credentials/ApifyApi.credentials.ts"],"names":[],"mappings":";;;AAUA,MAAa,QAAQ;IAArB;QACC,SAAI,GAAG,UAAU,CAAC;QAElB,gBAAW,GAAG,WAAW,CAAC;QAE1B,SAAI,GAAS,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC;QAEtE,qBAAgB,GACf,4FAA4F,CAAC;QAE9F,eAAU,GAAsB;YAC/B;gBACC,WAAW,EACV,4UAA4U;gBAC7U,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,EAAE;aACX;YACD;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,iDAAiD;aAC9D;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,aAAa,EAAE,iCAAiC;iBAChD;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,uBAAuB;gBAChC,GAAG,EAAE,cAAc;aACnB;SACD,CAAC;IACH,CAAC;CAAA;AA5CD,4BA4CC"}
@@ -0,0 +1,5 @@
1
+ <svg width="150" height="150" viewBox="0 0 150 150" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M86.0214 0H147.727C148.982 0 150 1.01753 150 2.27273V96.5744C150 98.8332 147.062 99.7089 145.826 97.8188L84.1196 3.51714C83.1305 2.00559 84.215 0 86.0214 0Z" fill="#246DFF"/>
3
+ <path d="M63.9786 0H2.27273C1.01753 0 0 1.01753 0 2.27273V96.5744C0 98.8332 2.93774 99.7089 4.1745 97.8188L65.8804 3.51714C66.8695 2.00559 65.785 0 63.9786 0Z" fill="#20A34E"/>
4
+ <path d="M73.9429 75.5012L3.84485 146.126C2.42137 147.56 3.43724 150 5.45792 150H144.6C146.612 150 147.632 147.578 146.225 146.139L77.1811 75.5135C76.2942 74.6063 74.8365 74.6008 73.9429 75.5012Z" fill="#F86606"/>
5
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg width="150" height="150" viewBox="0 0 150 150" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M86.0214 0H147.727C148.982 0 150 1.01753 150 2.27273V96.5744C150 98.8332 147.062 99.7089 145.826 97.8188L84.1196 3.51714C83.1305 2.00559 84.215 0 86.0214 0Z" fill="#246DFF"/>
3
+ <path d="M63.9786 0H2.27273C1.01753 0 0 1.01753 0 2.27273V96.5744C0 98.8332 2.93774 99.7089 4.1745 97.8188L65.8804 3.51714C66.8695 2.00559 65.785 0 63.9786 0Z" fill="#20A34E"/>
4
+ <path d="M73.9429 75.5012L3.84485 146.126C2.42137 147.56 3.43724 150 5.45792 150H144.6C146.612 150 147.632 147.578 146.225 146.139L77.1811 75.5135C76.2942 74.6063 74.8365 74.6008 73.9429 75.5012Z" fill="#F86606"/>
5
+ </svg>
@@ -0,0 +1,32 @@
1
+ import type { IDataObject, IExecuteFunctions, IHttpRequestMethods } from 'n8n-workflow';
2
+ export interface ApifyRequest {
3
+ method: IHttpRequestMethods;
4
+ endpoint: string;
5
+ integrationAppId: string;
6
+ body?: IDataObject;
7
+ qs?: IDataObject;
8
+ timeout?: number;
9
+ abortSignal?: AbortSignal;
10
+ }
11
+ export interface ActorRunOptions {
12
+ actorId: string;
13
+ integrationAppId: string;
14
+ input: IDataObject;
15
+ itemIndex: number;
16
+ timeoutSecs?: number;
17
+ }
18
+ export interface ActorRunResult {
19
+ run: IDataObject;
20
+ items: IDataObject[];
21
+ }
22
+ export declare function apifyApiRequest(this: IExecuteFunctions, request: ApifyRequest): Promise<IDataObject | IDataObject[]>;
23
+ export declare function parseList(value: unknown, separator?: RegExp): string[];
24
+ export type OptionKind = 'value' | 'list' | 'newlineList' | 'upper' | 'nonZero';
25
+ export interface OptionField {
26
+ key: string;
27
+ kind?: OptionKind;
28
+ }
29
+ export declare function requireString(this: IExecuteFunctions, parameterName: string, displayName: string, itemIndex: number): string;
30
+ export declare function requireList(this: IExecuteFunctions, parameterName: string, displayName: string, itemIndex: number, newlineOnly?: boolean): string[];
31
+ export declare function applyOptions(input: IDataObject, options: IDataObject, fields: Record<string, OptionField>): void;
32
+ export declare function runActorAndGetItems(this: IExecuteFunctions, options: ActorRunOptions): Promise<ActorRunResult>;
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.apifyApiRequest = apifyApiRequest;
4
+ exports.parseList = parseList;
5
+ exports.requireString = requireString;
6
+ exports.requireList = requireList;
7
+ exports.applyOptions = applyOptions;
8
+ exports.runActorAndGetItems = runActorAndGetItems;
9
+ const n8n_workflow_1 = require("n8n-workflow");
10
+ const APIFY_API_URL = 'https://api.apify.com';
11
+ const WAIT_FOR_FINISH_SECS = 60;
12
+ const LONG_POLL_TIMEOUT_MS = (WAIT_FOR_FINISH_SECS + 30) * 1000;
13
+ const MIN_POLL_INTERVAL_MS = 2000;
14
+ const DATASET_PAGE_SIZE = 1000;
15
+ const TERMINAL_STATUSES = ['SUCCEEDED', 'FAILED', 'TIMED-OUT', 'ABORTED'];
16
+ async function apifyApiRequest(request) {
17
+ const options = {
18
+ method: request.method,
19
+ url: `${APIFY_API_URL}${request.endpoint}`,
20
+ headers: {
21
+ 'x-apify-integration-platform': 'n8n',
22
+ 'x-apify-integration-app-id': request.integrationAppId,
23
+ },
24
+ qs: request.qs,
25
+ json: true,
26
+ timeout: request.timeout,
27
+ abortSignal: request.abortSignal,
28
+ };
29
+ if (request.body !== undefined) {
30
+ options.body = request.body;
31
+ }
32
+ try {
33
+ return (await this.helpers.httpRequestWithAuthentication.call(this, 'apifyApi', options));
34
+ }
35
+ catch (error) {
36
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
37
+ }
38
+ }
39
+ function parseList(value, separator = /[\n,]+/) {
40
+ const parts = Array.isArray(value) ? value.map(String) : String(value !== null && value !== void 0 ? value : '').split(separator);
41
+ return parts.map((part) => part.trim()).filter((part) => part !== '');
42
+ }
43
+ const NEWLINE_SEPARATOR = /\n+/;
44
+ function requireString(parameterName, displayName, itemIndex) {
45
+ var _a;
46
+ const value = String((_a = this.getNodeParameter(parameterName, itemIndex)) !== null && _a !== void 0 ? _a : '').trim();
47
+ if (value === '') {
48
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Enter a value for "${displayName}"`, {
49
+ itemIndex,
50
+ });
51
+ }
52
+ return value;
53
+ }
54
+ function requireList(parameterName, displayName, itemIndex, newlineOnly = false) {
55
+ const list = parseList(this.getNodeParameter(parameterName, itemIndex), newlineOnly ? NEWLINE_SEPARATOR : undefined);
56
+ if (list.length === 0) {
57
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Enter at least one value for "${displayName}"`, {
58
+ itemIndex,
59
+ });
60
+ }
61
+ return list;
62
+ }
63
+ function applyOptions(input, options, fields) {
64
+ for (const [name, value] of Object.entries(options)) {
65
+ const field = fields[name];
66
+ if (!field || value === undefined || value === null || value === '') {
67
+ continue;
68
+ }
69
+ switch (field.kind) {
70
+ case 'list':
71
+ case 'newlineList': {
72
+ const list = parseList(value, field.kind === 'newlineList' ? NEWLINE_SEPARATOR : undefined);
73
+ if (list.length > 0) {
74
+ input[field.key] = list;
75
+ }
76
+ break;
77
+ }
78
+ case 'upper':
79
+ input[field.key] = String(value).trim().toUpperCase();
80
+ break;
81
+ case 'nonZero':
82
+ if (Number(value) !== 0) {
83
+ input[field.key] = value;
84
+ }
85
+ break;
86
+ default:
87
+ input[field.key] = typeof value === 'string' ? value.trim() : value;
88
+ }
89
+ }
90
+ }
91
+ async function getDatasetItems(datasetId, integrationAppId) {
92
+ const items = [];
93
+ for (let offset = 0;; offset += DATASET_PAGE_SIZE) {
94
+ const page = (await apifyApiRequest.call(this, {
95
+ method: 'GET',
96
+ endpoint: `/v2/datasets/${datasetId}/items`,
97
+ integrationAppId,
98
+ qs: { clean: true, format: 'json', offset, limit: DATASET_PAGE_SIZE },
99
+ }));
100
+ items.push(...page);
101
+ if (page.length < DATASET_PAGE_SIZE) {
102
+ return items;
103
+ }
104
+ }
105
+ }
106
+ async function describeSavedResults(datasetId, integrationAppId) {
107
+ var _a, _b;
108
+ try {
109
+ const dataset = (await apifyApiRequest.call(this, {
110
+ method: 'GET',
111
+ endpoint: `/v2/datasets/${datasetId}`,
112
+ integrationAppId,
113
+ }));
114
+ const itemCount = Number((_b = (_a = dataset.data) === null || _a === void 0 ? void 0 : _a.itemCount) !== null && _b !== void 0 ? _b : 0);
115
+ if (itemCount > 0) {
116
+ return ` ${itemCount} result(s) saved before the run stopped are in its dataset: https://console.apify.com/storage/datasets/${datasetId}`;
117
+ }
118
+ }
119
+ catch {
120
+ }
121
+ return '';
122
+ }
123
+ async function runActorAndGetItems(options) {
124
+ var _a;
125
+ const { actorId, integrationAppId, input, itemIndex, timeoutSecs } = options;
126
+ const cancelSignal = (_a = this.getExecutionCancelSignal) === null || _a === void 0 ? void 0 : _a.call(this);
127
+ const startQs = { waitForFinish: WAIT_FOR_FINISH_SECS };
128
+ if (timeoutSecs) {
129
+ startQs.timeout = timeoutSecs;
130
+ }
131
+ const started = (await apifyApiRequest.call(this, {
132
+ method: 'POST',
133
+ endpoint: `/v2/acts/${actorId}/runs`,
134
+ integrationAppId,
135
+ body: input,
136
+ qs: startQs,
137
+ timeout: LONG_POLL_TIMEOUT_MS,
138
+ abortSignal: cancelSignal,
139
+ }));
140
+ let run = started.data;
141
+ const runUrl = `https://console.apify.com/view/runs/${String(run.id)}`;
142
+ while (!TERMINAL_STATUSES.includes(run.status)) {
143
+ if (cancelSignal === null || cancelSignal === void 0 ? void 0 : cancelSignal.aborted) {
144
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Execution cancelled', {
145
+ itemIndex,
146
+ description: `The Apify run keeps going. Abort it in Apify Console if you no longer need it: ${runUrl}`,
147
+ });
148
+ }
149
+ const polledAt = Date.now();
150
+ const polled = (await apifyApiRequest.call(this, {
151
+ method: 'GET',
152
+ endpoint: `/v2/actor-runs/${String(run.id)}`,
153
+ integrationAppId,
154
+ qs: { waitForFinish: WAIT_FOR_FINISH_SECS },
155
+ timeout: LONG_POLL_TIMEOUT_MS,
156
+ abortSignal: cancelSignal,
157
+ }));
158
+ run = polled.data;
159
+ const elapsed = Date.now() - polledAt;
160
+ if (elapsed < MIN_POLL_INTERVAL_MS && !TERMINAL_STATUSES.includes(run.status)) {
161
+ await (0, n8n_workflow_1.sleep)(MIN_POLL_INTERVAL_MS - elapsed);
162
+ }
163
+ }
164
+ if (run.status !== 'SUCCEEDED') {
165
+ const reason = run.statusMessage ? `: ${String(run.statusMessage)}` : '';
166
+ const savedResults = await describeSavedResults.call(this, run.defaultDatasetId, integrationAppId);
167
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Actor run ${String(run.status)}${reason}`, {
168
+ itemIndex,
169
+ description: `See the run log in Apify Console: ${runUrl}.${savedResults}`,
170
+ });
171
+ }
172
+ const items = await getDatasetItems.call(this, run.defaultDatasetId, integrationAppId);
173
+ return { run, items };
174
+ }
175
+ //# sourceMappingURL=GenericFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GenericFunctions.js","sourceRoot":"","sources":["../../../nodes/GoogleMapsScraper/GenericFunctions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class GoogleMapsScraper implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }