Simple Amazon Shortcuts

Shortcuts for Amazon product price history and review authenticity

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name     Simple Amazon Shortcuts
// @name:de  Einfache Amazon-Verknüpfungen
// @name:es  Atajos simples de Amazon
// @name:fr  Raccourcis Amazon simples
// @name:hi  सरल अमेज़न शॉर्टकट
// @name:it  Scorciatoie semplici Amazon
// @name:ja  シンプルなAmazonショートカッ
// @namespace   flightless22.SAS
// @description Shortcuts for Amazon product price history and review authenticity
// @description:de  Verknüpfungen für Amazon Product Price History and Review Echtiversität'
// @description:es  Atajos para el Historial de precios del producto de Amazon y de la autenticidad de la revisión
// @description:fr  Raccourcis pour Amazon Historique des prix du produit et révision de l'authenticité
// @description:hi  अमेज़ॅन उत्पाद मूल्य इतिहास के लिए शॉर्टकट और प्रामाणिकता की समीक्षा करें
// @description:it  Scorciatoie per la storia del prezzo del prodotto Amazon e della revisione dell'autenticità
// @description:ja  Amazon製品の価格履歴のショートカットとレビュー信憑性
// @version     2022.05.13.1025
// @author      flightless22
// @homepageURL https://greatest.deepsurf.us/en/scripts/427433
// @license 		MIT
// @include		  https://*.amazon.*/*
// @grant       GM.openInTab
// @grant       GM.registerMenuCommand
// @noframes
// ==/UserScript==
(function() {
	"use strict";

	/*<<<<====== User options ======>>>>*/
	// Override system language. For example: "" will use system settings. "en" will use English.
	// Currently supported language code: de, en, es, fr, hi, it and ja.
	const forcedlang = "";
	// Tab behavior. default: open in foreground and insert next to current tab.
	// Note: GreaseMonkey only supports boolean (true = open background | false = open foreground)
	// For full details see: https://violentmonkey.github.io/api/gm/#gm_openintab
	var taboptions = {"active": true, "insert": true};
	// Shortcut access key. set to empty string to disable.
	const accesskey = {"camelcamelcamel": "c", "keepa":"k", "reviewmeta":"r", "fakespot":"f"};
	/*<<<<====== User options ======>>>>*/

	if ((GM_info.scriptHandler === "GreaseMonkey" ) &&
	(typeof taboptions !== "boolean")) taboptions = taboptions["active"] !== undefined ? !taboptions["active"] : false;
	// [1] TLD / [2] ASIN
	const amazonsrc = /^https:\/\/[a-zA-Z]+\.amazon\.([.a-zA-Z]+).*\/([a-zA-Z0-9]{10})/.exec(location.href);
	var babel = {};
	const userlang = getuserlang();
	const service = {
		"Keepa": {
			"cat": translate("price"),
			"tld": {"com":"Default", "co.uk": 2, "de": 3, "fr": 4, "co.jp": 5, "ca": 6, "it": 8, "es": 9, "in": 10,
				"com.mx": 11, "com.br": 12},
			"durl": "https://keepa.com/#!product/1-$asin$",
			"url": "https://keepa.com/#!product/$tld$-$asin$",
			"fn" : function() { getservice("Keepa") },
			"k" : accesskey["keepa"]
		},
		"Camel Camel Camel": {
			"cat": translate("price"),
			"tld": {"au":"au", "ca":"ca", "com":"Default", "co.uk":"uk", "de":"de", "es":"es", "fr":"fr"},
			"durl": "https://camelcamelcamel.com/product/$asin$",
			"url": "https://$tld$.camelcamelcamel.com/product/$asin$",
			"fn" : function() { getservice("Camel Camel Camel") },
			"k" : accesskey["camelcamelcamel"]
		},
		"Review Meta": {
			"cat": translate("review"),
			"tld": {"ca":"ca", "com.au":"au", "com.br":"br","com.mx":"mx", "cn":"cn", "com":"Default", "co.jp":"jp",
				"co.uk":"uk", "de":"de", "es":"es", "fr":"fr", "it":"it", "in":"in", "nl":"nl"},
			"durl": "https://reviewmeta.com/amazon/$asin$",
			"url": "https://reviewmeta.com/amazon-$tld$/$asin$",
			"fn" : function() { getservice("Review Meta") },
			"k" : accesskey["reviewmeta"]
		},
		"Fake Spot": {
			"cat": translate("review"),
			"tld": {"ca":"ca", "com.au":"com.au", "co.jp":"co.jp", "com":"Default", "co.uk":"co.uk", "de":"de",
				"es":"es", "fr":"fr", "in":"in", "it":"it"},
			"durl": "https://www.fakespot.com/analyze?url=http://amazon.com/dp/$asin$",
			"url": "https://www.fakespot.com/analyze?url=http://amazon.$tld$/dp/$asin$",
			"fn" : function() { getservice("Fake Spot") },
			"k" : accesskey["fakespot"]
		}
	};
	function loadbabel(lang) {
		let translations = {
			"en":{ //English
				"price": "Price History",
				"review": "Review Analysis",
				"unsupportedprompt": '$service$: "$amazon$" is unsupported.\nDo you want to continue anyway?',
				"unsupported": '"$amazon$" is unsupported.'
			},
			"de":{ //German / Deutsch
				"price": "Preisverlauf",
				"review": "Bewertungen analysieren",
				"unsupportedprompt": '$service$: "$amazon$" wird nicht unterstützt.\nMöchtest du trotzdem weitermachen?',
				"unsupported": '"$amazon$" wird nicht unterstützt.'
			},
			"es":{ //Spanish / Español
				"price": "Historial de precios",
				"review": "Análisis de revisión",
				"unsupportedprompt": '$service$: "$amazon$" no es compatible.\n¿Quieres continuar de todos modos?',
				"unsupported": '"$amazon$" no es compatible.'
			},
			"fr":{ //French / Français
				"price": "Historique des prix",
				"review": "Analyser l'examen des utilisateurs",
				"unsupportedprompt": '$service$: "$amazon$" n\'est pas pris en charge.\nVoulez-vous continuer quand même?',
				"unsupported": '"$amazon$" n\'est pas pris en charge.'
			},
			"hi":{ //Hindi // हिन्दी
				"price": "मूल्य इतिहास",
				"review": "समीक्षा विश्लेषण",
				"unsupportedprompt": '$service$: $amazon$" समर्थित नहीं है\nक्या आप फिर भी जारी रखना चाहते हैं?',
				"unsupported": '"$amazon$"  समर्थित नहीं है'
			},
			"it":{ //Italian / Italiano
				"price": "Cronologia dei prezzi",
				"review": "Analisi delle recensioni",
				"unsupportedprompt": '$service$: $amazon$" non è supportato.\nVuoi continuare comunque?',
				"unsupported": '"$amazon$" non è supportato.'
			},
			"ja":{ //Japanese / 日本語
				"price": "価格履歴",
				"review": "レビュー分析",
				"unsupportedprompt": '$service$: "$amazon$"はサポートされていません。\n続行しますか?',
				"unsupported": '"$amazon$"はサポートされていません。'
			}
		};
		babel = {"en": translations["en"]}; //fallback language
		if (translations[lang] === undefined) return msg(`Error: '${lang}' translation does not exist. default to 'en' langauge`);
		babel = Object.assign(babel, {[lang]: translations[lang]});
	}
	function getuserlang(){
		let lang = ( forcedlang ? forcedlang : navigator.language.slice(0,2) ); //non region specific
		loadbabel(lang);
		if (babel[lang] === undefined) return "en";
		return lang;
	}
	function translate(name, rep){
		let str = babel[userlang][name];
		if (str === undefined) str = babel["en"][name];
		if (Array.isArray(rep) === true && rep.length % 2 === 0) {
			for (let i = 0; i<= rep.length/2; i+=2) {
				str = str.replace(rep[i], rep[i+1]);
			}
		}
		return str;
	}
	function getservice(name) {
		let p, url, tld = service[name]["tld"][amazonsrc[1]];
		if (tld === "Default") {
			url = service[name]["durl"].replace("$asin$", amazonsrc[2]);
		} else {
			if (tld === undefined) {
				msg(`Error: ${name} does not support amazon.${amazonsrc[1]}`);
				p = confirm( translate("unsupportedprompt", ["$service$", name, "$amazon$", `amazon.${amazonsrc[1]}`]) );
				if (p === false) return;
				tld = amazonsrc[1];
			}
			url = service[name]["url"].replace("$tld$", tld);
			url = url.replace("$asin$", amazonsrc[2]);
		}
		GM.openInTab(url, taboptions);
	}
	function setup() {
		// ignore 404 errors, sometimes product history is still desirable
		if (amazonsrc === null || amazonsrc.length < 2) return msg("ASIN not found, probably not a product page.");
		msg(`Domain: amazon.${amazonsrc[1]} Product ASIN: ${amazonsrc[2]}`);
		let errtxt = translate("unsupported", ["$amazon$", `amazon.${amazonsrc[1]}`]);
		for (let name in service) {
			GM.registerMenuCommand(
				`${name} : ${service[name]["cat"]} ${service[name]["tld"][amazonsrc[1]] === undefined ? `( ${errtxt} )` : ""}`,
				service[name]["fn"],
				service[name]["k"]
			);
		}
	}
	function msg(txt, ret){
		console.log(`[${GM_info.scriptHandler}] ${GM_info.script.name}: ${txt}`);
		return ret;
	}
	setup();
})();