├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── questioning.md
└── workflows
│ ├── deploy-docs.yml
│ ├── node-package.yml
│ └── python-package.yml
├── .gitignore
├── LICENSE
├── README.md
├── docs
├── assets
│ ├── favicon.ico
│ └── logo.png
├── index.md
├── nodejs.md
├── projects.md
└── python.md
├── mkdocs.yml
├── nodejs
├── .eslintrc.json
├── .npmignore
├── FlightRadar24
│ ├── api.js
│ ├── core.js
│ ├── entities
│ │ ├── airport.js
│ │ ├── entity.js
│ │ └── flight.js
│ ├── errors.js
│ ├── flightTrackerConfig.js
│ ├── index.d.ts
│ ├── index.js
│ ├── request.js
│ └── util.js
├── LICENSE
├── README.md
├── package-lock.json
├── package.json
└── tests
│ └── testApi.js
└── python
├── .flake8
├── FlightRadar24
├── __init__.py
├── api.py
├── core.py
├── entities
│ ├── __init__.py
│ ├── airport.py
│ ├── entity.py
│ └── flight.py
├── errors.py
└── request.py
├── LICENSE
├── README.md
├── pyproject.toml
├── requirements.txt
└── tests
├── conftest.py
├── package.py
├── test_api.py
└── util.py
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Set this input '....'
17 | 3. Run the '....'
18 | 4. Scroll down to '....'
19 | 5. See error
20 |
21 | **Expected behavior**
22 | A clear and concise description of what you expected to happen.
23 |
24 | **Screenshots**
25 | If applicable, add screenshots to help explain your problem.
26 |
27 | **System (please complete the following information):**
28 | - OS: [e.g. Windows]
29 | - Python Version [e.g. 1.10]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | - A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 | - A clear and concise description of what you want to happen.
13 | - A clear and concise description of any alternative solutions or features you've considered.
14 |
15 | **Is not your feature request related to a problem? Please describe**
16 | A clear and concise description of how your feature can positively impact the project.
17 |
18 | **Additional context**
19 | Add any other context or screenshots about the feature request here.
20 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/questioning.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Questioning
3 | about: Ask a question about the project
4 | title: ''
5 | labels: question
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your problem described in the documentation? If so, please describe**
11 | A clear and concise description of what is confusing in the documentation.
12 |
13 | **Describe your question**
14 | A clear and concise description of what the bug is.
15 |
16 | **Is your question reproducible? Please describe**
17 | Steps to reproduce the behavior:
18 |
19 | 1. Go to '...'
20 | 2. Set this input '....'
21 | 3. Run the '....'
22 | 4. Scroll down to '....'
23 | 5. See behavior
24 |
25 | **Screenshots**
26 | If applicable, add screenshots to help explain your problem.
27 |
28 | **System**
29 | If applicable, please complete the following information:
30 |
31 | 1. OS: [e.g. Windows]
32 | 2. Python Version [e.g. 1.10]
33 |
34 | **Additional context**
35 | Add any other context about the problem here.
36 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-docs.yml:
--------------------------------------------------------------------------------
1 | name: Deploy MkDocs
2 | on:
3 | push:
4 | branches:
5 | - main
6 | paths:
7 | - 'mkdocs.yml'
8 | - 'docs/**'
9 | - '.github/workflows/deploy-docs.yml'
10 | permissions:
11 | contents: write
12 | jobs:
13 | deploy:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | - name: Configure Git Credentials
18 | run: |
19 | git config user.name github-actions[bot]
20 | git config user.email 41898282+github-actions[bot]@users.noreply.github.com
21 | - uses: actions/setup-python@v5
22 | with:
23 | python-version: 3.x
24 | - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
25 | - uses: actions/cache@v4
26 | with:
27 | key: mkdocs-material-${{ env.cache_id }}
28 | path: .cache
29 | restore-keys: |
30 | mkdocs-material-
31 | - run: pip install \
32 | mkdocs-material \
33 | mkdocs-git-committers-plugin-2
34 | - run: mkdocs gh-deploy --force
--------------------------------------------------------------------------------
/.github/workflows/node-package.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
3 |
4 | name: Node.js Package
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 | schedule:
12 | - cron: '0 0 */7 * *'
13 | workflow_dispatch:
14 |
15 | defaults:
16 | run:
17 | working-directory: ./nodejs
18 |
19 | jobs:
20 | build:
21 | runs-on: ubuntu-latest
22 | strategy:
23 | matrix:
24 | node-version: ['14.x', '16.x', '18.x', '20.x']
25 | steps:
26 | - uses: actions/checkout@v3
27 | - name: Set up NodeJS ${{ matrix.python-version }}
28 | uses: actions/setup-node@v3
29 | with:
30 | node-version: ${{ matrix.node-version }}
31 | - name: Install dependencies
32 | run: npm ci
33 | - name: Test package
34 | run: npm test
35 |
--------------------------------------------------------------------------------
/.github/workflows/python-package.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: Python Package
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 | schedule:
12 | - cron: '0 0 */7 * *'
13 | workflow_dispatch:
14 |
15 | jobs:
16 | build:
17 | runs-on: ubuntu-latest
18 | strategy:
19 | matrix:
20 | python-version: ['3.8', '3.9', '3.10', '3.11']
21 | steps:
22 | - uses: actions/checkout@v2
23 | - name: Set up Python ${{ matrix.python-version }}
24 | uses: actions/setup-python@v2
25 | with:
26 | python-version: ${{ matrix.python-version }}
27 | - name: Install dependencies
28 | run: |
29 | python -m pip install --upgrade pip
30 | pip install -r python/requirements.txt
31 | - name: Test with pytest
32 | run: |
33 | cd python
34 | pytest tests -vv -s
35 | - name: Install package
36 | run: |
37 | pip install FlightRadar24
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | dist
3 | *.pytest_cache
4 | *.egg-info
5 | .idea/
6 | venv/
7 | node_modules/
8 | .env
9 | .cache
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Jean Loui Bernard Silva de Jesus
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FlightRadarAPI
2 | Unofficial SDK for [FlightRadar24](https://www.flightradar24.com/) for Python 3 and Node.js.
3 |
4 | This SDK should only be used for your own educational purposes. If you are interested in accessing Flightradar24 data commercially, please contact business@fr24.com. See more information at [Flightradar24's terms and conditions](https://www.flightradar24.com/terms-and-conditions).
5 |
6 | **Official FR24 API**: https://fr24api.flightradar24.com/
7 |
8 | [](https://github.com/JeanExtreme002/FlightRadarAPI/actions)
9 | [](https://pypi.org/project/FlightRadarAPI/)
10 | [](https://github.com/JeanExtreme002/FlightRadarAPI)
11 | [](https://pypi.org/project/FlightRadarAPI/)
12 | [](https://www.npmjs.com/package/flightradarapi)
13 | [](https://pypi.org/project/FlightRadarAPI/)
14 | [](https://pypi.org/project/FlightRadarAPI/)
15 |
16 | ## Installing FlightRadarAPI
17 | **For Python with pip:**
18 | ```
19 | pip install FlightRadarAPI
20 | ```
21 |
22 | **For Node.js with npm:**
23 | ```
24 | npm install flightradarapi
25 | ```
26 |
27 | ## Documentation
28 | Explore the documentation of FlightRadarAPI package, for Python or NodeJS, through [this site](https://JeanExtreme002.github.io/FlightRadarAPI/).
29 |
--------------------------------------------------------------------------------
/docs/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JeanExtreme002/FlightRadarAPI/61e76f5900c4292487f89d0287b828a94138682b/docs/assets/favicon.ico
--------------------------------------------------------------------------------
/docs/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JeanExtreme002/FlightRadarAPI/61e76f5900c4292487f89d0287b828a94138682b/docs/assets/logo.png
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | # FlightRadarAPI Documentation
2 |
3 | Unofficial SDK for [FlightRadar24](https://www.flightradar24.com/) for Python 3 and Node.js.
4 |
5 | This SDK should only be used for your own educational purposes. If you are interested in accessing Flightradar24 data commercially, please contact [business@fr24.com](business@fr24.com).
6 |
7 | See more information at [Flightradar24's terms and conditions](https://www.flightradar24.com/terms-and-conditions).
8 |
9 | [](https://github.com/JeanExtreme002/FlightRadarAPI/actions)
10 | [](https://pypi.org/project/FlightRadarAPI/)
11 | [](https://github.com/JeanExtreme002/FlightRadarAPI)
12 | [](https://pypi.org/project/FlightRadarAPI/)
13 | [](https://www.npmjs.com/package/flightradarapi)
14 | [](https://pypi.org/project/FlightRadarAPI/)
15 | [](https://pypi.org/project/FlightRadarAPI/)
16 |
17 | !!! info
18 | This is NOT an official FlightRadar24 API. You can access their official API [here](https://fr24api.flightradar24.com/).
19 |
20 |
21 |
22 | - :octicons-file-code-16:{ .lg .middle } __100% Free and Open Source!__
23 |
24 | ---
25 |
26 | The code is open source and available for inspection on GitHub.
27 |
28 |
29 | - :material-sticker-check-outline:{ .lg .middle } __Python and Node.js__
30 |
31 | ---
32 |
33 | Packages are avaiable for use on both Python and Node.js
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | ## Installation
44 |
45 | === "Python"
46 |
47 | To install FlightRadarAPI for Python using [pip](https://pypi.org/project/FlightRadarAPI/), run the following command in your terminal:
48 |
49 | ```bash
50 | pip install FlightRadarAPI
51 | ```
52 |
53 | === "Node.js"
54 |
55 | To install FlightRadarAPI for Node.js using [npm](https://www.npmjs.com/package/flightradarapi), run the following command in your terminal:
56 |
57 | ```bash
58 | npm install flightradarapi
59 | ```
60 |
--------------------------------------------------------------------------------
/docs/nodejs.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Node.js
3 | description: API Documentation for Node.js
4 | ---
5 |
6 | ## Installation
7 |
8 | To install the FlightRadarAPI for Node.js, use the following npm command:
9 |
10 | ```bash
11 | npm install flightradarapi
12 | ```
13 |
14 | ## Basic Usage
15 |
16 | Start by importing the `FlightRadar24API` class and creating an instance of it:
17 |
18 | ```javascript
19 | const { FlightRadar24API } = require("flightradarapi");
20 | const frApi = new FlightRadar24API();
21 | ```
22 |
23 | ### Fetching Data
24 |
25 | You can fetch various types of data using the following methods:
26 |
27 | - **Flights list:**
28 |
29 | ```javascript
30 | let flights = await frApi.getFlights(...); // Returns a list of Flight objects
31 | ```
32 |
33 | - **Airports list:**
34 |
35 | ```javascript
36 | let airports = await frApi.getAirports(...); // Returns a list of Airport objects
37 | ```
38 |
39 | - **Airlines list:**
40 |
41 | ```javascript
42 | let airlines = await frApi.getAirlines();
43 | ```
44 |
45 | - **Zones list:**
46 |
47 | ```javascript
48 | let zones = await frApi.getZones();
49 | ```
50 |
51 | ### Fetching Detailed Information
52 |
53 | Fetch more information about a specific flight or airport using the following methods:
54 |
55 | - **Flight details:**
56 |
57 | ```javascript
58 | let flightDetails = await frApi.getFlightDetails(flight);
59 | flight.setFlightDetails(flightDetails);
60 |
61 | console.log("Flying to", flight.destinationAirportName);
62 | ```
63 |
64 | - **Airport details:**
65 |
66 | ```javascript
67 | let airportDetails = await frApi.getAirportDetails(icao);
68 | ```
69 |
70 | !!! note
71 | Arrivals and departures can have a limit `flightLimit` (max value is 100) to display. When you need to reach more than 100 flights you can use additional parameter `page` to view other pages.
72 |
73 | ## Advanced Usage
74 |
75 | ### Fetching Flights Above a Specific Position
76 |
77 | Use the `getBoundsByPoint(...)` method to fetch flights above a specific position. This method takes `latitude` and `longitude` for your position and `radius` for the distance in meters from your position to designate a tracking area.
78 |
79 | ```javascript
80 | // Your point is 52°34'04.7"N 13°16'57.5"E from Google Maps and radius 2km
81 | let bounds = frApi.getBoundsByPoint(52.567967, 13.282644, 2000);
82 |
83 | let flights = await frApi.getFlights(null, bounds);
84 | ```
85 |
86 | ### Filtering Flights and Airports
87 |
88 | Use the `getFlights(...)` method to search for flights by area line, bounds (customized coordinates or obtained by the `getZones()` method), aircraft registration or aircraft type.
89 |
90 | ```javascript
91 | let airlineIcao = "UAE";
92 | let aircraftType = "B77W";
93 |
94 | // You may also set a custom region, such as: bounds = "73,-12,-156,38"
95 | let zone = (await frApi.getZones())["northamerica"];
96 | let bounds = frApi.getBounds(zone);
97 |
98 | let emiratesFlights = await frApi.getFlights(
99 | airlineIcao,
100 | bounds,
101 | null,
102 | aircraftType,
103 | );
104 | ```
105 |
106 | ### Fetching Airport by ICAO or IATA
107 |
108 | ```javascript
109 | let luklaAirport = await frApi.getAirport("VNLK", true);
110 | ```
111 |
112 | ### Calculating Distance Between Flights and Airports
113 |
114 | The `Flight` and `Airport` classes inherit from `Entity`, which contains the `getDistanceFrom(...)` method. This method returns the distance between the self instance and another entity in kilometers.
115 |
116 | ```javascript
117 | let airport = await frApi.getAirport("KJFK");
118 | let distance = flight.getDistanceFrom(airport);
119 |
120 | console.log("The flight is", distance, "km away from the airport.");
121 | ```
122 |
123 | ## Downloading Flight Data :material-information-outline:{ title="This requires a premium subscription" }
124 |
125 | You can download flight data in either CSV or KML format. The method `getHistoryData(...)` is used for this purpose. It takes three parameters:
126 |
127 | !!! warning inline end
128 | If an invalid time is provided, a blank document will be returned.
129 |
130 | | Parameter | Description |
131 | | ------------- | ------------- |
132 | | `flight_id` | The ID of the flight. This can be obtained from any other function that returns flight details. |
133 | | `file_type` | The format of the file to download. This can be either "CSV" or "KML". |
134 | | `time` | The scheduled time of departure (STD) of the flight in UTC, as a Unix timestamp. |
135 |
136 | Here is an example of how to use this method:
137 |
138 | ```javascript
139 | let historyData = await frApi.getHistoryData(flight, "csv", 1706529600);
140 |
141 | const buffer = Buffer.from(historyData);
142 | fs.writeFile("history_data.csv", buffer);
143 | ```
144 |
145 | ### Setting and Getting Real-time Flight Tracker Parameters
146 |
147 | Set it by using the `setFlightTrackerConfig(...)` method. It receives a `FlightTrackerConfig` dataclass instance, but you can also use keyword arguments directly to the method.
148 |
149 | Get the current configuration with the `getFlightTrackerConfig()` method, that returns a `FlightTrackerConfig` instance. Note: creating a new `FlightTrackerConfig` instance means resetting all parameters to default.
150 |
151 | ```javascript
152 | let flightTracker = frApi.getFlightTrackerConfig();
153 | flightTracker.limit = 10
154 |
155 | frApi.setFlightTrackerConfig(flightTracker, ...);
156 |
157 | let flights = await frApi.getFlights(...); // Returns only 10 flights
158 | ```
159 |
--------------------------------------------------------------------------------
/docs/projects.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Projects using FlightRadarAPI
3 | description: Nice projects that use FlightRadarAPI
4 | ---
5 |
6 |
7 |
8 | - [__Automatic Calibration in Crowd-sourced Network of Spectrum Sensors__](https://dl.acm.org/doi/10.1145/3626111.3628187)
9 |
10 | ---
11 |
12 | By Ali Abedi, Joshua Sanz, Anant Sahai, from University of California (UC), Berkeley
13 |
14 |
15 | - [__Airline Status Tracker for top 10 Airport Departures in North America__](https://people.ischool.berkeley.edu/~frank.song/flight.html)
16 |
17 | ---
18 |
19 | By Adeleke Coker, Frank Song, Greg Chi, from University of California (UC), Berkeley, School of Information
20 |
21 | - [__Flight Tracker with Weather__](https://magpi.raspberrypi.com/articles/flight-tracker-with-weather)
22 |
23 | ---
24 |
25 | By Adam Paulson, a Reddit user going by the name C0wsaysmoo
26 |
27 | - [__Design and implementation project of an aircraft mobile node module for the SeamSAT-LEO constellation simulator__](https://upcommons.upc.edu/bitstream/handle/2117/394691/TFG.pdf?sequence=2&isAllowed=y)
28 |
29 | ---
30 |
31 | By David Anton Dobarro, graduate in Aerospace Technologies Engineering from Universitat Politècnica de Catalunya
32 |
33 | - [__Fridge Flight Tracker__](https://blog.colinwaddell.com/flight-tracker/)
34 |
35 | ---
36 |
37 | By Colin Waddell, a Glasgow based programmer, website designer and electronics specialist
38 |
39 | - [__Plane spotting Telegram Bot__](https://github.com/ViLsonCake/avgeek-telegram-bot)
40 |
41 | ---
42 |
43 | By Timofey Dmitrenko, aviation geek and Java Spring Boot programmer
44 |
45 |
46 |
47 | [Contribute Your Own :writing_hand:](https://github.com/JeanExtreme002/FlightRadarAPI/edit/main/docs/projects.md){ .md-button .md-button--primary }
48 |
--------------------------------------------------------------------------------
/docs/python.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Python
3 | description: API Documentation for Python
4 | ---
5 |
6 | ## Installation
7 |
8 | To install the FlightRadarAPI for Python, use the following pip command:
9 |
10 | ```bash
11 | pip install FlightRadarAPI
12 | ```
13 |
14 | ## Basic Usage
15 |
16 | Start by importing the `FlightRadar24API` class and creating an instance of it:
17 |
18 | ```python
19 | from FlightRadar24 import FlightRadar24API
20 | fr_api = FlightRadar24API()
21 | ```
22 |
23 | ### Fetching Data
24 |
25 | You can fetch various types of data using the following methods:
26 |
27 | - **Flights list:**
28 |
29 | ```python
30 | flights = fr_api.get_flights(...) # Returns a list of Flight objects
31 | ```
32 |
33 | - **Airports list:**
34 |
35 | ```python
36 | airports = fr_api.get_airports(...) # Returns a list of Airport objects
37 | ```
38 |
39 | - **Airlines list:**
40 |
41 | ```python
42 | airlines = fr_api.get_airlines()
43 | ```
44 |
45 | - **Zones list:**
46 |
47 | ```python
48 | zones = fr_api.get_zones()
49 | ```
50 |
51 | ### Fetching Detailed Information
52 |
53 | Fetch more information about a specific flight or airport using the following methods:
54 |
55 | - **Flight details:**
56 |
57 | ```python
58 | flight_details = fr_api.get_flight_details(flight)
59 | flight.set_flight_details(flight_details)
60 |
61 | print("Flying to", flight.destination_airport_name)
62 | ```
63 |
64 | - **Airport details:**
65 |
66 | ```python
67 | airport_details = fr_api.get_airport_details(icao)
68 | ```
69 |
70 | !!! note
71 | Arrivals and departures can have a limit `flightLimit` (max value is 100) to display. When you need to reach more than 100 flights you can use additional parameter `page` to view other pages.
72 |
73 | ## Advanced Usage
74 |
75 | ### Fetching Flights Above a Specific Position
76 |
77 | Use the `get_bounds_by_point(...)` method to fetch flights above a specific position. This method takes `latitude` and `longitude` for your position and `radius` for the distance in meters from your position to designate a tracking area.
78 |
79 | ```python
80 | # Your point is 52°34'04.7"N 13°16'57.5"E from Google Maps and radius 2km
81 | bounds = fr_api.get_bounds_by_point(52.567967, 13.282644, 2000)
82 |
83 | flights = fr_api.get_flights(bounds = bounds)
84 | ```
85 |
86 | ### Filtering Flights and Airports
87 |
88 | Use the `get_flights(...)` method to search for flights by area line, bounds (customized coordinates or obtained by the `get_zones()` method), aircraft registration or aircraft type.
89 |
90 | ```python
91 | airline_icao = "UAE"
92 | aircraft_type = "B77W"
93 |
94 | # You may also set a custom region, such as: bounds = "73,-12,-156,38"
95 | zone = fr_api.get_zones()["northamerica"]
96 | bounds = fr_api.get_bounds(zone)
97 |
98 | emirates_flights = fr_api.get_flights(
99 | aircraft_type = aircraft_type,
100 | airline = airline_icao,
101 | bounds = bounds
102 | )
103 | ```
104 |
105 | ### Fetching Airport by ICAO or IATA
106 |
107 | ```python
108 | lukla_airport = fr_api.get_airport(code = "VNLK", details = True)
109 | ```
110 |
111 | ### Calculating Distance Between Flights and Airports
112 |
113 | The `Flight` and `Airport` classes inherit from `Entity`, which contains the `get_distance_from(...)` method. This method returns the distance between the self instance and another entity in kilometers.
114 |
115 | ```python
116 | airport = fr_api.get_airport("KJFK")
117 | distance = flight.get_distance_from(airport)
118 |
119 | print(f"The flight is {distance} km away from the airport.")
120 | ```
121 |
122 | ### Downloading Flight Data :material-information-outline:{ title="This requires a premium subscription" }
123 |
124 |
125 | ```py
126 | history_data = fr_api.get_history_data(flight, file_type="csv", time=1706529600)
127 |
128 | with open("history_data.csv", "w") as file:
129 | file.write(history_data)
130 | ```
131 |
132 | !!! warning inline end
133 | If an invalid time is provided, a blank document will be returned.
134 |
135 | | Parameter | Description |
136 | | ------------- | ------------- |
137 | | `flight_id` | The ID of the flight. This can be obtained from any other function that returns flight details. |
138 | | `file_type` | The format of the file to download. This can be either "CSV" or "KML". |
139 | | `time` | The scheduled time of departure (STD) of the flight in UTC, as a Unix timestamp. |
140 |
141 |
142 | ### Setting and Getting Real-time Flight Tracker Parameters
143 |
144 | Set it by using the `set_flight_tracker_config(...)` method. It receives a `FlightTrackerConfig` dataclass instance, but you can also use keyword arguments directly to the method.
145 |
146 | Get the current configuration with the `get_flight_tracker_config()` method, that returns a `FlightTrackerConfig` instance. Note: creating a new `FlightTrackerConfig` instance means resetting all parameters to default.
147 |
148 | ```python
149 | flight_tracker = fr_api.get_flight_tracker_config()
150 | flight_tracker.limit = 10
151 |
152 | fr_api.set_flight_tracker_config(flight_tracker, ...)
153 |
154 | flights = fr_api.get_flights(...) # Returns only 10 flights
155 | ```
156 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: FlightRadarAPI
2 | repo_url: https://github.com/JeanExtreme002/FlightRadarAPI
3 | docs_dir: docs
4 | site_description: Documentation for the FlightRadarAPI
5 | site_author: JeanExtreme002
6 | edit_uri: edit/main/docs/
7 |
8 | nav:
9 | - Home: index.md
10 | - Python: python.md
11 | - Node.js: nodejs.md
12 | - Projects Using FlightRadarAPI: projects.md
13 |
14 | theme:
15 | name: material
16 | logo: assets/logo.png
17 | favicon: assets/favicon.ico
18 |
19 | features:
20 | - navigation.instant
21 | - navigation.instant.progress
22 | - content.code.copy
23 | - content.action.edit
24 | - search.suggest
25 | - search.highlight
26 | - search.share
27 | - content.tooltips
28 | - content.tabs.link
29 |
30 | icon:
31 | repo: fontawesome/brands/github
32 | annotation: material/arrow-right-circle
33 |
34 | palette:
35 | - primary: indigo
36 | - accent: yellow
37 |
38 | extra:
39 | social:
40 | - icon: fontawesome/brands/github
41 | link: https://github.com/JeanExtreme002
42 |
43 | markdown_extensions:
44 | - admonition
45 | - pymdownx.details
46 | - attr_list
47 | - md_in_html
48 | - abbr
49 | - attr_list
50 | - pymdownx.snippets
51 | - pymdownx.emoji:
52 | emoji_index: !!python/name:material.extensions.emoji.twemoji
53 | emoji_generator: !!python/name:material.extensions.emoji.to_svg
54 | - pymdownx.tabbed:
55 | alternate_style: true
56 | - pymdownx.superfences
57 |
58 | plugins:
59 | - git-committers:
60 | repository: JeanExtreme002/FlightRadarAPI
61 | branch: main
62 | - search
--------------------------------------------------------------------------------
/nodejs/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "commonjs": true,
4 | "es2021": true,
5 | "node": true
6 | },
7 | "extends": "google",
8 | "parserOptions": {
9 | "ecmaVersion": "latest"
10 | },
11 | "rules": {
12 | "max-len": ["error", {"code": 130}],
13 | "quotes": ["warn", "double"],
14 | "indent": ["warn", 4],
15 | "brace-style": ["warn", "stroustrup"],
16 | "valid-jsdoc": ["warn"],
17 | "require-jsdoc": ["warn"]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/nodejs/.npmignore:
--------------------------------------------------------------------------------
1 | .eslintrc.json
2 | tests/
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/api.js:
--------------------------------------------------------------------------------
1 | const Core = require("./core");
2 | const APIRequest = require("./request");
3 | const Airport = require("./entities/airport");
4 | const Flight = require("./entities/flight");
5 | const FlightTrackerConfig = require("./flightTrackerConfig");
6 | const {AirportNotFoundError, LoginError} = require("./errors");
7 | const {isNumeric} = require("./util");
8 |
9 |
10 | /**
11 | * Main class of the FlightRadarAPI
12 | */
13 | class FlightRadar24API {
14 | /**
15 | * Constructor of FlightRadar24API class
16 | */
17 | constructor() {
18 | this.__flightTrackerConfig = new FlightTrackerConfig();
19 | this.__loginData = null;
20 | }
21 |
22 | /**
23 | * Return a list with all airlines.
24 | *
25 | * @return {object}
26 | */
27 | async getAirlines() {
28 | const response = new APIRequest(Core.airlinesDataUrl, null, Core.jsonHeaders);
29 | await response.receive();
30 |
31 | return (await response.getContent())["rows"];
32 | }
33 |
34 | /**
35 | * Download the logo of an airline from FlightRadar24 and return it as bytes.
36 | *
37 | * @param {string} iata - IATA of the airline
38 | * @param {string} icao - ICAO of the airline
39 | * @return {[object, string]}
40 | */
41 | async getAirlineLogo(iata, icao) {
42 | iata = iata.toUpperCase();
43 | icao = icao.toUpperCase();
44 |
45 | const firstLogoUrl = Core.airlineLogoUrl.format(iata, icao);
46 |
47 | // Try to get the image by the first URL option.
48 | let response = new APIRequest(firstLogoUrl, null, Core.imageHeaders, null, null, [403]);
49 | await response.receive();
50 |
51 | let statusCode = response.getStatusCode();
52 |
53 | if (!statusCode.toString().startsWith("4")) {
54 | const splitUrl = firstLogoUrl.split(".");
55 | return [(await response.getContent()), splitUrl[splitUrl.length - 1]];
56 | }
57 |
58 | // Get the image by the second airline logo URL.
59 | const secondLogoUrl = Core.alternativeAirlineLogoUrl.format(icao);
60 |
61 | response = new APIRequest(secondLogoUrl, null, Core.imageHeaders);
62 | await response.receive();
63 |
64 | statusCode = response.getStatusCode();
65 |
66 | if (!statusCode.toString().startsWith("4")) {
67 | const splitUrl = secondLogoUrl.split(".");
68 | return [(await response.getContent()), splitUrl[splitUrl.length - 1]];
69 | }
70 | }
71 |
72 | /**
73 | * Return basic information about a specific airport.
74 | *
75 | * @param {string} code - ICAO or IATA of the airport
76 | * @param {boolean} details - If true, it returns flights with detailed information
77 | * @return {Airport}
78 | */
79 | async getAirport(code, details = false) {
80 | if (4 < code.length || code.length < 3) {
81 | throw new Error("The code '" + code + "' is invalid. It must be the IATA or ICAO of the airport.");
82 | }
83 |
84 | if (details) {
85 | const airport = new Airport();
86 |
87 | const airportDetails = await this.getAirportDetails(code);
88 | airport.setAirportDetails(airportDetails);
89 |
90 | return airport;
91 | }
92 |
93 | const response = new APIRequest(Core.airportDataUrl.format(code), null, Core.jsonHeaders);
94 | await response.receive();
95 |
96 | const info = (await response.getContent())["details"];
97 |
98 | if (info === undefined) {
99 | throw new AirportNotFoundError("Could not find an airport by the code '" + code + "'.");
100 | }
101 | return new Airport({}, info);
102 | }
103 |
104 | /**
105 | * Return the airport details from FlightRadar24.
106 | *
107 | * @param {string} code - ICAO or IATA of the airport
108 | * @param {number} [flightLimit=100] - Limit of flights related to the airport
109 | * @param {number} [page=1] - Page of result to display
110 | * @return {object}
111 | */
112 | async getAirportDetails(code, flightLimit = 100, page = 1) {
113 | if (4 < code.length || code.length < 3) {
114 | throw new Error("The code '" + code + "' is invalid. It must be the IATA or ICAO of the airport.");
115 | }
116 |
117 | const requestParams = {"format": "json"};
118 |
119 | if (this.__loginData != null) {
120 | requestParams["token"] = this.__loginData["cookies"]["_frPl"];
121 | }
122 |
123 | // Insert the method parameters into the dictionary for the request.
124 | requestParams["code"] = code;
125 | requestParams["limit"] = flightLimit;
126 | requestParams["page"] = page;
127 |
128 | // Request details from the FlightRadar24.
129 | const response = new APIRequest(Core.apiAirportDataUrl, requestParams, Core.jsonHeaders, null, null, [400]);
130 | await response.receive();
131 |
132 | const content = await response.getContent();
133 |
134 | if (response.getStatusCode() === 400 && content?.["errors"] !== undefined) {
135 | const errors = content["errors"]?.["errors"]?.["parameters"];
136 | const limit = errors?.["limit"];
137 |
138 | if (limit !== undefined) {
139 | throw new Error(limit["notBetween"]);
140 | }
141 | throw new AirportNotFoundError("Could not find an airport by the code '" + code + "'.", errors);
142 | }
143 |
144 | const result = content["result"]["response"];
145 |
146 | // Check whether it received data of an airport.
147 | const data = result?.["airport"]?.["pluginData"];
148 | const dataCount = typeof data === "object" ? Object.entries(data).length : 0;
149 |
150 | const runways = data?.["runways"];
151 | const runwaysCount = typeof runways === "object" ? Object.entries(runways).length : 0;
152 |
153 | if (data?.["details"] === undefined && runwaysCount == 0 && dataCount <= 3) {
154 | throw new AirportNotFoundError("Could not find an airport by the code '" + code + "'.");
155 | }
156 |
157 | // Return the airport details.
158 | return result;
159 | }
160 |
161 | /**
162 | * Return airport disruptions.
163 | *
164 | * @return {object}
165 | */
166 | async getAirportDisruptions() {
167 | const response = new APIRequest(Core.airportDisruptionsUrl, null, Core.jsonHeaders);
168 | await response.receive();
169 |
170 | return await response.getContent();
171 | }
172 |
173 | /**
174 | * Return a list with all airports.
175 | *
176 | * @return {Array}
177 | */
178 | async getAirports() {
179 | const response = new APIRequest(Core.airportsDataUrl, null, Core.jsonHeaders);
180 | await response.receive();
181 |
182 | const content = await response.getContent();
183 | const airports = [];
184 |
185 | for (const airportData of content["rows"]) {
186 | const airport = new Airport(airportData);
187 | airports.push(airport);
188 | }
189 | return airports;
190 | }
191 |
192 | /**
193 | * Return the bookmarks from the FlightRadar24 account.
194 | *
195 | * @return {object}
196 | */
197 | async getBookmarks() {
198 | if (!this.isLoggedIn()) {
199 | throw new LoginError("You must log in to your account.");
200 | }
201 |
202 | const headers = {...Core.jsonHeaders};
203 | headers["accesstoken"] = this.getLoginData()["accessToken"];
204 |
205 | const cookies = this.__loginData["cookies"];
206 |
207 | const response = new APIRequest(Core.bookmarksUrl, null, headers, null, cookies);
208 | await response.receive();
209 |
210 | return await response.getContent();
211 | }
212 |
213 | /**
214 | * Convert coordinate dictionary to a string "y1, y2, x1, x2".
215 | *
216 | * @param {object} zone - Dictionary containing the following keys: tl_y, tl_x, br_y, br_x
217 | * @return {string}
218 | */
219 | getBounds(zone) {
220 | return "" + zone["tl_y"] + "," + zone["br_y"] + "," + zone["tl_x"] + "," + zone["br_x"];
221 | }
222 |
223 | /**
224 | * Convert a point coordinate and a radius to a string "y1, y2, x1, x2".
225 | *
226 | * @param {number} latitude - Latitude of the point
227 | * @param {number} longitude - Longitude of the point
228 | * @param {number} radius - Radius in meters to create area around the point
229 | * @return {string}
230 | */
231 | getBoundsByPoint(latitude, longitude, radius) {
232 | const halfSideInKm = Math.abs(radius) / 1000;
233 |
234 | Math.rad2deg = (x) => x * (180 / Math.PI);
235 | Math.radians = (x) => x * (Math.PI / 180);
236 |
237 | const lat = Math.radians(latitude);
238 | const lon = Math.radians(longitude);
239 |
240 | const approxEarthRadius = 6371;
241 | const hypotenuseDistance = Math.sqrt(2 * (Math.pow(halfSideInKm, 2)));
242 |
243 | const latMin = Math.asin(
244 | Math.sin(lat) * Math.cos(hypotenuseDistance / approxEarthRadius) +
245 | Math.cos(lat) *
246 | Math.sin(hypotenuseDistance / approxEarthRadius) *
247 | Math.cos(225 * (Math.PI / 180)),
248 | );
249 | const lonMin = lon + Math.atan2(
250 | Math.sin(225 * (Math.PI / 180)) *
251 | Math.sin(hypotenuseDistance / approxEarthRadius) *
252 | Math.cos(lat),
253 | Math.cos(hypotenuseDistance / approxEarthRadius) -
254 | Math.sin(lat) * Math.sin(latMin),
255 | );
256 |
257 | const latMax = Math.asin(
258 | Math.sin(lat) * Math.cos(hypotenuseDistance / approxEarthRadius) +
259 | Math.cos(lat) *
260 | Math.sin(hypotenuseDistance / approxEarthRadius) *
261 | Math.cos(45 * (Math.PI / 180)),
262 | );
263 | const lonMax = lon + Math.atan2(
264 | Math.sin(45 * (Math.PI / 180)) *
265 | Math.sin(hypotenuseDistance / approxEarthRadius) *
266 | Math.cos(lat),
267 | Math.cos(hypotenuseDistance / approxEarthRadius) -
268 | Math.sin(lat) * Math.sin(latMax),
269 | );
270 |
271 | const zone = {
272 | "tl_y": Math.rad2deg(latMax),
273 | "br_y": Math.rad2deg(latMin),
274 | "tl_x": Math.rad2deg(lonMin),
275 | "br_x": Math.rad2deg(lonMax),
276 | };
277 | return this.getBounds(zone);
278 | }
279 |
280 | /**
281 | * Download the flag of a country from FlightRadar24 and return it as bytes.
282 | *
283 | * @param {string} country - Country name
284 | * @return {[object, string]}
285 | */
286 | async getCountryFlag(country) {
287 | const flagUrl = Core.countryFlagUrl.format(country.toLowerCase().replace(" ", "-"));
288 | const headers = {...Core.imageHeaders};
289 |
290 | if (headers.hasOwnProperty("origin")) {
291 | delete headers["origin"]; // Does not work for this request.
292 | }
293 |
294 | const response = new APIRequest(flagUrl, null, headers);
295 | await response.receive();
296 |
297 | const statusCode = response.getStatusCode();
298 |
299 | if (!statusCode.toString().startsWith("4")) {
300 | const splitUrl = flagUrl.split(".");
301 | return [(await response.getContent()), splitUrl[splitUrl.length - 1]];
302 | }
303 | }
304 |
305 | /**
306 | * Return the flight details from Data Live FlightRadar24.
307 | *
308 | * @param {Flight} flight - A Flight instance
309 | * @return {object}
310 | */
311 | async getFlightDetails(flight) {
312 | const response = new APIRequest(Core.flightDataUrl.format(flight.id), null, Core.jsonHeaders);
313 | await response.receive();
314 |
315 | return (await response.getContent());
316 | }
317 |
318 | /**
319 | * Return a list of flights. See more options at setFlightTrackerConfig() method.
320 | *
321 | * @param {string} [airline] - The airline ICAO. Ex: "DAL"
322 | * @param {string} [bounds] - Coordinates (y1, y2 ,x1, x2). Ex: "75.78,-75.78,-427.56,427.56"
323 | * @param {string} [registration] - Aircraft registration
324 | * @param {string} [aircraftType] - Aircraft model code. Ex: "B737"
325 | * @param {boolean} [details] - If true, it returns flights with detailed information
326 | * @return {Array}
327 | */
328 | async getFlights(airline = null, bounds = null, registration = null, aircraftType = null, details = false) {
329 | const requestParams = {...this.__flightTrackerConfig};
330 |
331 | if (this.__loginData != null) {
332 | requestParams["enc"] = this.__loginData["cookies"]["_frPl"];
333 | }
334 |
335 | // Insert the method parameters into the dictionary for the request.
336 | if (airline != null) {
337 | requestParams["airline"] = airline;
338 | }
339 | if (bounds != null) {
340 | requestParams["bounds"] = bounds.replace(",", "%2C");
341 | }
342 | if (registration != null) {
343 | requestParams["reg"] = registration;
344 | }
345 | if (aircraftType != null) {
346 | requestParams["type"] = aircraftType;
347 | }
348 |
349 | // Get all flights from Data Live FlightRadar24.
350 | const response = new APIRequest(Core.realTimeFlightTrackerDataUrl, requestParams, Core.jsonHeaders);
351 | await response.receive();
352 |
353 | const content = await response.getContent();
354 | const flights = [];
355 |
356 | for (const flightId in content) {
357 | if (!Object.prototype.hasOwnProperty.call(content, flightId)) { // guard-for-in
358 | continue;
359 | }
360 |
361 | const flightInfo = content[flightId];
362 |
363 | // Get flights only.
364 | if (!isNumeric(flightId[0])) {
365 | continue;
366 | }
367 |
368 | const flight = new Flight(flightId, flightInfo);
369 | flights.push(flight);
370 |
371 | // Set flight details.
372 | if (details) {
373 | const flightDetails = await this.getFlightDetails(flight);
374 | flight.setFlightDetails(flightDetails);
375 | }
376 | }
377 |
378 | return flights;
379 | }
380 |
381 | /**
382 | * Return a copy of the current config of the Real Time Flight Tracker, used by getFlights() method.
383 | *
384 | * @return {FlightTrackerConfig}
385 | */
386 | getFlightTrackerConfig() {
387 | return new FlightTrackerConfig({...this.__flightTrackerConfig});
388 | }
389 |
390 | /**
391 | * Download historical data of a flight.
392 | *
393 | * @param {Flight} flight - A Flight instance.
394 | * @param {string} fileType - Must be "CSV" or "KML"
395 | * @param {number} timestamp - A Unix timestamp
396 | */
397 | async getHistoryData(flight, fileType, timestamp) {
398 | if (!this.isLoggedIn()) {
399 | throw new LoginError("You must log in to your account.");
400 | }
401 |
402 | fileType = fileType.toLowerCase();
403 |
404 | if (!["csv", "kml"].includes(fileType)) {
405 | throw new Error("File type '" + fileType + "' is not supported. Only CSV and KML are supported.");
406 | }
407 |
408 | const response = new APIRequest(
409 | Core.historicalDataUrl.format(flight.id, fileType, timestamp),
410 | null, Core.jsonHeaders, null, self.__loginData["cookies"],
411 | );
412 | await response.receive();
413 |
414 | const content = await response.getContent();
415 | return content;
416 | }
417 |
418 | /**
419 | * Return the user data.
420 | *
421 | * @return {object}
422 | */
423 | getLoginData() {
424 | if (!this.isLoggedIn()) {
425 | throw new LoginError("You must log in to your account.");
426 | }
427 | return {...this.__loginData["userData"]};
428 | }
429 |
430 | /**
431 | * Return the most tracked data.
432 | *
433 | * @return {object}
434 | */
435 | async getMostTracked() {
436 | const response = new APIRequest(Core.mostTrackedUrl, null, Core.jsonHeaders);
437 | await response.receive();
438 |
439 | return await response.getContent();
440 | }
441 |
442 | /**
443 | * Return boundaries of volcanic eruptions and ash clouds impacting aviation.
444 | *
445 | * @return {object}
446 | */
447 | async getVolcanicEruptions() {
448 | const response = new APIRequest(Core.volcanicEruptionDataUrl, null, Core.jsonHeaders);
449 | await response.receive();
450 |
451 | return await response.getContent();
452 | }
453 |
454 | /**
455 | * Return all major zones on the globe.
456 | *
457 | * @return {object}
458 | */
459 | async getZones() {
460 | const response = new APIRequest(Core.zonesDataUrl, null, Core.jsonHeaders);
461 | await response.receive();
462 |
463 | const zones = await response.getContent();
464 |
465 | if (zones.hasOwnProperty("version")) {
466 | delete zones["version"];
467 | }
468 | return zones;
469 | }
470 |
471 | /**
472 | * Return the search result.
473 | *
474 | * @param {string} query
475 | * @param {number} [limit=50]
476 | * @return {object}
477 | */
478 | async search(query, limit = 50) {
479 | const url = Core.searchDataUrl.format(query, limit);
480 |
481 | const response = new APIRequest(url, null, Core.jsonHeaders);
482 | await response.receive();
483 |
484 | const content = await response.getContent();
485 |
486 | let results = content["results"];
487 | results = results == null ? [] : results;
488 |
489 | let stats = content["stats"];
490 | stats = stats == null ? {} : stats;
491 |
492 | let countDict = stats["count"];
493 | countDict = countDict == null ? {} : countDict;
494 |
495 | let index = 0;
496 | let countedTotal = 0;
497 |
498 | const data = {};
499 |
500 | for (const name in countDict) {
501 | if (!Object.prototype.hasOwnProperty.call(countDict, name)) { // guard-for-in
502 | continue;
503 | }
504 |
505 | const count = countDict[name];
506 |
507 | data[name] = [];
508 |
509 | while (index < (countedTotal + count) && (index < results.length)) {
510 | data[name].push(results[index]);
511 | index++;
512 | }
513 | countedTotal += count;
514 | }
515 |
516 | return data;
517 | }
518 |
519 | /**
520 | * Check if the user is logged into the FlightRadar24 account.
521 | *
522 | * @return {boolean}
523 | */
524 | isLoggedIn() {
525 | return this.__loginData != null;
526 | }
527 |
528 | /**
529 | * Log in to a FlightRadar24 account.
530 | *
531 | * @param {string} user - Your email.
532 | * @param {string} password - Your password.
533 | * @return {undefined}
534 | */
535 | async login(user, password) {
536 | const data = {
537 | "email": user,
538 | "password": password,
539 | "remember": "true",
540 | "type": "web",
541 | };
542 |
543 | const response = new APIRequest(Core.userLoginUrl, null, Core.jsonHeaders, data);
544 | await response.receive();
545 |
546 | const statusCode = response.getStatusCode();
547 | const content = await response.getContent();
548 |
549 | if (!statusCode.toString().startsWith("2") || !content["success"]) {
550 | if (typeof content === "object") {
551 | throw new LoginError(content["message"]);
552 | }
553 | else {
554 | throw new LoginError("Your email or password is incorrect");
555 | }
556 | }
557 |
558 | this.__loginData = {
559 | "userData": content["userData"],
560 | "cookies": response.getCookies(),
561 | };
562 | }
563 |
564 | /**
565 | * Log out of the FlightRadar24 account.
566 | *
567 | * @return {boolean} - Return a boolean indicating that it successfully logged out of the server.
568 | */
569 | async logout() {
570 | if (this.__loginData == null) {
571 | return true;
572 | }
573 |
574 | const cookies = this.__loginData["cookies"];
575 | this.__loginData = null;
576 |
577 | const response = new APIRequest(Core.userLoginUrl, null, Core.jsonHeaders, null, cookies);
578 | await response.receive();
579 |
580 | return response.getStatusCode().toString().startsWith("2");
581 | }
582 |
583 | /**
584 | * Set config for the Real Time Flight Tracker, used by getFlights() method.
585 | *
586 | * @param {FlightTrackerConfig} [flightTrackerConfig] - If null, set to the default config.
587 | * @param {object} [config={}] - Config as an JSON object
588 | * @return {undefined}
589 | */
590 | async setFlightTrackerConfig(flightTrackerConfig = null, config = {}) {
591 | if (flightTrackerConfig != null) {
592 | this.__flightTrackerConfig = flightTrackerConfig;
593 | }
594 |
595 | for (const key in config) {
596 | if (Object.prototype.hasOwnProperty.call(config, key)) { // guard-for-in
597 | const value = config[key].toString();
598 | this.__flightTrackerConfig[key] = value;
599 | }
600 | }
601 | }
602 | }
603 |
604 | module.exports = FlightRadar24API;
605 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/core.js:
--------------------------------------------------------------------------------
1 | String.prototype.format = function() {
2 | const args = arguments;
3 | let index = 0;
4 |
5 | return this.replace(/{}/g, function(match, position) {
6 | return (typeof args[index] == "undefined") ? match : args[index++];
7 | });
8 | };
9 |
10 |
11 | /**
12 | * Class which contains all URLs used by the package.
13 | */
14 | class Core {
15 | /**
16 | * Constructor of the Core class
17 | */
18 | constructor() {
19 | this.apiFlightradarBaseUrl = "https://api.flightradar24.com/common/v1";
20 | this.cdnFlightradarBaseUrl = "https://cdn.flightradar24.com";
21 | this.flightRadarBaseUrl = "https://www.flightradar24.com";
22 | this.dataLiveBaseUrl = "https://data-live.flightradar24.com";
23 | this.dataCloudBaseUrl = "https://data-cloud.flightradar24.com";
24 |
25 | // User login URL.
26 | this.userLoginUrl = this.flightRadarBaseUrl + "/user/login";
27 | this.userLogoutUrl = this.flightRadarBaseUrl + "/user/logout";
28 |
29 | // Search data URL
30 | this.searchDataUrl = this.flightRadarBaseUrl + "/v1/search/web/find?query={}&limit={}";
31 |
32 | // Flights data URLs.
33 | this.realTimeFlightTrackerDataUrl = this.dataCloudBaseUrl + "/zones/fcgi/feed.js";
34 | this.flightDataUrl = this.dataLiveBaseUrl + "/clickhandler/?flight={}";
35 |
36 | // Historical data URL.
37 | this.historicalDataUrl = this.flightradarBaseUrl + "/download/?flight={}&file={}&trailLimit=0&history={}";
38 |
39 | // Airports data URLs.
40 | this.apiAirportDataUrl = this.apiFlightradarBaseUrl + "/airport.json";
41 | this.airportDataUrl = this.flightRadarBaseUrl + "/airports/traffic-stats/?airport={}";
42 | this.airportsDataUrl = this.flightRadarBaseUrl + "/_json/airports.php";
43 |
44 | // Airlines data URL.
45 | this.airlinesDataUrl = this.flightRadarBaseUrl + "/_json/airlines.php";
46 |
47 | // Zones data URL.
48 | this.zonesDataUrl = this.flightRadarBaseUrl + "/js/zones.js.php";
49 |
50 | // Weather data URL.
51 | this.volcanicEruptionDataUrl = this.flightRadarBaseUrl + "/weather/volcanic";
52 |
53 | // Most tracked URL
54 | this.mostTrackedUrl = this.flightRadarBaseUrl + "/flights/most-tracked";
55 |
56 | // Airport disruptions URL.
57 | this.airportDisruptionsUrl = this.flightRadarBaseUrl + "/webapi/v1/airport-disruptions";
58 |
59 | // Bookmarks URL.
60 | this.bookmarksUrl = this.flightRadarBaseUrl + "/webapi/v1/bookmarks";
61 |
62 | // Country flag image URL.
63 | this.countryFlagUrl = this.flightRadarBaseUrl + "/static/images/data/flags-small/{}.svg";
64 |
65 | // Airline logo image URL.
66 | this.airlineLogoUrl = this.cdnFlightradarBaseUrl + "/assets/airlines/logotypes/{}_{}.png";
67 | this.alternativeAirlineLogoUrl = this.flightRadarBaseUrl + "/static/images/data/operators/{}_logo0.png";
68 |
69 | this.headers = {
70 | "accept-encoding": "gzip, br",
71 | "accept-language": "pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7",
72 | "cache-control": "max-age=0",
73 | "origin": "https://www.flightradar24.com",
74 | "referer": "https://www.flightradar24.com/",
75 | "sec-fetch-dest": "empty",
76 | "sec-fetch-mode": "cors",
77 | "sec-fetch-site": "same-site",
78 | "user-agent": "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36",
79 | };
80 |
81 | this.jsonHeaders = {accept: "application/json", ...this.headers};
82 |
83 | this.imageHeaders = {accept: "image/gif, image/jpg, image/jpeg, image/png", ...this.headers};
84 | }
85 | }
86 |
87 | module.exports = new Core();
88 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/entities/airport.js:
--------------------------------------------------------------------------------
1 | const Entity = require("./entity");
2 |
3 |
4 | /**
5 | * Airport representation.
6 | */
7 | class Airport extends Entity {
8 | /**
9 | * Constructor of Airport class.
10 | *
11 | * The parameters below are optional. You can just create an Airport instance with no information
12 | * and use the setAirportDetails(...) method for having an instance with detailed information.
13 | *
14 | * @param {object} [basicInfo] - Basic information about the airport received from FlightRadar24
15 | * @param {object} [info] - Dictionary with more information about the airport received from FlightRadar24
16 | */
17 | constructor(basicInfo = {}, info = {}) {
18 | super();
19 |
20 | if (basicInfo && Object.keys(basicInfo).length > 0) {
21 | this.__setPosition(basicInfo["lat"], basicInfo["lon"]);
22 | this.__initializeWithBasicInfo(basicInfo);
23 | }
24 |
25 | if (info && Object.keys(info).length > 0) {
26 | this.__setPosition(info["position"]["latitude"], info["position"]["longitude"]);
27 | this.__initializeWithInfo(info);
28 | }
29 | }
30 |
31 | /**
32 | * Initialize instance with basic information about the airport.
33 | *
34 | * @param {object} basicInfo
35 | */
36 | __initializeWithBasicInfo(basicInfo) {
37 | this.altitude = basicInfo["alt"];
38 |
39 | this.name = basicInfo["name"];
40 | this.icao = basicInfo["icao"];
41 | this.iata = basicInfo["iata"];
42 |
43 | this.country = basicInfo["country"];
44 | }
45 |
46 | /**
47 | * Initialize instance with extra information about the airport.
48 | *
49 | * @param {object} info
50 | */
51 | __initializeWithInfo(info) {
52 | this.altitude = info["position"]["altitude"];
53 |
54 | this.name = info["name"];
55 | this.icao = info["code"]["icao"];
56 | this.iata = info["code"]["iata"];
57 |
58 | // Location information.
59 | const position = info["position"];
60 |
61 | this.country = position["country"]["name"];
62 | this.countryCode = this.__getInfo(position["country"]?.["code"]);
63 | this.city = this.__getInfo(position["region"]?.["city"]);
64 |
65 | // Timezone information.
66 | const timezone = info["timezone"];
67 |
68 | this.timezoneName = this.__getInfo(timezone?.["name"]);
69 | this.timezoneOffset = this.__getInfo(timezone?.["offset"]);
70 | this.timezoneOffsetHours = this.__getInfo(timezone?.["offsetHours"]);
71 | this.timezoneAbbr = this.__getInfo(timezone?.["abbr"]);
72 | this.timezoneAbbrName = this.__getInfo(timezone?.["abbrName"]);
73 |
74 | // Other information.
75 | this.visible = this.__getInfo(info["visible"]);
76 | this.website = this.__getInfo(info["website"]);
77 | }
78 |
79 | /**
80 | * Set airport details to the instance. Use FlightRadar24API.getAirportDetails(...) method to get it.
81 | *
82 | * @param {object} airportDetails
83 | */
84 | setAirportDetails(airportDetails) {
85 | // Get airport data.
86 | const airport = airportDetails?.["airport"]?.["pluginData"];
87 |
88 | // Get information about the airport.
89 | const details = airport?.["details"];
90 |
91 | // Get location information.
92 | const position = details?.["position"];
93 | const code = details?.["code"];
94 | const country = position?.["country"];
95 | const region = position?.["region"];
96 |
97 | // Get reviews of the airport.
98 | const flightDiary = airport?.["flightdiary"];
99 | const ratings = flightDiary?.["ratings"];
100 |
101 | // Get schedule information.
102 | const schedule = airport?.["schedule"];
103 |
104 | // Get timezone information.
105 | const timezone = details?.["timezone"];
106 |
107 | // Get aircraft count.
108 | const aircraftCount = airport?.["aircraftCount"];
109 | const aircraftOnGround = aircraftCount?.["onGround"];
110 |
111 | // Get URLs for more information about the airport.
112 | const urls = details?.["url"];
113 |
114 | // Basic airport information.
115 | this.name = this.__getInfo(details?.["name"]);
116 | this.iata = this.__getInfo(code?.["iata"]);
117 | this.icao = this.__getInfo(code?.["icao"]);
118 | this.altitude = this.__getInfo(position?.["elevation"]);
119 | this.latitude = this.__getInfo(position?.["latitude"]);
120 | this.longitude = this.__getInfo(position?.["longitude"]);
121 |
122 | // Airport location.
123 | this.country = this.__getInfo(country?.["name"]);
124 | this.country_code = this.__getInfo(country?.["code"]);
125 | this.country_id = this.__getInfo(country?.["id"]);
126 | this.city = this.__getInfo(region?.["city"]);
127 |
128 | // Airport timezone.
129 | this.timezoneAbbr = this.__getInfo(timezone?.["abbr"]);
130 | this.timezoneAbbrName = this.__getInfo(timezone?.["abbrName"]);
131 | this.timezoneName = this.__getInfo(timezone?.["name"]);
132 | this.timezoneOffset = this.__getInfo(timezone?.["offset"]);
133 |
134 | if (typeof this.timezoneOffset === "number") {
135 | this.timezoneOffsetHours = Math.trunc(this.timezoneOffset / 60 / 60);
136 | this.timezoneOffsetHours = this.timezoneOffsetHours + ":00";
137 | }
138 | else {
139 | this.timezoneOffsetHours = this.__getInfo(None);
140 | }
141 |
142 | // Airport reviews.
143 | this.reviewsUrl = flightDiary?.["url"];
144 |
145 | if (this.reviewsUrl && typeof this.reviewsUrl === "string") {
146 | this.reviewsUrl = "https://www.flightradar24.com" + this.reviewsUrl;
147 | }
148 | else {
149 | this.reviewsUrl = this.__getInfo(this.reviewsUrl);
150 | }
151 |
152 | this.reviews = this.__getInfo(flightDiary?.["reviews"]);
153 | this.evaluation = this.__getInfo(flightDiary?.["evaluation"]);
154 |
155 | this.averageRating = this.__getInfo(ratings?.["avg"]);
156 | this.totalRating = this.__getInfo(ratings?.["total"]);
157 |
158 | // Weather information.
159 | this.weather = this.__getInfo(airport?.["weather"], {});
160 |
161 | // Runway information.
162 | this.runways = this.__getInfo(airport?.["runways"], []);
163 |
164 | // Aircraft count information.
165 | this.aircraftOnGround = this.__getInfo(aircraftOnGround?.["total"]);
166 | this.aircraftVisibleOnGround = this.__getInfo(aircraftOnGround?.["visible"]);
167 |
168 | // Schedule information.
169 | this.arrivals = this.__getInfo(schedule?.["arrivals"], {});
170 | this.departures = this.__getInfo(schedule?.["departures"], {});
171 |
172 | // Link for the homepage and more information
173 | this.website = this.__getInfo(urls?.["homepage"]);
174 | this.wikipedia = this.__getInfo(urls?.["wikipedia"]);
175 |
176 | // Other information.
177 | this.visible = this.__getInfo(details?.["visible"]);
178 | this.images = this.__getInfo(details?.["airportImages"], {});
179 | }
180 | }
181 |
182 | module.exports = Airport;
183 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/entities/entity.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Representation of a real entity, at some location.
3 | */
4 | class Entity {
5 | static __defaultText = "N/A";
6 |
7 | /**
8 | * Constructor of Entity class.
9 | *
10 | * @param {number} latitude
11 | * @param {number} longitude
12 | */
13 | constructor(latitude = null, longitude = null) {
14 | this.__setPosition(latitude, longitude);
15 | }
16 |
17 | __setPosition(latitude, longitude) {
18 | this.latitude = latitude;
19 | this.longitude = longitude;
20 | }
21 |
22 | __getInfo(info, replaceBy = undefined) {
23 | replaceBy = replaceBy === undefined ? this.__defaultText : replaceBy;
24 | return (info || info === 0) && (info !== this.__defaultText) ? info : replaceBy;
25 | }
26 |
27 | /**
28 | * Return the distance from another entity (in kilometers).
29 | *
30 | * @param {Entity} entity
31 | * @return {number}
32 | */
33 | getDistanceFrom(entity) {
34 | Math.radians = (x) => x * (Math.PI / 180);
35 |
36 | const lat1 = Math.radians(this.latitude);
37 | const lon1 = Math.radians(this.longitude);
38 |
39 | const lat2 = Math.radians(entity.latitude);
40 | const lon2 = Math.radians(entity.longitude);
41 |
42 | return Math.acos(Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)) * 6371;
43 | }
44 | }
45 |
46 | module.exports = Entity;
47 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/entities/flight.js:
--------------------------------------------------------------------------------
1 | const Entity = require("./entity");
2 |
3 | /**
4 | * Flight representation.
5 | */
6 | class Flight extends Entity {
7 | /**
8 | * Constructor of Flight class.
9 | *
10 | * @param {*} flightId - The flight ID specifically used by FlightRadar24
11 | * @param {*} info - Dictionary with received data from FlightRadar24
12 | */
13 | constructor(flightId, info) {
14 | super();
15 |
16 | this.__setPosition(this.__getInfo(info[1]), this.__getInfo(info[2]));
17 |
18 | this.id = flightId;
19 | this.icao24bit = this.__getInfo(info[0]);
20 | this.heading = this.__getInfo(info[3]);
21 | this.altitude = this.__getInfo(info[4]);
22 | this.groundSpeed = this.__getInfo(info[5]);
23 | this.squawk = this.__getInfo(info[6]);
24 | this.aircraftCode = this.__getInfo(info[8]);
25 | this.registration = this.__getInfo(info[9]);
26 | this.time = this.__getInfo(info[10]);
27 | this.originAirportIata = this.__getInfo(info[11]);
28 | this.destinationAirportIata = this.__getInfo(info[12]);
29 | this.number = this.__getInfo(info[13]);
30 | this.airlineIata = this.__getInfo(info[13].slice(0, 2));
31 | this.onGround = this.__getInfo(info[14]);
32 | this.verticalSpeed =this.__getInfo(info[15]);
33 | this.callsign = this.__getInfo(info[16]);
34 | this.airlineIcao = this.__getInfo(info[18]);
35 | }
36 |
37 | /**
38 | * Check one or more flight information.
39 | *
40 | * You can use the prefix "max" or "min" in the parameter
41 | * to compare numeric data with ">" or "<".
42 | *
43 | * Example: checkInfo({minAltitude: 6700, maxAltitude: 13000, airlineIcao: "THY"})
44 | *
45 | * @param {object} info
46 | * @return {boolean}
47 | */
48 | checkInfo(info) {
49 | const comparisonFunctions = {"max": Math.max, "min": Math.min};
50 |
51 | for (let key in info) {
52 | if (!Object.prototype.hasOwnProperty.call(info, key)) { // guard-for-in
53 | continue;
54 | }
55 |
56 | let prefix = key.slice(0, 3);
57 | const value = info[key];
58 |
59 | // Separate the comparison prefix if it exists.
60 | if ((prefix === "max") || (prefix === "min")) {
61 | key = key[3].toLowerCase() + key.slice(4, key.length);
62 | }
63 | else {
64 | prefix = null;
65 | }
66 |
67 | // Check if the value is greater than or less than the attribute value.
68 | if (this.hasOwnProperty(key) && prefix) {
69 | if (comparisonFunctions[prefix](value, this[key]) !== value) {
70 | return false;
71 | }
72 | }
73 |
74 | // Check if the value is equal.
75 | else if (this.hasOwnProperty(key) && value !== this[key]) {
76 | return false;
77 | }
78 | }
79 | return true;
80 | }
81 |
82 | /**
83 | * Return the formatted altitude, with the unit of measure.
84 | *
85 | * @return {string}
86 | */
87 | getAltitude() {
88 | return this.altitude.toString() + " ft";
89 | }
90 |
91 | /**
92 | * Return the formatted flight level, with the unit of measure.
93 | *
94 | * @return {string}
95 | */
96 | getFlightLevel() {
97 | if (this.altitude >= 10000) {
98 | return this.altitude.toString().slice(0, 3) + " FL";
99 | }
100 | return this.getAltitude();
101 | }
102 |
103 | /**
104 | * Return the formatted ground speed, with the unit of measure.
105 | *
106 | * @return {string}
107 | */
108 | getGroundSpeed() {
109 | const sufix = this.groundSpeed > 1 ? "s" : "";
110 | return this.groundSpeed.toString() + " kt" + sufix;
111 | }
112 |
113 | /**
114 | * Return the formatted heading, with the unit of measure.
115 | *
116 | * @return {string}
117 | */
118 | getHeading() {
119 | return this.heading.toString() + "°";
120 | }
121 |
122 | /**
123 | * Return the formatted vertical speed, with the unit of measure.
124 | *
125 | * @return {string}
126 | */
127 | getVerticalSpeed() {
128 | return this.verticalSpeed.toString() + " fpm";
129 | }
130 |
131 | /**
132 | * Set flight details to the instance. Use FlightRadar24API.getFlightDetails(...) method to get it.
133 | *
134 | * @param {object} flightDetails
135 | * @return {undefined}
136 | */
137 | setFlightDetails(flightDetails) {
138 | // Get aircraft data.
139 | const aircraft = flightDetails["aircraft"];
140 |
141 | // Get airline data.
142 | const airline = flightDetails?.["airline"];
143 |
144 | // Get airport data.
145 | const airport = flightDetails?.["airport"];
146 |
147 | // Get destination data.
148 | const destAirport = airport?.["destination"];
149 | const destAirportCode = destAirport?.["code"];
150 | const destAirportInfo = destAirport?.["info"];
151 | const destAirportPosition = destAirport?.["position"];
152 | const destAirportCountry = destAirportPosition?.["country"];
153 | const destAirportTimezone = destAirport?.["timezone"];
154 |
155 | // Get origin data.
156 | const origAirport = airport?.["origin"];
157 | const origAirportCode = origAirport?.["code"];
158 | const origAirportInfo = origAirport?.["info"];
159 | const origAirportPosition = origAirport?.["position"];
160 | const origAirportCountry = origAirportPosition?.["country"];
161 | const origAirportTimezone = origAirport?.["timezone"];
162 |
163 | // Get flight history.
164 | const history = flightDetails?.["flightHistory"];
165 |
166 | // Get flight status.
167 | const status = flightDetails?.["status"];
168 |
169 | // Aircraft information.
170 | this.aircraftAge = this.__getInfo(aircraft?.["age"]);
171 | this.aircraftCountryId = this.__getInfo(aircraft?.["countryId"]);
172 | this.aircraftHistory = this.__getInfo(history?.["aircraft"], []);
173 | this.aircraftImages = this.__getInfo(aircraft?.["images"], []);
174 | this.aircraftModel = this.__getInfo(aircraft?.["model"]?.["text"]);
175 |
176 | // Airline information.
177 | this.airlineName = this.__getInfo(airline?.["name"]);
178 | this.airlineShortName = this.__getInfo(airline?.["short"]);
179 |
180 | // Destination airport position.
181 | this.destinationAirportAltitude = this.__getInfo(destAirportPosition?.["altitude"]);
182 | this.destinationAirportCountryCode = this.__getInfo(destAirportCountry?.["code"]);
183 | this.destinationAirportCountryName = this.__getInfo(destAirportCountry?.["name"]);
184 | this.destinationAirportLatitude = this.__getInfo(destAirportPosition?.["latitude"]);
185 | this.destinationAirportLongitude = this.__getInfo(destAirportPosition?.["longitude"]);
186 |
187 | // Destination airport information.
188 | this.destinationAirportIcao = this.__getInfo(destAirportCode?.["icao"]);
189 | this.destinationAirportBaggage = this.__getInfo(destAirportInfo?.["baggage"]);
190 | this.destinationAirportGate = this.__getInfo(destAirportInfo?.["gate"]);
191 | this.destinationAirportName = this.__getInfo(destAirport?.["name"]);
192 | this.destinationAirportTerminal = this.__getInfo(destAirportInfo?.["terminal"]);
193 | this.destinationAirportVisible = this.__getInfo(destAirport?.["visible"]);
194 | this.destinationAirportWebsite = this.__getInfo(destAirport?.["website"]);
195 |
196 | // Destination airport timezone.
197 | this.destinationAirportTimezoneAbbr = this.__getInfo(destAirportTimezone?.["abbr"]);
198 | this.destinationAirportTimezoneAbbrName = this.__getInfo(destAirportTimezone?.["abbrName"]);
199 | this.destinationAirportTimezoneName = this.__getInfo(destAirportTimezone?.["name"]);
200 | this.destinationAirportTimezoneOffset = this.__getInfo(destAirportTimezone?.["offset"]);
201 | this.destinationAirportTimezoneOffsetHours = this.__getInfo(destAirportTimezone?.["offsetHours"]);
202 |
203 | // Origin airport position.
204 | this.originAirportAltitude = this.__getInfo(origAirportPosition?.["altitude"]);
205 | this.originAirportCountryCode = this.__getInfo(origAirportCountry?.["code"]);
206 | this.originAirportCountryName = this.__getInfo(origAirportCountry?.["name"]);
207 | this.originAirportLatitude = this.__getInfo(origAirportPosition?.["latitude"]);
208 | this.originAirportLongitude = this.__getInfo(origAirportPosition?.["longitude"]);
209 |
210 | // Origin airport information.
211 | this.originAirportIcao = this.__getInfo(origAirportCode?.["icao"]);
212 | this.originAirportBaggage = this.__getInfo(origAirportInfo?.["baggage"]);
213 | this.originAirportGate = this.__getInfo(origAirportInfo?.["gate"]);
214 | this.originAirportName = this.__getInfo(origAirport?.["name"]);
215 | this.originAirportTerminal = this.__getInfo(origAirportInfo?.["terminal"]);
216 | this.originAirportVisible = this.__getInfo(origAirport?.["visible"]);
217 | this.originAirportWebsite = this.__getInfo(origAirport?.["website"]);
218 |
219 | // Origin airport timezone.
220 | this.originAirportTimezoneAbbr = this.__getInfo(origAirportTimezone?.["abbr"]);
221 | this.originAirportTimezoneAbbrName = this.__getInfo(origAirportTimezone?.["abbrName"]);
222 | this.originAirportTimezoneName = this.__getInfo(origAirportTimezone?.["name"]);
223 | this.originAirportTimezoneOffset = this.__getInfo(origAirportTimezone?.["offset"]);
224 | this.originAirportTimezoneOffsetHours = this.__getInfo(origAirportTimezone?.["offsetHours"]);
225 |
226 | // Flight status.
227 | this.statusIcon = this.__getInfo(status?.["icon"]);
228 | this.statusText = this.__getInfo(status?.["text"]);
229 |
230 | // Time details.
231 | this.timeDetails = this.__getInfo(flightDetails?.["time"], {});
232 |
233 | // Flight trail.
234 | this.trail = this.__getInfo(flightDetails?.["trail"], []);
235 | }
236 | }
237 |
238 | module.exports = Flight;
239 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/errors.js:
--------------------------------------------------------------------------------
1 | class AirportNotFoundError extends Error {
2 | constructor(message) {
3 | super(message);
4 |
5 | this.name = this.constructor.name;
6 |
7 | Error.captureStackTrace(this, this.constructor);
8 | }
9 | }
10 |
11 | class CloudflareError extends Error {
12 | constructor(message, response) {
13 | super(message);
14 |
15 | this.name = this.constructor.name;
16 | this.response = response;
17 |
18 | Error.captureStackTrace(this, this.constructor);
19 | }
20 | }
21 |
22 | class LoginError extends Error {
23 | constructor(message) {
24 | super(message);
25 |
26 | this.name = this.constructor.name;
27 |
28 | Error.captureStackTrace(this, this.constructor);
29 | }
30 | }
31 |
32 | module.exports = {AirportNotFoundError, CloudflareError, LoginError};
33 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/flightTrackerConfig.js:
--------------------------------------------------------------------------------
1 | const {isNumeric} = require("./util");
2 |
3 |
4 | const proxyHandler = {
5 | set: function(target, key, value) {
6 | if (!target.hasOwnProperty(key)) {
7 | throw new Error("Unknown option: '" + key + "'");
8 | }
9 | if ((typeof value !== "number") && (!isNumeric(value))) {
10 | throw new Error("Value must be a decimal. Got '" + key + "'");
11 | }
12 | target[key] = value.toString();
13 | },
14 | };
15 |
16 |
17 | /**
18 | * Data class with settings of the Real Time Flight Tracker.
19 | */
20 | class FlightTrackerConfig {
21 | faa = "1";
22 | satellite = "1";
23 | mlat = "1";
24 | flarm = "1";
25 | adsb = "1";
26 | gnd = "1";
27 | air = "1";
28 | vehicles = "1";
29 | estimated = "1";
30 | maxage = "14400";
31 | gliders = "1";
32 | stats = "1";
33 | limit = "5000";
34 |
35 | /**
36 | * Constructor of FlighTrackerConfig class.
37 | *
38 | * @param {object} data
39 | */
40 | constructor(data) {
41 | for (const key in data) {
42 | if (!Object.prototype.hasOwnProperty.call(data, key)) { // guard-for-in
43 | continue;
44 | }
45 | const value = data[key];
46 |
47 | if (this.hasOwnProperty(key) && (typeof value === "number" || isNumeric(value))) {
48 | this[key] = value;
49 | }
50 | }
51 | return new Proxy(this, proxyHandler);
52 | }
53 | }
54 |
55 | module.exports = FlightTrackerConfig;
56 |
--------------------------------------------------------------------------------
/nodejs/FlightRadar24/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Main class of the FlightRadarAPI
3 | */
4 | export class FlightRadar24API {
5 | private __flightTrackerConfig: FlightTrackerConfig;
6 | private __loginData: {userData: any; cookies: any;} | null;
7 |
8 | /**
9 | * Constructor of FlightRadar24API class
10 | */
11 | constructor();
12 |
13 | /**
14 | * Return a list with all airlines.
15 | */
16 | getAirlines(): Promise