node-red-contrib-ipgeolocation 1.0.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 +21 -0
- package/README.md +423 -0
- package/examples/01 - Single IP Lookup.json +102 -0
- package/examples/02 - Bulk IP Lookup.json +98 -0
- package/examples/03 - IP Security Lookup.json +98 -0
- package/examples/04 - Bulk IP Security.json +96 -0
- package/examples/05 - Abuse Contact Lookup.json +98 -0
- package/examples/06 - ASN Lookup.json +102 -0
- package/examples/07 - Timezone Lookup.json +101 -0
- package/examples/08 - Astronomy (Sun & Moon).json +109 -0
- package/examples/09 - User-Agent Parser.json +96 -0
- package/index.js +22 -0
- package/nodes/ipgeo-abuse.html +203 -0
- package/nodes/ipgeo-abuse.js +148 -0
- package/nodes/ipgeo-asn.html +297 -0
- package/nodes/ipgeo-asn.js +197 -0
- package/nodes/ipgeo-astronomy.html +242 -0
- package/nodes/ipgeo-astronomy.js +195 -0
- package/nodes/ipgeo-bulk-security.html +166 -0
- package/nodes/ipgeo-bulk-security.js +177 -0
- package/nodes/ipgeo-bulk.html +158 -0
- package/nodes/ipgeo-bulk.js +146 -0
- package/nodes/ipgeo-config.html +72 -0
- package/nodes/ipgeo-config.js +30 -0
- package/nodes/ipgeo-lookup.html +300 -0
- package/nodes/ipgeo-lookup.js +165 -0
- package/nodes/ipgeo-security.html +214 -0
- package/nodes/ipgeo-security.js +150 -0
- package/nodes/ipgeo-timezone.html +201 -0
- package/nodes/ipgeo-timezone.js +154 -0
- package/nodes/ipgeo-useragent.html +133 -0
- package/nodes/ipgeo-useragent.js +110 -0
- package/nodes/lib/api-client.js +210 -0
- package/nodes/lib/node-helpers.js +214 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 IPGeolocation
|
|
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,423 @@
|
|
|
1
|
+
# node-red-contrib-ipgeolocation
|
|
2
|
+
|
|
3
|
+
Node-RED nodes for the [IPGeolocation.io](https://ipgeolocation.io) v3 API: IP geolocation, security and threat intelligence, VPN and proxy detection, abuse contacts, ASN lookup, bulk IP processing, timezone, astronomy, and user-agent parsing.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/node-red-contrib-ipgeolocation)
|
|
6
|
+
[](https://www.npmjs.com/package/node-red-contrib-ipgeolocation)
|
|
7
|
+
[](https://nodered.org)
|
|
8
|
+
[](https://nodejs.org)
|
|
9
|
+
[](./LICENSE)
|
|
10
|
+
|
|
11
|
+
A complete, production-ready set of **Node-RED IP geolocation nodes**. Look up the country, city, latitude, and longitude of any IP address or domain, score IPs for proxy, VPN, TOR, and bot risk, resolve ASN and abuse-contact data, parse user-agent strings, and fetch timezone and astronomy data, all from low-code Node-RED flows.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Table of contents
|
|
16
|
+
|
|
17
|
+
- [Features](#features)
|
|
18
|
+
- [Quick start](#quick-start)
|
|
19
|
+
- [Requirements](#requirements)
|
|
20
|
+
- [Installation](#installation)
|
|
21
|
+
- [Configuration: API key](#configuration-api-key)
|
|
22
|
+
- [How the nodes work](#how-the-nodes-work)
|
|
23
|
+
- [Node reference](#node-reference)
|
|
24
|
+
- [Message properties](#message-properties)
|
|
25
|
+
- [Error handling and retries](#error-handling-and-retries)
|
|
26
|
+
- [Example flows](#example-flows)
|
|
27
|
+
- [Recipes](#recipes)
|
|
28
|
+
- [API credits](#api-credits)
|
|
29
|
+
- [Development and testing](#development-and-testing)
|
|
30
|
+
- [FAQ](#faq)
|
|
31
|
+
- [License](#license)
|
|
32
|
+
- [Links](#links)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- **Single IP geolocation:** resolve country, region, city, latitude, longitude, currency, and timezone for any IPv4, IPv6, or domain.
|
|
39
|
+
- **Bulk IP geolocation:** process up to 50,000 IP addresses in one request.
|
|
40
|
+
- **IP security and threat intelligence:** detect proxy, VPN, TOR, bot, and threat scores for fraud prevention and access control.
|
|
41
|
+
- **Bulk security lookup:** score large IP lists in a single call.
|
|
42
|
+
- **Abuse contact lookup:** retrieve the abuse email, phone, and owning organization for an IP.
|
|
43
|
+
- **ASN lookup:** resolve Autonomous System details by IP or AS number.
|
|
44
|
+
- **Timezone API:** get timezone data by name, IP, coordinates, city, IATA code, ICAO code, or UN/LOCODE.
|
|
45
|
+
- **Astronomy API:** sunrise, sunset, moonrise, moonset, twilight phases, moon phase, and solar and lunar positions by coordinates, address, or IP.
|
|
46
|
+
- **User-agent parser:** identify browser, device, OS, and engine from a user-agent string.
|
|
47
|
+
- **Developer friendly:** dynamic `msg`, `flow`, and `global` inputs, an optional dedicated error output, automatic retries with exponential backoff, secure credential storage, and per-request credit reporting.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# In your Node-RED user directory (usually ~/.node-red)
|
|
55
|
+
npm install node-red-contrib-ipgeolocation
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
1. Restart Node-RED.
|
|
59
|
+
2. Drag the **ipgeo lookup** node onto the canvas (find it under the **IPGeolocation** palette category).
|
|
60
|
+
3. Open the node, click the pencil next to **API Config**, and paste your [free IPGeolocation.io API key](https://app.ipgeolocation.io/signup).
|
|
61
|
+
4. Wire an **inject** node in and a **debug** node out, then deploy.
|
|
62
|
+
5. Inject any IP string as `msg.payload`, for example `8.8.8.8`, and read the geolocation result from the debug panel.
|
|
63
|
+
|
|
64
|
+
That is the whole loop: inject an IP, get structured location data back.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Requirements
|
|
69
|
+
|
|
70
|
+
| Requirement | Version |
|
|
71
|
+
|-------------|---------|
|
|
72
|
+
| Node-RED | >= 2.0 |
|
|
73
|
+
| Node.js | >= 14.0 |
|
|
74
|
+
| IPGeolocation.io API key | Free tier works ([sign up](https://app.ipgeolocation.io/signup)) |
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Installation
|
|
79
|
+
|
|
80
|
+
### Palette Manager (recommended)
|
|
81
|
+
|
|
82
|
+
1. Open Node-RED.
|
|
83
|
+
2. Go to **Menu > Manage palette > Install**.
|
|
84
|
+
3. Search for `node-red-contrib-ipgeolocation`.
|
|
85
|
+
4. Click **Install**.
|
|
86
|
+
|
|
87
|
+
### npm
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
cd ~/.node-red
|
|
91
|
+
npm install node-red-contrib-ipgeolocation
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Restart Node-RED. All ten nodes appear under the **IPGeolocation** category in the palette.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Configuration: API key
|
|
99
|
+
|
|
100
|
+
Every functional node references a shared **ipgeo config** node that holds your API key. The key is stored as an encrypted Node-RED credential and is never written into exported flow JSON.
|
|
101
|
+
|
|
102
|
+
1. Drag any IPGeolocation node onto the canvas.
|
|
103
|
+
2. Double-click it, then click the pencil icon beside **API Config**.
|
|
104
|
+
3. Enter a **Name** and paste your **API Key**.
|
|
105
|
+
4. Click **Add**, then **Done**.
|
|
106
|
+
|
|
107
|
+
Reuse the same config node across every IPGeolocation node so you manage one key in one place.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## How the nodes work
|
|
112
|
+
|
|
113
|
+
These conventions apply to all nine functional nodes.
|
|
114
|
+
|
|
115
|
+
**Dynamic input.** Any IP, coordinate, or value can be a static string or read at runtime from a `msg`, `flow`, or `global` property. One configured node can serve many different inputs.
|
|
116
|
+
|
|
117
|
+
**Two outputs by default.** Each node ships with two outputs:
|
|
118
|
+
|
|
119
|
+
- Output 1 (success): the API result, written to the configured property (default `msg.payload`).
|
|
120
|
+
- Output 2 (error): the original `msg` with a structured `msg.error` attached.
|
|
121
|
+
|
|
122
|
+
Uncheck **Use second output** to collapse to a single output and handle failures flow-wide with a standard **Catch** node.
|
|
123
|
+
|
|
124
|
+
**Response shaping.** Most nodes expose **Fields** (return only the listed dot-notation paths) and **Excludes** (drop listed paths) so you can trim large responses, for example `location.city,location.country_name` or `security.threat_score`.
|
|
125
|
+
|
|
126
|
+
**Credit reporting.** Every successful response sets `msg.ipgeo_credits` to the number of API credits the request consumed.
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Node reference
|
|
131
|
+
|
|
132
|
+
| Node | Endpoint | Purpose |
|
|
133
|
+
|------|----------|---------|
|
|
134
|
+
| `ipgeo-config` | n/a | Shared API key credential |
|
|
135
|
+
| `ipgeo-lookup` | `GET /v3/ipgeo` | Single IP or domain geolocation |
|
|
136
|
+
| `ipgeo-bulk` | `POST /v3/ipgeo-bulk` | Bulk geolocation, up to 50,000 IPs |
|
|
137
|
+
| `ipgeo-security` | `GET /v3/security` | Single-IP security and threat data |
|
|
138
|
+
| `ipgeo-bulk-security` | `POST /v3/security-bulk` | Bulk security, up to 50,000 IPs |
|
|
139
|
+
| `ipgeo-abuse` | `GET /v3/abuse` | Abuse contact details |
|
|
140
|
+
| `ipgeo-asn` | `GET /v3/asn` | ASN details by IP or AS number |
|
|
141
|
+
| `ipgeo-timezone` | `GET /v3/timezone` | Timezone by name, IP, coords, city, IATA, ICAO, UN/LOCODE |
|
|
142
|
+
| `ipgeo-astronomy` | `GET /v3/astronomy` | Sun and moon data |
|
|
143
|
+
| `ipgeo-useragent` | `GET /v3/user-agent` | User-agent parsing |
|
|
144
|
+
|
|
145
|
+
### ipgeo-lookup: single IP geolocation
|
|
146
|
+
|
|
147
|
+
Resolves a single IPv4, IPv6, or domain. Leave the IP blank to look up the caller's own IP.
|
|
148
|
+
|
|
149
|
+
| Option | Description | Default |
|
|
150
|
+
|--------|-------------|---------|
|
|
151
|
+
| IP / Domain | Static value or `msg` / `flow` / `global` property | empty (caller IP) |
|
|
152
|
+
| Include | Optional data modules to add | none |
|
|
153
|
+
| Fields / Excludes | Restrict or trim the response | all |
|
|
154
|
+
| Language | Response language | `en` |
|
|
155
|
+
| User-Agent header | Forward a UA string as a request header | off |
|
|
156
|
+
| Output to | Destination property | `msg.payload` |
|
|
157
|
+
|
|
158
|
+
Include modules:
|
|
159
|
+
|
|
160
|
+
| Module | Extra credits | Adds |
|
|
161
|
+
|--------|:---:|------|
|
|
162
|
+
| `security` | +2 | Proxy, VPN, TOR, bot, threat score |
|
|
163
|
+
| `abuse` | +1 | Abuse contact (email, phone, org) |
|
|
164
|
+
| `user_agent` | 0 | Parsed user-agent |
|
|
165
|
+
| `geo_accuracy` | 0 | Accuracy radius and confidence |
|
|
166
|
+
| `dma_code` | 0 | US Designated Market Area code |
|
|
167
|
+
| `hostname` | 0 | PTR from local database |
|
|
168
|
+
| `liveHostname` | 0 | Live DNS PTR lookup |
|
|
169
|
+
| `hostnameFallbackLive` | 0 | Database first, then live DNS |
|
|
170
|
+
|
|
171
|
+
Set `msg.ipgeo_include` upstream to override the include list per message.
|
|
172
|
+
|
|
173
|
+
### ipgeo-bulk: bulk IP geolocation
|
|
174
|
+
|
|
175
|
+
Sends up to 50,000 IPs or domains in one POST.
|
|
176
|
+
|
|
177
|
+
- **Input:** `msg.payload` as a string array (`["1.2.3.4", "example.com"]`) or a comma-separated string, which is split automatically.
|
|
178
|
+
- **Output:** an array of result objects in input order. Invalid or private entries come back as `{ "message": "..." }`.
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
// Keep only successfully resolved results
|
|
182
|
+
const resolved = msg.payload.filter(r => r.ip);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### ipgeo-security: IP security and threat intelligence
|
|
186
|
+
|
|
187
|
+
Single-IP risk lookup: proxy, VPN, TOR, and bot detection plus a threat score, useful for fraud checks, login protection, and access control. Supports **Fields** and **Excludes**.
|
|
188
|
+
|
|
189
|
+
### ipgeo-bulk-security: bulk IP security
|
|
190
|
+
|
|
191
|
+
Bulk version of the security lookup, up to 50,000 IPs. Input handling matches `ipgeo-bulk`. When some entries cannot be scored, the node summarizes them:
|
|
192
|
+
|
|
193
|
+
| Property | Set when | Meaning |
|
|
194
|
+
|----------|----------|---------|
|
|
195
|
+
| `msg.ipgeo_invalid_count` | an entry has no `security` object | count of invalid entries |
|
|
196
|
+
| `msg.ipgeo_invalid_messages` | as above | the invalid entries' messages |
|
|
197
|
+
|
|
198
|
+
Both are removed from `msg` when every entry is valid.
|
|
199
|
+
|
|
200
|
+
### ipgeo-abuse: abuse contact lookup
|
|
201
|
+
|
|
202
|
+
Returns the abuse-contact record for an IP, such as `abuse.emails`, `abuse.phone_numbers`, and the owning organization. Supports **Fields** and **Excludes**.
|
|
203
|
+
|
|
204
|
+
### ipgeo-asn: ASN lookup
|
|
205
|
+
|
|
206
|
+
Looks up Autonomous System details. The **Query type** selects what gets sent:
|
|
207
|
+
|
|
208
|
+
| Query type | Sends | Notes |
|
|
209
|
+
|------------|-------|-------|
|
|
210
|
+
| `auto` | neither ip nor asn | API infers from context |
|
|
211
|
+
| `ip` | `ip=<value>` | resolve the ASN behind an IP |
|
|
212
|
+
| `asn` | `asn=<number>` | an `AS` prefix is stripped automatically (`AS15169` becomes `15169`) |
|
|
213
|
+
|
|
214
|
+
Supports an **Include** list (`peers`, `downstreams`, `upstreams`, and more), overridable per message via `msg.ipgeo_include`, plus **Fields** and **Excludes**.
|
|
215
|
+
|
|
216
|
+
### ipgeo-timezone: timezone API
|
|
217
|
+
|
|
218
|
+
Seven lookup modes:
|
|
219
|
+
|
|
220
|
+
| Mode | Parameter sent | Example |
|
|
221
|
+
|------|----------------|---------|
|
|
222
|
+
| Timezone name | `tz` | `America/New_York` |
|
|
223
|
+
| IP address | `ip` | `8.8.8.8` |
|
|
224
|
+
| Address / city | `location` | `Paris, France` |
|
|
225
|
+
| Coordinates | `lat` + `long` | `48.8566`, `2.3522` |
|
|
226
|
+
| IATA airport | `iata` | `CDG` |
|
|
227
|
+
| ICAO airport | `icao` | `LFPG` |
|
|
228
|
+
| UN/LOCODE | `location` | `FRPAR` |
|
|
229
|
+
|
|
230
|
+
Returns `INVALID_INPUT` when the value required for the chosen mode is missing.
|
|
231
|
+
|
|
232
|
+
### ipgeo-astronomy: sun and moon data
|
|
233
|
+
|
|
234
|
+
Returns sunrise, sunset, moonrise, moonset, twilight phases (civil, nautical, astronomical, plus blue hour and golden hour), solar noon, day length, moon phase, illumination, and live solar and lunar positions.
|
|
235
|
+
|
|
236
|
+
The location can be derived four ways, selected by the **Look up by** mode:
|
|
237
|
+
|
|
238
|
+
| Mode | Sends | Notes |
|
|
239
|
+
|------|-------|-------|
|
|
240
|
+
| `coords` | `lat` + `long` | decimal degrees; both required |
|
|
241
|
+
| `location` | `location` | address, preferably a city, for example `New York, USA` |
|
|
242
|
+
| `ip` | `ip` | any IPv4 or IPv6 address; adds an `ip` field to the response |
|
|
243
|
+
| `auto` | nothing | the API uses the caller's IP |
|
|
244
|
+
|
|
245
|
+
When more than one is supplied, the API prefers coordinates, then location, then IP. Coordinates and location modes return `INVALID_INPUT` when their value is missing.
|
|
246
|
+
|
|
247
|
+
Optional parameters (all modes):
|
|
248
|
+
|
|
249
|
+
| Option | Parameter | Description |
|
|
250
|
+
|--------|-----------|-------------|
|
|
251
|
+
| Date | `date` | `YYYY-MM-DD`; defaults to today at the location |
|
|
252
|
+
| Time zone | `time_zone` | IANA name; converts all event times into this zone |
|
|
253
|
+
| Elevation | `elevation` | meters above sea level, 0 to 10000; defaults to 0 |
|
|
254
|
+
| Language | `lang` | language for the `location` object (paid plans) |
|
|
255
|
+
|
|
256
|
+
The response nests results under an `astronomy` object alongside a `location` object, so read values such as `payload.astronomy.sunrise` and `payload.location.city`.
|
|
257
|
+
|
|
258
|
+
### ipgeo-useragent: user-agent parser
|
|
259
|
+
|
|
260
|
+
Parses a user-agent string into browser, device, OS, and engine. The UA is sent to the API as a request header rather than a query parameter.
|
|
261
|
+
|
|
262
|
+
Ideal in HTTP-in flows: point the UA source at `msg.req.headers.user-agent` (the default) to parse each visitor's browser automatically. An empty UA returns `INVALID_INPUT`.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Message properties
|
|
267
|
+
|
|
268
|
+
| Property | Direction | Type | Description |
|
|
269
|
+
|----------|-----------|------|-------------|
|
|
270
|
+
| `ipgeo_credits` | output | number | Credits consumed by the request |
|
|
271
|
+
| `ipgeo_include` | input | string | Per-message override of the include list, where supported |
|
|
272
|
+
| `ipgeo_invalid_count` | output | number | Bulk-security: entries with no security result |
|
|
273
|
+
| `ipgeo_invalid_messages` | output | array | Bulk-security: messages for invalid entries |
|
|
274
|
+
| `error` | output | object | On the error output: `{ code, message, status, body }` |
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Error handling and retries
|
|
279
|
+
|
|
280
|
+
On failure, the node sets `msg.error` with a typed `code`, a readable `message`, the HTTP `status` where applicable, and the raw response `body`.
|
|
281
|
+
|
|
282
|
+
| Code | Cause |
|
|
283
|
+
|------|-------|
|
|
284
|
+
| `NO_API_KEY` | Config node missing or key empty |
|
|
285
|
+
| `BAD_REQUEST` | Invalid parameters (HTTP 400) |
|
|
286
|
+
| `AUTH_FAILED` | Invalid or missing API key (HTTP 401) |
|
|
287
|
+
| `FORBIDDEN` | Plan restriction or origin not whitelisted (HTTP 403) |
|
|
288
|
+
| `NOT_FOUND` | Endpoint or resource not found (HTTP 404) |
|
|
289
|
+
| `VALIDATION` | Validation error (HTTP 422) |
|
|
290
|
+
| `LOCKED` | Key locked, quota exceeded, or account suspended (HTTP 423) |
|
|
291
|
+
| `RATE_LIMITED` | Too many requests (HTTP 429) |
|
|
292
|
+
| `SERVER_ERROR` | API internal error (HTTP 500) |
|
|
293
|
+
| `HTTP_ERROR` | Any other non-2xx status |
|
|
294
|
+
| `TIMEOUT` | Request timed out |
|
|
295
|
+
| `NETWORK_ERROR` | DNS or connectivity failure |
|
|
296
|
+
| `NO_RESPONSE` | Request sent but no response received |
|
|
297
|
+
| `INVALID_INPUT` / `INVALID_MODE` | Missing or malformed node input |
|
|
298
|
+
| `TOO_MANY_IPS` | Bulk request over the 50,000-IP limit |
|
|
299
|
+
|
|
300
|
+
**Automatic retries.** Transient failures (HTTP 429, 500, 502, 503, 504, timeouts, and network errors) are retried up to 3 times with exponential backoff (500 ms, 1 s, 2 s). For HTTP 429, the `Retry-After` header is honored when present. The default request timeout is 10 seconds, and 30 seconds for the bulk endpoints.
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Example flows
|
|
305
|
+
|
|
306
|
+
The package bundles ready-to-import examples, one per functional node:
|
|
307
|
+
|
|
308
|
+
| Example | Demonstrates |
|
|
309
|
+
|---------|--------------|
|
|
310
|
+
| 01 - Single IP Lookup | `ipgeo-lookup` |
|
|
311
|
+
| 02 - Bulk IP Lookup | `ipgeo-bulk` |
|
|
312
|
+
| 03 - IP Security Lookup | `ipgeo-security` |
|
|
313
|
+
| 04 - Bulk IP Security | `ipgeo-bulk-security` |
|
|
314
|
+
| 05 - Abuse Contact Lookup | `ipgeo-abuse` |
|
|
315
|
+
| 06 - ASN Lookup | `ipgeo-asn` |
|
|
316
|
+
| 07 - Timezone Lookup | `ipgeo-timezone` |
|
|
317
|
+
| 08 - Astronomy (Sun & Moon) | `ipgeo-astronomy` |
|
|
318
|
+
| 09 - User-Agent Parser | `ipgeo-useragent` |
|
|
319
|
+
|
|
320
|
+
To import: **Menu > Import > Examples**, then choose **node-red-contrib-ipgeolocation** and pick a flow. Each example has an inject trigger, the node wired to result and error debug nodes, and a placeholder config node. Point that config node at your own API key before deploying.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Recipes
|
|
325
|
+
|
|
326
|
+
### Override the include list per message
|
|
327
|
+
|
|
328
|
+
```javascript
|
|
329
|
+
// In a Function node upstream of ipgeo-lookup or ipgeo-asn
|
|
330
|
+
msg.ipgeo_include = "security,abuse";
|
|
331
|
+
return msg;
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Geolocate the visitor in an HTTP flow
|
|
335
|
+
|
|
336
|
+
Configure `ipgeo-lookup` with **IP / Domain** as a `msg` property pointing at `req.headers['x-forwarded-for']` (behind a proxy) or `req.connection.remoteAddress` (direct).
|
|
337
|
+
|
|
338
|
+
### Block proxies and VPNs at the edge
|
|
339
|
+
|
|
340
|
+
Run incoming IPs through `ipgeo-security`, then use a **Switch** node on `payload.security.is_proxy` or the threat score to drop or flag risky traffic before it reaches your application.
|
|
341
|
+
|
|
342
|
+
### Return compact bulk responses
|
|
343
|
+
|
|
344
|
+
On `ipgeo-bulk`, set **Fields** to `location.city,location.country_name,asn.organization`, optionally add **Include** `security`, and **Excludes** `security.threat_score` to return only the data you need per IP.
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## API credits
|
|
349
|
+
|
|
350
|
+
| Endpoint or module | Credits |
|
|
351
|
+
|--------------------|:---:|
|
|
352
|
+
| Single IP lookup (base) | 1 |
|
|
353
|
+
| + security module | +2 |
|
|
354
|
+
| + abuse module | +1 |
|
|
355
|
+
| Bulk lookup | 1-4 per valid IP |
|
|
356
|
+
| Security / bulk-security | 2 per valid IP |
|
|
357
|
+
| ASN, Abuse, Timezone, User-Agent, Astronomy | 1 |
|
|
358
|
+
|
|
359
|
+
Each node reports the real charge in `msg.ipgeo_credits`. See the [Credits Usage Guide](https://ipgeolocation.io/documentation/credits-usage.html) for current pricing.
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Development and testing
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
npm install # install dependencies
|
|
367
|
+
npm test # run the mocha test suite
|
|
368
|
+
npm run coverage # run tests with an HTML and text coverage report
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Tests use `mocha`, `node-red-node-test-helper`, `should`, and `nock`, with all HTTP fully mocked so the suite runs offline with no live API calls. Specs live in `test/**/*_spec.js` and cover the shared API client, the helpers, every node, and the bundled example flows.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Frequently Asked Questions
|
|
376
|
+
|
|
377
|
+
<details>
|
|
378
|
+
<summary><strong>How do I get an IPGeolocation.io API key?</strong></summary>
|
|
379
|
+
Sign up for a free account at <code>app.ipgeolocation.io/signup</code>. The free tier provides enough usage to evaluate every node included in this package.
|
|
380
|
+
</details>
|
|
381
|
+
|
|
382
|
+
<details>
|
|
383
|
+
<summary><strong>Is the API key safe in exported flows?</strong></summary>
|
|
384
|
+
Yes. The API key is stored as an encrypted Node-RED credential on the <code>ipgeo-config</code> node and is never included in exported flow JSON.
|
|
385
|
+
</details>
|
|
386
|
+
|
|
387
|
+
<details>
|
|
388
|
+
<summary><strong>Can I look up many IP addresses at once?</strong></summary>
|
|
389
|
+
Yes. Use the <code>ipgeo-bulk</code> node for geolocation lookups or the <code>ipgeo-bulk-security</code> node for security and threat analysis. Both support processing up to 50,000 IP addresses in a single request.
|
|
390
|
+
</details>
|
|
391
|
+
|
|
392
|
+
<details>
|
|
393
|
+
<summary><strong>How do I detect VPNs, proxies, or TOR exit nodes?</strong></summary>
|
|
394
|
+
Use the <code>ipgeo-security</code> node, or enable the <code>security</code> include module when using <code>ipgeo-lookup</code>. The response includes fields indicating proxy usage, VPN detection, TOR exit node status, and other threat-related information.
|
|
395
|
+
</details>
|
|
396
|
+
|
|
397
|
+
<details>
|
|
398
|
+
<summary><strong>Does it work behind a reverse proxy?</strong></summary>
|
|
399
|
+
Yes. Read the client IP address from <code>req.headers['x-forwarded-for']</code> and pass it to <code>ipgeo-lookup</code> as a dynamic <code>msg</code> input to geolocate the original client.
|
|
400
|
+
</details>
|
|
401
|
+
|
|
402
|
+
<details>
|
|
403
|
+
<summary><strong>What happens when I hit a rate limit?</strong></summary>
|
|
404
|
+
The nodes automatically retry requests using exponential backoff and honor the <code>Retry-After</code> response header when provided. If the rate limit persists, the operation fails with a <code>RATE_LIMITED</code> error on the error output.
|
|
405
|
+
</details>
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
---
|
|
409
|
+
|
|
410
|
+
## License
|
|
411
|
+
|
|
412
|
+
[MIT](https://github.com/IPGeolocation/node-red-contrib-ipgeolocation/blob/main/LICENSE) (c) IPGeolocation.io
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Links
|
|
417
|
+
|
|
418
|
+
- [IPGeolocation.io website](https://ipgeolocation.io)
|
|
419
|
+
- [API documentation](https://ipgeolocation.io/documentation.html)
|
|
420
|
+
- [Get a free API key](https://app.ipgeolocation.io/signup)
|
|
421
|
+
- [Node-RED](https://nodered.org)
|
|
422
|
+
- [npm package](https://www.npmjs.com/package/node-red-contrib-ipgeolocation)
|
|
423
|
+
- [Issue tracker](https://github.com/IPGeolocation/node-red-contrib-ipgeolocation/issues)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "ipgeo_ex_lookup",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "IPGeo: Single IP Lookup",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "Geolocate a single IP address (or domain). The inject sends an IP on msg.payload; the lookup node reads it and returns full geolocation data."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "cmt",
|
|
11
|
+
"type": "comment",
|
|
12
|
+
"z": "ipgeo_ex_lookup",
|
|
13
|
+
"name": "\u2500\u2500 IPGeo: Single IP Lookup \u2500\u2500",
|
|
14
|
+
"info": "Set up: after importing, open the **IPGeolocation API** config node and paste your API key.\n\nGeolocate a single IP address (or domain). The inject sends an IP on msg.payload; the lookup node reads it and returns full geolocation data.",
|
|
15
|
+
"x": 180,
|
|
16
|
+
"y": 40
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "trig",
|
|
20
|
+
"type": "inject",
|
|
21
|
+
"z": "ipgeo_ex_lookup",
|
|
22
|
+
"name": "Lookup 8.8.8.8",
|
|
23
|
+
"props": [
|
|
24
|
+
{
|
|
25
|
+
"p": "payload",
|
|
26
|
+
"v": "8.8.8.8",
|
|
27
|
+
"vt": "str"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"repeat": "",
|
|
31
|
+
"crontab": "",
|
|
32
|
+
"once": false,
|
|
33
|
+
"topic": "",
|
|
34
|
+
"x": 150,
|
|
35
|
+
"y": 120,
|
|
36
|
+
"wires": [
|
|
37
|
+
[
|
|
38
|
+
"ipgeo_node"
|
|
39
|
+
]
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "ipgeo-lookup",
|
|
44
|
+
"name": "IP Lookup",
|
|
45
|
+
"ipType": "msg",
|
|
46
|
+
"ipValue": "payload",
|
|
47
|
+
"include": "",
|
|
48
|
+
"fields": "",
|
|
49
|
+
"excludes": "",
|
|
50
|
+
"lang": "en",
|
|
51
|
+
"outputProp": "payload",
|
|
52
|
+
"outputType": "msg",
|
|
53
|
+
"uaHeader": false,
|
|
54
|
+
"uaProp": "req.headers.user-agent",
|
|
55
|
+
"twoOutputs": true,
|
|
56
|
+
"z": "ipgeo_ex_lookup",
|
|
57
|
+
"server": "ipgeo_cfg",
|
|
58
|
+
"x": 410,
|
|
59
|
+
"y": 120,
|
|
60
|
+
"wires": [
|
|
61
|
+
[
|
|
62
|
+
"dbg_ok"
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
"dbg_err"
|
|
66
|
+
]
|
|
67
|
+
],
|
|
68
|
+
"id": "ipgeo_node"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "dbg_ok",
|
|
72
|
+
"type": "debug",
|
|
73
|
+
"z": "ipgeo_ex_lookup",
|
|
74
|
+
"name": "Result",
|
|
75
|
+
"active": true,
|
|
76
|
+
"tosidebar": true,
|
|
77
|
+
"console": false,
|
|
78
|
+
"complete": "payload",
|
|
79
|
+
"x": 640,
|
|
80
|
+
"y": 100,
|
|
81
|
+
"wires": []
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "dbg_err",
|
|
85
|
+
"type": "debug",
|
|
86
|
+
"z": "ipgeo_ex_lookup",
|
|
87
|
+
"name": "Error",
|
|
88
|
+
"active": true,
|
|
89
|
+
"tosidebar": true,
|
|
90
|
+
"console": false,
|
|
91
|
+
"complete": "true",
|
|
92
|
+
"x": 640,
|
|
93
|
+
"y": 160,
|
|
94
|
+
"wires": []
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "ipgeo_cfg",
|
|
98
|
+
"type": "ipgeo-config",
|
|
99
|
+
"z": "ipgeo_ex_lookup",
|
|
100
|
+
"name": "IPGeolocation API"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "ipgeo_ex_bulk",
|
|
4
|
+
"type": "tab",
|
|
5
|
+
"label": "IPGeo: Bulk Lookup",
|
|
6
|
+
"disabled": false,
|
|
7
|
+
"info": "Geolocate many IPs in one request. The inject sends an array of IPs on msg.payload; the bulk node POSTs them and returns an array of results."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "cmt",
|
|
11
|
+
"type": "comment",
|
|
12
|
+
"z": "ipgeo_ex_bulk",
|
|
13
|
+
"name": "\u2500\u2500 IPGeo: Bulk Lookup \u2500\u2500",
|
|
14
|
+
"info": "Set up: after importing, open the **IPGeolocation API** config node and paste your API key.\n\nGeolocate many IPs in one request. The inject sends an array of IPs on msg.payload; the bulk node POSTs them and returns an array of results.",
|
|
15
|
+
"x": 180,
|
|
16
|
+
"y": 40
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "trig",
|
|
20
|
+
"type": "inject",
|
|
21
|
+
"z": "ipgeo_ex_bulk",
|
|
22
|
+
"name": "Send 3 IPs",
|
|
23
|
+
"props": [
|
|
24
|
+
{
|
|
25
|
+
"p": "payload",
|
|
26
|
+
"v": "[\"8.8.8.8\",\"1.1.1.1\",\"208.67.222.222\"]",
|
|
27
|
+
"vt": "json"
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"repeat": "",
|
|
31
|
+
"crontab": "",
|
|
32
|
+
"once": false,
|
|
33
|
+
"topic": "",
|
|
34
|
+
"x": 150,
|
|
35
|
+
"y": 120,
|
|
36
|
+
"wires": [
|
|
37
|
+
[
|
|
38
|
+
"ipgeo_node"
|
|
39
|
+
]
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"type": "ipgeo-bulk",
|
|
44
|
+
"name": "Bulk Lookup",
|
|
45
|
+
"include": "",
|
|
46
|
+
"fields": "location.city,location.country_name",
|
|
47
|
+
"excludes": "",
|
|
48
|
+
"lang": "en",
|
|
49
|
+
"outputProp": "payload",
|
|
50
|
+
"outputType": "msg",
|
|
51
|
+
"twoOutputs": true,
|
|
52
|
+
"z": "ipgeo_ex_bulk",
|
|
53
|
+
"server": "ipgeo_cfg",
|
|
54
|
+
"x": 410,
|
|
55
|
+
"y": 120,
|
|
56
|
+
"wires": [
|
|
57
|
+
[
|
|
58
|
+
"dbg_ok"
|
|
59
|
+
],
|
|
60
|
+
[
|
|
61
|
+
"dbg_err"
|
|
62
|
+
]
|
|
63
|
+
],
|
|
64
|
+
"id": "ipgeo_node"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "dbg_ok",
|
|
68
|
+
"type": "debug",
|
|
69
|
+
"z": "ipgeo_ex_bulk",
|
|
70
|
+
"name": "Result",
|
|
71
|
+
"active": true,
|
|
72
|
+
"tosidebar": true,
|
|
73
|
+
"console": false,
|
|
74
|
+
"complete": "payload",
|
|
75
|
+
"x": 640,
|
|
76
|
+
"y": 100,
|
|
77
|
+
"wires": []
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "dbg_err",
|
|
81
|
+
"type": "debug",
|
|
82
|
+
"z": "ipgeo_ex_bulk",
|
|
83
|
+
"name": "Error",
|
|
84
|
+
"active": true,
|
|
85
|
+
"tosidebar": true,
|
|
86
|
+
"console": false,
|
|
87
|
+
"complete": "true",
|
|
88
|
+
"x": 640,
|
|
89
|
+
"y": 160,
|
|
90
|
+
"wires": []
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "ipgeo_cfg",
|
|
94
|
+
"type": "ipgeo-config",
|
|
95
|
+
"z": "ipgeo_ex_bulk",
|
|
96
|
+
"name": "IPGeolocation API"
|
|
97
|
+
}
|
|
98
|
+
]
|