// ==UserScript==
// @name YouTube SuperChat货币转换器
// @name:zh-CN YouTube SuperChat货币转换器
// @name:zh-TW YouTube SuperChat貨幣轉換器
// @name:zh-HK YouTube SuperChat貨幣轉換器
// @description 将各种国际货币金额转为你所在地区的币种(如CNY,HKD,NTD,USD,JPY等)
// @description:zh-CN 将各种国际货币金额转为你所在地区的币种(如CNY,HKD,NTD,USD,JPY等)
// @description:zh-TW 將各種國際貨幣金額轉為你所在地區的幣種(如CNY,HKD,NTD,USD,JPY等)
// @description:zh-HK 將各種國際貨幣金額轉為你所在地區的幣種(如CNY,HKD,NTD,USD,JPY等)
// @namespace http://tampermonkey.net/
// @version 1.2
// @author kksskkoopp
// @match https://www.youtube.com/*
// @grant GM_xmlhttpRequest
// @require https://code.jquery.com/jquery-3.6.0.min.js
// @connect v6.exchangerate-api.com
// @license MIT
// @run-at document-end
// ==/UserScript==
/* globals $ */
(function() {
'use strict';
console.log('脚本信息');
console.log(GM.info);
// 汇率API信息
let targetCurrencyCode = 'CNY'; // 目标币种
let targetCurrencyPrecision = 2 // 目标币种保留的小数位数;
// API密钥请在 https://www.exchangerate-api.com/ 免费获取:邮箱注册->一键激活->获得API密钥->替换下面的API_KEY
let API_KEY = '0c719520222e5b86cf26f479'; // API密钥
let API_URL = `https://v6.exchangerate-api.com/v6/${API_KEY}/latest/${targetCurrencyCode}`; // API地址
// YoutubeSuperChat货币符号 : ISO-4217货币码
let currencyMap = {
'$': { code: 'USD', chinese_name: '美元' },
'¥': { code: 'JPY', chinese_name: '日元' },
'₱': { code: 'PHP', chinese_name: '菲律宾比索' },
'£': { code: 'GBP', chinese_name: '英镑' },
'€': { code: 'EUR', chinese_name: '欧元' },
'₩': { code: 'KRW', chinese_name: '韩元' },
'₽': { code: 'RUB', chinese_name: '卢布' },
'₹': { code: 'INR', chinese_name: '卢比' },
'฿': { code: 'THB', chinese_name: '泰铢' },
'₣': { code: 'FRF', chinese_name: '法郎' },
'₫': { code: 'VND', chinese_name: '越南盾' },
'A$': { code: 'AUD', chinese_name: '澳大利亚元' },
'NZ$': { code: 'NZD', chinese_name: '新西兰元' },
'R$': { code: 'BRL', chinese_name: '巴西雷亚尔' },
'HK$': { code: 'HKD', chinese_name: '港币' },
'NT$': { code: 'TWD', chinese_name: '新台币' },
'CA$': { code: 'CAD', chinese_name: '加拿大元' },
'US$': { code: 'USD', chinese_name: '美元' },
'AED': { code: 'AED', chinese_name: '阿联酋迪拉姆' },
'ARS': { code: 'ARS', chinese_name: '阿根廷比索' },
'SGD': { code: 'SGD', chinese_name: '新加坡元' },
'MYR': { code: 'MYR', chinese_name: '马来西亚林吉特' }
};
let exchangeRates = {};
/*
计算公式
targetCurrencyAmount = fromCurrencyAmount * exchangeRates[fromCurrenyCode]
*/
// 获取汇率信息
function fetchExchangeRates(callback) {
console.log(`开始请求汇率${API_URL}`);
GM_xmlhttpRequest({
method: 'GET',
url: API_URL,
onload: function(response) {
let data = JSON.parse(response.responseText);
if (data.result == 'success')
{
exchangeRates = data.conversion_rates;
let datetime = new Date();
console.log(`汇率 ${datetime.toLocaleDateString()} ${datetime.toLocaleTimeString()}`);
console.log(exchangeRates);
console.log('汇率请求完毕');
callback();
}
else if (data.result == 'error')
{
console.error(`错误:响应:${data}`);
console.error(`详情见https://www.exchangerate-api.com/docs/standard-requests`);
}
},
onerror: function() {
console.error('无法获取汇率');
}
});
}
// 解析金额和货币类型
function parseAmountAndCurrency(text) {
// 去除空白字符
text = text.replace(/\s+/g, '');
// 遍历currencyMap字典,找到匹配的货币符号
for (const [symbol, info] of Object.entries(currencyMap)) {
if (text.startsWith(symbol)) {
const amount = parseFloat(text.replace(symbol, '').replace(/,/g, '')); // 提取金额并去除千位分隔符
return { amount, fromCurrencyCode: info.code, chinese_name: info.chinese_name };
}
}
console.error(`新的币种${text}.`);
return null; // 如果未找到匹配的货币符号,返回null
}
// 观察DOM变化并转换SuperChat金额
function observeSuperChat() {
let targetNode = document.body;
let config = { childList: true, subtree: true };
let callback = function(mutationsList, observer) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
// 遍历新增的节点,检查是否包含SuperChat消息
$(mutation.addedNodes).each(function() {
let element = $(this).find('yt-formatted-string.style-scope.yt-live-chat-paid-message-renderer, yt-formatted-string.style-scope.yt-live-chat-paid-sticker-renderer').not('#deleted-state, #dashboard-deleted-state');
if (element.length > 0) {
// 处理每个SuperChat消息
element.each(function() {
if (!$(this).attr('YoutubeSuperChatCurrencyConverter-converted')) {
let message = $(this).text().trim();
console.log(`捕获到超级留言[${message}]`);
let parsed = parseAmountAndCurrency(message);
if (parsed) {
console.log(`解析成功${message}:${parsed.fromCurrencyCode} ${parsed.amount}`);
// 获取汇率并计算转换后的金额
let targetCurrencyAmount = parsed.amount / exchangeRates[parsed.fromCurrencyCode];
let targetCurrencyAmount_str = targetCurrencyAmount.toFixed(targetCurrencyPrecision);
//let newText = `${message}=${targetCurrencyCode} ${targetCurrencyAmount_str}`;
const additionalInfo = `
<div class="split-text" style="display: inline-block; white-space: no-wrap; text-align: left;">
<div style="font-size: 7px;">${parsed.chinese_name}</div>
<div style="font-size: 11px;">=${targetCurrencyCode} ${targetCurrencyAmount_str}</div>
</div>`;
$(this).html(message + additionalInfo);
//$(this).text(newText);
$(this).attr('YoutubeSuperChatCurrencyConverter-converted', 'true'); // 标记为已处理
} else {
console.log(`解析失败[${message}]`);
}
}
});
}
});
}
}
};
// 创建并启动MutationObserver
let observer = new MutationObserver(callback);
observer.observe(targetNode, config);
}
// 启动观察器
$(document).ready(function() {
fetchExchangeRates(observeSuperChat);
});
})();