├── .gitignore ├── images ├── demo.png └── icon.png ├── manifest.json ├── Privacy-Policy.md ├── LICENSE ├── README.md └── content.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /images/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pankajtanwarbanna/boeing-flight-detector/HEAD/images/demo.png -------------------------------------------------------------------------------- /images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pankajtanwarbanna/boeing-flight-detector/HEAD/images/icon.png -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "Boeing Flight Detector", 4 | "author": "Pankaj Tanwar", 5 | "version": "1.1", 6 | "description": "Instantly identifies and highlights Boeing aircraft on flight booking sites.", 7 | "content_scripts": [ 8 | { 9 | "matches": [ 10 | "https://www.cleartrip.com/flights/results*" 11 | ], 12 | "js": [ 13 | "content.js" 14 | ] 15 | } 16 | ], 17 | "icons": { 18 | "16": "images/icon.png", 19 | "32": "images/icon.png", 20 | "48": "images/icon.png", 21 | "128": "images/icon.png" 22 | } 23 | } -------------------------------------------------------------------------------- /Privacy-Policy.md: -------------------------------------------------------------------------------- 1 | # Privacy Policy - Boeing Flight Detector. 2 | 3 | **Last updated: June 19, 2025** 4 | 5 | ## What We Don't Collect 6 | 7 | We don't collect, store, or transmit any personal data. Period. 8 | 9 | ## What The Extension Does 10 | 11 | - Reads flight information from Cleartrip.com pages you visit 12 | - Identifies Boeing aircraft from publicly available flight data 13 | - Adds visual warnings to your browser locally 14 | - Everything happens on your device only 15 | 16 | ## No Data Sharing 17 | 18 | We don't share anything because we don't collect anything. 19 | 20 | ## Third-Party Services 21 | 22 | The extension accesses Cleartrip's public flight search API to identify aircraft types. This is the same data already displayed on the website. 23 | 24 | ## Your Control 25 | 26 | - Disable the extension anytime through Chrome settings 27 | - No accounts, no tracking, no cookies 28 | - Uninstall removes everything completely 29 | 30 | ## Contact 31 | 32 | Questions? Open an issue on our GitHub repository. 33 | 34 | --- 35 | 36 | **Simple version: We see nothing, store nothing, share nothing. Your privacy is intact.** -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Pankaj Tanwar 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 | # Boeing Flight Detector 🛩️ 2 | 3 | A browser extension that spots Boeing aircraft on flight booking sites and slaps a big red warning on them. 4 | 5 | > My heart goes out to the victims of Air India flight 171. ❤️ 6 | 7 | ![Boeing Flight Detector Demo Image](./images/demo.png) 8 | 9 | ## Why This Exists? 10 | 11 | Boeing's been making headlines for all the wrong reasons lately. Door plugs flying off mid-flight, crashes, investigations, whistleblowers... the list goes on. 12 | 13 | Yet when you're booking flights, airlines conveniently hide what aircraft you're actually flying on. This extension fixes that bullsh*t. 14 | 15 | Now you'll see a bright red "⚠️ BOEING DETECTED" label on every Boeing flight. Book it or skip it - your call. At least you'll know what you're getting into. 16 | 17 | ## What It Does 18 | 19 | - Scans flight results on Cleartrip 20 | - Identifies all Boeing aircraft (737 MAX, 787, 777, etc.) 21 | - Slaps a red warning label on Boeing flights 22 | - Works in real-time as you search 23 | - Doesn't block booking - just gives you the heads up 24 | 25 | ## Supported Sites 26 | 27 | - ✅ Cleartrip.com 28 | - 🔄 More sites coming soon 29 | 30 | ## Contributing 31 | 32 | Found a bug? Want to add more sites? PRs welcome. Let's make flight booking transparent again. 33 | 34 | ## Disclaimer 35 | 36 | This is just info, not flight advice. Boeing planes still fly every day. Your risk tolerance is your business. 37 | 38 | ## Built with ❤️ by 39 | 40 | [Pankaj Tanwar](https://twitter.com/the2ndfloorguy), and checkout his [other side-hustles](https://pankajtanwar.in/side-hustles) 41 | -------------------------------------------------------------------------------- /content.js: -------------------------------------------------------------------------------- 1 | const style = document.createElement('style'); 2 | style.textContent = ` 3 | .dangerous-flight { 4 | border: 2px solid #dc2626 !important; 5 | box-shadow: 0 0 8px rgba(220, 38, 38, 0.3); 6 | background-color: #fef2f2 !important; 7 | position: relative !important; 8 | } 9 | 10 | .dangerous-flight::before { 11 | content: "⚠️ BOEING DETECTED"; 12 | position: absolute; 13 | top: -1px; 14 | left: -1px; 15 | background: linear-gradient(135deg, #dc2626, #ef4444); 16 | color: white; 17 | font-size: 11px; 18 | font-weight: bold; 19 | padding: 4px 8px; 20 | border-radius: 4px 0 4px 0; 21 | z-index: 10; 22 | text-shadow: 0 1px 2px rgba(0,0,0,0.5); 23 | animation: pulse-warning 2s infinite; 24 | } 25 | 26 | @keyframes pulse-warning { 27 | 0%, 100% { opacity: 1; } 28 | 50% { opacity: 0.8; } 29 | } 30 | 31 | .dangerous-flight .sc-aXZVg.bqBeXl { 32 | background-color: #fee2e2 !important; 33 | border: 1px solid #fca5a5 !important; 34 | } 35 | 36 | .dangerous-flight:hover { 37 | border-color: #b91c1c !important; 38 | box-shadow: 0 0 12px rgba(220, 38, 38, 0.4); 39 | } 40 | `; 41 | document.head.appendChild(style); 42 | 43 | const flightSelector = ".sc-aXZVg.dczbns.mb-2.bg-white"; 44 | let dangerousFlightNumbers = null; 45 | 46 | const boeingAircrafts = { 47 | "707": "Boeing 707", 48 | "B707": "Boeing 707", 49 | "720": "Boeing 720", 50 | "B720": "Boeing 720", 51 | "721": "Boeing 727-100", 52 | "B721": "Boeing 727-100", 53 | "722": "Boeing 727-200", 54 | "B722": "Boeing 727-200", 55 | "731": "Boeing 737-100", 56 | "B731": "Boeing 737-100", 57 | "732": "Boeing 737-200", 58 | "B732": "Boeing 737-200", 59 | "733": "Boeing 737-300", 60 | "B733": "Boeing 737-300", 61 | "734": "Boeing 737-400", 62 | "B734": "Boeing 737-400", 63 | "735": "Boeing 737-500", 64 | "B735": "Boeing 737-500", 65 | "736": "Boeing 737-600", 66 | "B736": "Boeing 737-600", 67 | "737": "Boeing 737-700", 68 | "B737": "Boeing 737-700", 69 | "738": "Boeing 737-800", 70 | "B738": "Boeing 737-800", 71 | "739": "Boeing 737-900", 72 | "B739": "Boeing 737-900", 73 | "7M7": "Boeing 737 MAX 7", 74 | "B37M": "Boeing 737 MAX 7", 75 | "7M8": "Boeing 737 MAX 8", 76 | "B38M": "Boeing 737 MAX 8", 77 | "7M9": "Boeing 737 MAX 9", 78 | "B39M": "Boeing 737 MAX 9", 79 | "7L9": "Boeing 737 MAX 10", 80 | "B7L9": "Boeing 737 MAX 10", 81 | "741": "Boeing 747-100", 82 | "B741": "Boeing 747-100", 83 | "742": "Boeing 747-200", 84 | "B742": "Boeing 747-200", 85 | "743": "Boeing 747-300", 86 | "B743": "Boeing 747-300", 87 | "744": "Boeing 747-400", 88 | "B744": "Boeing 747-400", 89 | "748": "Boeing 747-8", 90 | "B748": "Boeing 747-8", 91 | "74D": "Boeing 747 Domestic", 92 | "B74D": "Boeing 747 Domestic", 93 | "74L": "Boeing 747 SP", 94 | "B74L": "Boeing 747 SP", 95 | "74F": "Boeing 747 Freighter", 96 | "B74F": "Boeing 747 Freighter", 97 | "752": "Boeing 757-200", 98 | "B752": "Boeing 757-200", 99 | "753": "Boeing 757-300", 100 | "B753": "Boeing 757-300", 101 | "762": "Boeing 767-200", 102 | "B762": "Boeing 767-200", 103 | "763": "Boeing 767-300", 104 | "B763": "Boeing 767-300", 105 | "764": "Boeing 767-400ER", 106 | "B764": "Boeing 767-400ER", 107 | "772": "Boeing 777-200", 108 | "B772": "Boeing 777-200", 109 | "773": "Boeing 777-300", 110 | "B773": "Boeing 777-300", 111 | "77L": "Boeing 777-200LR", 112 | "B77L": "Boeing 777-200LR", 113 | "77W": "Boeing 777-300ER", 114 | "B77W": "Boeing 777-300ER", 115 | "77F": "Boeing 777 Freighter", 116 | "B77F": "Boeing 777 Freighter", 117 | "77X": "Boeing 777X", 118 | "B77X": "Boeing 777X", 119 | "778": "Boeing 777-8", 120 | "B778": "Boeing 777-8", 121 | "779": "Boeing 777-9", 122 | "B779": "Boeing 777-9", 123 | "788": "Boeing 787-8 Dreamliner", 124 | "B788": "Boeing 787-8 Dreamliner", 125 | "789": "Boeing 787-9 Dreamliner", 126 | "B789": "Boeing 787-9 Dreamliner", 127 | "78X": "Boeing 787-10 Dreamliner", 128 | "B78X": "Boeing 787-10 Dreamliner", 129 | "717": "Boeing 717-200", 130 | "B717": "Boeing 717-200" 131 | }; 132 | 133 | function getQueryParams(url) { 134 | return new URL(url).searchParams; 135 | } 136 | 137 | function getDepartDate(url) { 138 | const params = new URL(url).searchParams; 139 | return params.get('depart_date'); 140 | } 141 | 142 | async function fetchAirCraftData() { 143 | try { 144 | const pageUrl = window.location.href; 145 | const params = getQueryParams(pageUrl); 146 | 147 | const from = params.get('from'); 148 | const to = params.get('to'); 149 | 150 | const travelClass = params.get('class') || 'Economy'; 151 | const adults = params.get('adults') || '1'; 152 | const childs = params.get('childs') || '0'; 153 | const infants = params.get('infants') || '0'; 154 | 155 | const isIntl = params.get('intl') || 'n'; 156 | const isMultiFare = params.get('isMultiFare') || 'true'; 157 | const isFFSC = params.get('isFFSC') || 'false'; 158 | 159 | const departDate = getDepartDate(pageUrl); 160 | const apiUrl = `https://www.cleartrip.com/flight/search/v2?from=${from}&source_header=${from}&to=${to}&destination_header=${to}&depart_date=${departDate}&class=${travelClass}&adults=${adults}&childs=${childs}&infants=${infants}&mobileApp=true&intl=${isIntl}&responseType=jsonV3&source=DESKTOP&utm_currency=INR&sft=&return_date=&carrier=&cfw=false&multiFare=${isMultiFare}&isFFSC=${isFFSC}`; 161 | const response = await fetch(apiUrl, { 162 | method: 'GET', 163 | headers: { 'app-agent': 'DESKTOP' } 164 | }); 165 | 166 | if (!response.ok) { 167 | console.error(`Error fetching aircraft data: HTTP status ${response.status}`); 168 | return []; 169 | } 170 | 171 | const data = await response.json(); 172 | 173 | if (data && typeof data.flights === 'object' && data.flights !== null) { 174 | const dangerousFlights = []; 175 | 176 | for (const flight of Object.keys(data.flights)) { 177 | const aircraftType = data.flights[flight].aircraftType; 178 | const codes = aircraftType.split(' '); 179 | 180 | if (boeingAircrafts[aircraftType] || aircraftType.startsWith('7')) { 181 | dangerousFlights.push(flight); 182 | } else if (codes.length > 1 && boeingAircrafts[codes[0]]) { 183 | dangerousFlights.push(flight); 184 | } 185 | } 186 | 187 | return dangerousFlights; 188 | } else { 189 | console.warn('API response structure unexpected: missing or invalid "flights" field', data); 190 | return []; 191 | } 192 | } catch (error) { 193 | console.error('Error fetching aircraft data:', error); 194 | return []; 195 | } 196 | } 197 | 198 | function markFlightIfDangerous(flightDiv) { 199 | if (flightDiv && flightDiv.nodeType === Node.ELEMENT_NODE && !flightDiv.classList.contains('dangerous-flight')) { 200 | if (dangerousFlightNumbers === null) { 201 | console.warn("markFlightIfDangerous called before data was loaded. This indicates a script logic issue."); 202 | return; 203 | } 204 | 205 | const flightNumberElement = flightDiv.querySelector('.sc-eqUAAy.fkahrI'); 206 | 207 | if (flightNumberElement) { 208 | const flightNumber = flightNumberElement.textContent.trim(); 209 | 210 | for (flight of dangerousFlightNumbers) { 211 | if (flight.startsWith(flightNumber)) { 212 | console.log(`Marking flight as dangerous: ${flightNumber} (found in dangerous list)`); 213 | flightDiv.classList.add('dangerous-flight'); 214 | } 215 | } 216 | } else { 217 | console.warn('Could not find flight number element in flight div:', flightDiv); 218 | } 219 | } 220 | } 221 | 222 | fetchAirCraftData().then(data => { 223 | dangerousFlightNumbers = data; 224 | document.querySelectorAll(flightSelector).forEach(markFlightIfDangerous); 225 | 226 | console.log('Starting MutationObserver...'); 227 | 228 | const observer = new MutationObserver(mutations => { 229 | mutations.forEach(mutation => { 230 | mutation.addedNodes.forEach(node => { 231 | if (node.nodeType === Node.ELEMENT_NODE && node.matches(flightSelector)) { 232 | markFlightIfDangerous(node); 233 | } else if (node.nodeType === Node.ELEMENT_NODE) { 234 | node.querySelectorAll(flightSelector).forEach(markFlightIfDangerous); 235 | } 236 | }); 237 | }); 238 | }); 239 | 240 | observer.observe(document.body, { childList: true, subtree: true }); 241 | }).catch(error => { 242 | console.error("Error during the initial data fetch or processing:", error); 243 | }); --------------------------------------------------------------------------------