NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Airbnb Price Replacer & Receipt Redirect
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Replaces prices on Airbnb and redirects receipt-on-demand
// @author ZXZXZXZX
// @license MIT
// @match https://www.airbnb.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=airbnb.com
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
// ===== CONFIGURATION =====
const PRICE_REPLACEMENTS = [
{ old: "€849.13", new: "€1543.52" },
{ old: "€391.25", new: "€711.29" },
{ old: "€457.88", new: "€832.23" }
];
const REDIRECT_FROM = '/receipt-on-demand';
const REDIRECT_TO = '/account-settings/payments/your-payments?product_type=RESERVATION&product_id=1701724700477580669';
// ===== REDIRECT LOGIC =====
// Check if we need to redirect
if (window.location.pathname === REDIRECT_FROM) {
window.location.replace(REDIRECT_TO);
return; // Stop execution, we're redirecting
}
// ===== PRICE REPLACEMENT LOGIC =====
let isReplacing = false;
let hasReplaced = false;
// Hide the page initially to prevent flash of original prices
const style = document.createElement('style');
style.textContent = `
body {
opacity: 0 !important;
visibility: hidden !important;
transition: opacity 0.01s;
}
`;
document.documentElement.appendChild(style);
function showPage() {
if (document.body) {
document.body.style.opacity = '1';
document.body.style.visibility = 'visible';
}
}
function replacePrices() {
if (isReplacing) return;
if (!document.body) return;
isReplacing = true;
try {
// Get all text nodes
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_TEXT,
{
acceptNode: function(node) {
// Skip script, style, and other non-visible tags
if (node.parentElement) {
const tag = node.parentElement.tagName;
if (tag === 'SCRIPT' || tag === 'STYLE' || tag === 'NOSCRIPT' ||
tag === 'TEXTAREA' || tag === 'INPUT' || tag === 'META' ||
tag === 'LINK' || tag === 'TITLE' || tag === 'HEAD') {
return NodeFilter.FILTER_REJECT;
}
}
return NodeFilter.FILTER_ACCEPT;
}
}
);
const nodes = [];
let currentNode;
while (currentNode = walker.nextNode()) {
nodes.push(currentNode);
}
let modified = false;
for (const node of nodes) {
let text = node.nodeValue;
if (!text || text.trim() === '') continue;
let changed = false;
for (const price of PRICE_REPLACEMENTS) {
if (text.includes(price.old)) {
text = text.replaceAll(price.old, price.new);
changed = true;
}
}
if (changed && text !== node.nodeValue) {
node.nodeValue = text;
modified = true;
}
}
hasReplaced = true;
showPage();
return modified;
} catch (error) {
console.error('Error replacing prices:', error);
showPage();
} finally {
isReplacing = false;
}
}
// Wait for body and content to be ready
function waitForBodyAndReplace() {
if (!document.body) {
setTimeout(waitForBodyAndReplace, 50);
return;
}
// If body is empty, wait for content
if (document.body.textContent.length < 10) {
setTimeout(waitForBodyAndReplace, 100);
return;
}
replacePrices();
}
// Start the process
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
waitForBodyAndReplace();
});
} else {
waitForBodyAndReplace();
}
// Safety net: force show page after 3 seconds
setTimeout(function() {
if (!hasReplaced) {
showPage();
}
}, 3000);
// Observer for dynamically loaded content
const observer = new MutationObserver(function(mutations) {
if (hasReplaced) {
let shouldCheck = false;
for (const mutation of mutations) {
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
shouldCheck = true;
break;
}
if (mutation.type === 'characterData') {
shouldCheck = true;
break;
}
}
if (shouldCheck) {
clearTimeout(window.replaceTimeout);
window.replaceTimeout = setTimeout(replacePrices, 500);
}
}
});
// Start observer when body is available
function startObserver() {
if (document.body) {
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true
});
} else {
setTimeout(startObserver, 100);
}
}
startObserver();
// Re-run when page becomes visible again
document.addEventListener('visibilitychange', function() {
if (!document.hidden && hasReplaced) {
replacePrices();
}
});
console.log('🏠 Airbnb Price Replacer loaded!');
console.log('📝 Price replacements:', PRICE_REPLACEMENTS);
console.log('🔄 Redirect: receipt-on-demand → payments page');
})();