Auto Currency

Automatically convert all currencies on any website to your local currency

  1. // ==UserScript==
  2. // @name Auto Currency
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-09-25
  5. // @description Automatically convert all currencies on any website to your local currency
  6. // @author Obelous
  7. // @match *://*/*
  8. // @icon
  9. // @grant none
  10. // @license apache2
  11. // ==/UserScript==
  12.  
  13. /////////////////////////////////////////////
  14. // YOU MUST EDIT THIS SCRIPT FOR IT TO WORK//
  15. /////////////////////////////////////////////
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. // API settings: Get a free API key from https://www.exchangerate-api.com/
  21. const apiKey = 'API_KEY';
  22. const apiURL = `https://v6.exchangerate-api.com/v6/${apiKey}/latest/USD`;
  23.  
  24. // Function to fetch conversion rate
  25. async function getGBPConversionRate() {
  26. try {
  27. const response = await fetch(apiURL);
  28. const data = await response.json();
  29. return data.conversion_rates.GBP;
  30. } catch (error) {
  31. console.error('Error fetching conversion rate:', error);
  32. return null;
  33. }
  34. }
  35.  
  36. // Function to convert USD to GBP and format the price
  37. function convertAndReplacePrices(usdToGbpRate, targetNode) {
  38. const priceRegex = /\$([0-9]+(?:\.[0-9]{2})?)/g;
  39.  
  40. // Iterate over all text nodes, including nested text nodes inside spans and labels
  41. const walker = document.createTreeWalker(targetNode, NodeFilter.SHOW_TEXT, {
  42. acceptNode: function(node) {
  43. if (priceRegex.test(node.nodeValue)) return NodeFilter.FILTER_ACCEPT;
  44. }
  45. });
  46.  
  47. while (walker.nextNode()) {
  48. const node = walker.currentNode;
  49. node.nodeValue = node.nodeValue.replace(priceRegex, function(match, usdPrice) {
  50. const usdValue = parseFloat(usdPrice);
  51. const gbpValue = (usdValue * usdToGbpRate).toFixed(2);
  52. return ${gbpValue} (${match})`;
  53. });
  54. }
  55. }
  56.  
  57. // Function to handle nested price elements in the DOM
  58. function handlePriceElements(usdToGbpRate) {
  59. const priceSelectors = ['.woocommerce-Price-amount', '.wc-pao-addon-price'];
  60.  
  61. priceSelectors.forEach(selector => {
  62. const elements = document.querySelectorAll(selector);
  63. elements.forEach(element => {
  64. const priceText = element.innerText.match(/\$([0-9]+(?:\.[0-9]{2})?)/);
  65.  
  66. if (priceText) {
  67. const usdValue = parseFloat(priceText[1]);
  68. const gbpValue = (usdValue * usdToGbpRate).toFixed(2);
  69. element.innerText = ${gbpValue} ($${usdValue})`;
  70. }
  71. });
  72. });
  73. }
  74.  
  75. // Function to observe DOM changes
  76. async function observeDOMChanges() {
  77. const usdToGbpRate = await getGBPConversionRate();
  78. if (!usdToGbpRate) return;
  79.  
  80. // Initial price conversion on the whole page
  81. convertAndReplacePrices(usdToGbpRate, document.body);
  82. handlePriceElements(usdToGbpRate); // Handle nested price elements
  83.  
  84. // Callback to execute when mutations are observed
  85. const mutationCallback = function(mutationsList) {
  86. for (let mutation of mutationsList) {
  87. if (mutation.type === 'childList' || mutation.type === 'subtree') {
  88. mutation.addedNodes.forEach(node => {
  89. if (node.nodeType === Node.ELEMENT_NODE) {
  90. convertAndReplacePrices(usdToGbpRate, node);
  91. handlePriceElements(usdToGbpRate); // Handle nested price elements in new nodes
  92. }
  93. });
  94. }
  95. }
  96. };
  97.  
  98. // Set up a MutationObserver to watch for changes to the body
  99. const observer = new MutationObserver(mutationCallback);
  100. observer.observe(document.body, { childList: true, subtree: true });
  101. }
  102.  
  103. // Start observing DOM changes
  104. observeDOMChanges();
  105.  
  106. })();