YouTube SuperChat货币转换器

将各种国际货币金额转为你所在地区的币种(如CNY,HKD,NTD,USD,JPY等)

目前为 2024-07-22 提交的版本。查看 最新版本

// ==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.4
// @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';
 
    // 汇率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 = {
    '$': { ISOcode: 'USD', chinese_name: '美元' },
    '¥': { ISOcode: 'JPY', chinese_name: '日元' },
    '₱': { ISOcode: 'PHP', chinese_name: '菲律宾比索' },
    '£': { ISOcode: 'GBP', chinese_name: '英镑' },
    '€': { ISOcode: 'EUR', chinese_name: '欧元' },
    '₩': { ISOcode: 'KRW', chinese_name: '韩元' },
    '₽': { ISOcode: 'RUB', chinese_name: '俄罗斯卢布' },
    '₹': { ISOcode: 'INR', chinese_name: '印度卢比' },
    '฿': { ISOcode: 'THB', chinese_name: '泰铢' },
    '₫': { ISOcode: 'VND', chinese_name: '越南盾' },
    
    'A$': { ISOcode: 'AUD', chinese_name: '澳大利亚元' },
    'AU$': { ISOcode: 'AUD', chinese_name: '澳大利亚元' },
    'NZ$': { ISOcode: 'NZD', chinese_name: '新西兰元' },
    'R$': { ISOcode: 'BRL', chinese_name: '巴西雷亚尔' },
    'HK$': { ISOcode: 'HKD', chinese_name: '港币' },
    'NT$': { ISOcode: 'TWD', chinese_name: '新台币' },
    'CA$': { ISOcode: 'CAD', chinese_name: '加拿大元' },
    'US$': { ISOcode: 'USD', chinese_name: '美元' },
    'JP¥': { ISOcode: 'JPY', chinese_name: '日元' },

    'AED': { ISOcode: 'AED', chinese_name: '阿联酋迪拉姆' },
    'AFN': { ISOcode: 'AFN', chinese_name: '阿富汗尼' },
    'ALL': { ISOcode: 'ALL', chinese_name: '阿尔巴尼亚列克' },
    'AMD': { ISOcode: 'AMD', chinese_name: '亚美尼亚德拉姆' },
    'ANG': { ISOcode: 'ANG', chinese_name: '荷属安的列斯盾' },
    'AOA': { ISOcode: 'AOA', chinese_name: '安哥拉宽扎' },
    'ARS': { ISOcode: 'ARS', chinese_name: '阿根廷比索' },
    'AUD': { ISOcode: 'AUD', chinese_name: '澳大利亚元' },
    'AWG': { ISOcode: 'AWG', chinese_name: '阿鲁巴弗罗林' },
    'AZN': { ISOcode: 'AZN', chinese_name: '阿塞拜疆马纳特' },
    'BAM': { ISOcode: 'BAM', chinese_name: '波斯尼亚和黑塞哥维那马克' },
    'BBD': { ISOcode: 'BBD', chinese_name: '巴巴多斯元' },
    'BDT': { ISOcode: 'BDT', chinese_name: '孟加拉塔卡' },
    'BGN': { ISOcode: 'BGN', chinese_name: '保加利亚列弗' },
    'BHD': { ISOcode: 'BHD', chinese_name: '巴林第纳尔' },
    'BIF': { ISOcode: 'BIF', chinese_name: '布隆迪法郎' },
    'BMD': { ISOcode: 'BMD', chinese_name: '百慕大元' },
    'BND': { ISOcode: 'BND', chinese_name: '文莱元' },
    'BOB': { ISOcode: 'BOB', chinese_name: '玻利维亚诺' },
    'BRL': { ISOcode: 'BRL', chinese_name: '巴西雷亚尔' },
    'BSD': { ISOcode: 'BSD', chinese_name: '巴哈马元' },
    'BTN': { ISOcode: 'BTN', chinese_name: '不丹努扎姆' },
    'BWP': { ISOcode: 'BWP', chinese_name: '博茨瓦纳普拉' },
    'BYN': { ISOcode: 'BYN', chinese_name: '白俄罗斯卢布' },
    'BZD': { ISOcode: 'BZD', chinese_name: '伯利兹元' },
    'CAD': { ISOcode: 'CAD', chinese_name: '加拿大元' },
    'CDF': { ISOcode: 'CDF', chinese_name: '刚果法郎' },
    'CHF': { ISOcode: 'CHF', chinese_name: '瑞士法郎' },
    'CLP': { ISOcode: 'CLP', chinese_name: '智利比索' },
    'CNY': { ISOcode: 'CNY', chinese_name: '人民币' },
    'COP': { ISOcode: 'COP', chinese_name: '哥伦比亚比索' },
    'CRC': { ISOcode: 'CRC', chinese_name: '哥斯达黎加科朗' },
    'CUP': { ISOcode: 'CUP', chinese_name: '古巴比索' },
    'CVE': { ISOcode: 'CVE', chinese_name: '佛得角埃斯库多' },
    'CZK': { ISOcode: 'CZK', chinese_name: '捷克克朗' },
    'DJF': { ISOcode: 'DJF', chinese_name: '吉布提法郎' },
    'DKK': { ISOcode: 'DKK', chinese_name: '丹麦克朗' },
    'DOP': { ISOcode: 'DOP', chinese_name: '多米尼加比索' },
    'DZD': { ISOcode: 'DZD', chinese_name: '阿尔及利亚第纳尔' },
    'EGP': { ISOcode: 'EGP', chinese_name: '埃及镑' },
    'ERN': { ISOcode: 'ERN', chinese_name: '厄立特里亚纳克法' },
    'ETB': { ISOcode: 'ETB', chinese_name: '埃塞俄比亚比尔' },
    'EUR': { ISOcode: 'EUR', chinese_name: '欧元' },
    'FJD': { ISOcode: 'FJD', chinese_name: '斐济元' },
    'FKP': { ISOcode: 'FKP', chinese_name: '福克兰群岛镑' },
    'FOK': { ISOcode: 'FOK', chinese_name: '法罗克朗' },
    'GBP': { ISOcode: 'GBP', chinese_name: '英镑' },
    'GEL': { ISOcode: 'GEL', chinese_name: '格鲁吉亚拉里' },
    'GGP': { ISOcode: 'GGP', chinese_name: '根西镑' },
    'GHS': { ISOcode: 'GHS', chinese_name: '加纳塞地' },
    'GIP': { ISOcode: 'GIP', chinese_name: '直布罗陀镑' },
    'GMD': { ISOcode: 'GMD', chinese_name: '冈比亚达拉西' },
    'GNF': { ISOcode: 'GNF', chinese_name: '几内亚法郎' },
    'GTQ': { ISOcode: 'GTQ', chinese_name: '危地马拉格查尔' },
    'GYD': { ISOcode: 'GYD', chinese_name: '圭亚那元' },
    'HKD': { ISOcode: 'HKD', chinese_name: '港币' },
    'HNL': { ISOcode: 'HNL', chinese_name: '洪都拉斯伦皮拉' },
    'HRK': { ISOcode: 'HRK', chinese_name: '克罗地亚库纳' },
    'HTG': { ISOcode: 'HTG', chinese_name: '海地古德' },
    'HUF': { ISOcode: 'HUF', chinese_name: '匈牙利福林' },
    'IDR': { ISOcode: 'IDR', chinese_name: '印尼卢比' },
    'ILS': { ISOcode: 'ILS', chinese_name: '以色列新谢克尔' },
    'IMP': { ISOcode: 'IMP', chinese_name: '马恩岛镑' },
    'INR': { ISOcode: 'INR', chinese_name: '印度卢比' },
    'IQD': { ISOcode: 'IQD', chinese_name: '伊拉克第纳尔' },
    'IRR': { ISOcode: 'IRR', chinese_name: '伊朗里亚尔' },
    'ISK': { ISOcode: 'ISK', chinese_name: '冰岛克朗' },
    'JEP': { ISOcode: 'JEP', chinese_name: '泽西镑' },
    'JMD': { ISOcode: 'JMD', chinese_name: '牙买加元' },
    'JOD': { ISOcode: 'JOD', chinese_name: '约旦第纳尔' },
    'JPY': { ISOcode: 'JPY', chinese_name: '日元' },
    'KES': { ISOcode: 'KES', chinese_name: '肯尼亚先令' },
    'KGS': { ISOcode: 'KGS', chinese_name: '吉尔吉斯斯坦索姆' },
    'KHR': { ISOcode: 'KHR', chinese_name: '柬埔寨瑞尔' },
    'KID': { ISOcode: 'KID', chinese_name: '基里巴斯元' },
    'KMF': { ISOcode: 'KMF', chinese_name: '科摩罗法郎' },
    'KRW': { ISOcode: 'KRW', chinese_name: '韩元' },
    'KWD': { ISOcode: 'KWD', chinese_name: '科威特第纳尔' },
    'KYD': { ISOcode: 'KYD', chinese_name: '开曼群岛元' },
    'KZT': { ISOcode: 'KZT', chinese_name: '哈萨克斯坦坚戈' },
    'LAK': { ISOcode: 'LAK', chinese_name: '老挝基普' },
    'LBP': { ISOcode: 'LBP', chinese_name: '黎巴嫩镑' },
    'LKR': { ISOcode: 'LKR', chinese_name: '斯里兰卡卢比' },
    'LRD': { ISOcode: 'LRD', chinese_name: '利比里亚元' },
    'LSL': { ISOcode: 'LSL', chinese_name: '莱索托洛蒂' },
    'LYD': { ISOcode: 'LYD', chinese_name: '利比亚第纳尔' },
    'MAD': { ISOcode: 'MAD', chinese_name: '摩洛哥迪拉姆' },
    'MDL': { ISOcode: 'MDL', chinese_name: '摩尔多瓦列伊' },
    'MGA': { ISOcode: 'MGA', chinese_name: '马达加斯加阿里亚里' },
    'MKD': { ISOcode: 'MKD', chinese_name: '马其顿第纳尔' },
    'MMK': { ISOcode: 'MMK', chinese_name: '缅元' },
    'MNT': { ISOcode: 'MNT', chinese_name: '蒙古图格里克' },
    'MOP': { ISOcode: 'MOP', chinese_name: '澳门元' },
    'MRU': { ISOcode: 'MRU', chinese_name: '毛里塔尼亚乌吉亚' },
    'MUR': { ISOcode: 'MUR', chinese_name: '毛里求斯卢比' },
    'MVR': { ISOcode: 'MVR', chinese_name: '马尔代夫拉菲亚' },
    'MWK': { ISOcode: 'MWK', chinese_name: '马拉维克瓦查' },
    'MXN': { ISOcode: 'MXN', chinese_name: '墨西哥比索' },
    'MYR': { ISOcode: 'MYR', chinese_name: '马来西亚林吉特' },
    'MZN': { ISOcode: 'MZN', chinese_name: '莫桑比克梅蒂卡尔' },
    'NAD': { ISOcode: 'NAD', chinese_name: '纳米比亚元' },
    'NGN': { ISOcode: 'NGN', chinese_name: '尼日利亚奈拉' },
    'NIO': { ISOcode: 'NIO', chinese_name: '尼加拉瓜科多巴' },
    'NOK': { ISOcode: 'NOK', chinese_name: '挪威克朗' },
    'NPR': { ISOcode: 'NPR', chinese_name: '尼泊尔卢比' },
    'NZD': { ISOcode: 'NZD', chinese_name: '新西兰元' },
    'OMR': { ISOcode: 'OMR', chinese_name: '阿曼里亚尔' },
    'PAB': { ISOcode: 'PAB', chinese_name: '巴拿马巴波亚' },
    'PEN': { ISOcode: 'PEN', chinese_name: '秘鲁新索尔' },
    'PGK': { ISOcode: 'PGK', chinese_name: '巴布亚新几内亚基那' },
    'PHP': { ISOcode: 'PHP', chinese_name: '菲律宾比索' },
    'PKR': { ISOcode: 'PKR', chinese_name: '巴基斯坦卢比' },
    'PLN': { ISOcode: 'PLN', chinese_name: '波兰兹罗提' },
    'PYG': { ISOcode: 'PYG', chinese_name: '巴拉圭瓜拉尼' },
    'QAR': { ISOcode: 'QAR', chinese_name: '卡塔尔里亚尔' },
    'RON': { ISOcode: 'RON', chinese_name: '罗马尼亚列伊' },
    'RSD': { ISOcode: 'RSD', chinese_name: '塞尔维亚第纳尔' },
    'RUB': { ISOcode: 'RUB', chinese_name: '俄罗斯卢布' },
    'RWF': { ISOcode: 'RWF', chinese_name: '卢旺达法郎' },
    'SAR': { ISOcode: 'SAR', chinese_name: '沙特里亚尔' },
    'SBD': { ISOcode: 'SBD', chinese_name: '所罗门群岛元' },
    'SCR': { ISOcode: 'SCR', chinese_name: '塞舌尔卢比' },
    'SDG': { ISOcode: 'SDG', chinese_name: '苏丹镑' },
    'SEK': { ISOcode: 'SEK', chinese_name: '瑞典克朗' },
    'SGD': { ISOcode: 'SGD', chinese_name: '新加坡元' },
    'SHP': { ISOcode: 'SHP', chinese_name: '圣赫勒拿镑' },
    'SLE': { ISOcode: 'SLE', chinese_name: '塞拉利昂利昂' },
    'SOS': { ISOcode: 'SOS', chinese_name: '索马里先令' },
    'SRD': { ISOcode: 'SRD', chinese_name: '苏里南元' },
    'SSP': { ISOcode: 'SSP', chinese_name: '南苏丹镑' },
    'STN': { ISOcode: 'STN', chinese_name: '圣多美和普林西比多布拉' },
    'SYP': { ISOcode: 'SYP', chinese_name: '叙利亚镑' },
    'SZL': { ISOcode: 'SZL', chinese_name: '斯威士兰里兰吉尼' },
    'THB': { ISOcode: 'THB', chinese_name: '泰铢' },
    'TJS': { ISOcode: 'TJS', chinese_name: '塔吉克斯坦索莫尼' },
    'TMT': { ISOcode: 'TMT', chinese_name: '土库曼斯坦马纳特' },
    'TND': { ISOcode: 'TND', chinese_name: '突尼斯第纳尔' },
    'TOP': { ISOcode: 'TOP', chinese_name: '汤加潘加' },
    'TRY': { ISOcode: 'TRY', chinese_name: '土耳其里拉' },
    'TTD': { ISOcode: 'TTD', chinese_name: '特立尼达和多巴哥元' },
    'TVD': { ISOcode: 'TVD', chinese_name: '图瓦卢元' },
    'TWD': { ISOcode: 'TWD', chinese_name: '新台币' },
    'TZS': { ISOcode: 'TZS', chinese_name: '坦桑尼亚先令' },
    'UAH': { ISOcode: 'UAH', chinese_name: '乌克兰格里夫纳' },
    'UGX': { ISOcode: 'UGX', chinese_name: '乌干达先令' },
    'USD': { ISOcode: 'USD', chinese_name: '美元' },
    'UYU': { ISOcode: 'UYU', chinese_name: '乌拉圭比索' },
    'UZS': { ISOcode: 'UZS', chinese_name: '乌兹别克斯坦苏姆' },
    'VES': { ISOcode: 'VES', chinese_name: '委内瑞拉主权玻利瓦尔' },
    'VND': { ISOcode: 'VND', chinese_name: '越南盾' },
    'VUV': { ISOcode: 'VUV', chinese_name: '瓦努阿图瓦图' },
    'WST': { ISOcode: 'WST', chinese_name: '萨摩亚塔拉' },
    'XAF': { ISOcode: 'XAF', chinese_name: '中非法郎' },
    'XCD': { ISOcode: 'XCD', chinese_name: '东加勒比元' },
    'XDR': { ISOcode: 'XDR', chinese_name: '特别提款权' },
    'XOF': { ISOcode: 'XOF', chinese_name: '西非法郎' },
    'XPF': { ISOcode: 'XPF', chinese_name: '太平洋法郎' },
    'YER': { ISOcode: 'YER', chinese_name: '也门里亚尔' },
    'ZAR': { ISOcode: 'ZAR', chinese_name: '南非兰特' },
    'ZMW': { ISOcode: 'ZMW', chinese_name: '赞比亚克瓦查' },
    'ZWL': { ISOcode: 'ZWL', 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.ISOcode, 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);
                                        
                                        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).attr('YoutubeSuperChatCurrencyConverter-converted', 'true'); // 标记为已处理
 
                                    } else {
                                        console.log(`解析失败[${message}]`);
                                    }
                                }
                            });
                        }
                    });
                }
            }
        };
 
        // 创建并启动MutationObserver
        let observer = new MutationObserver(callback);
        observer.observe(targetNode, config);
    }
 
    // 启动观察器
    $(document).ready(function() {
        fetchExchangeRates(observeSuperChat);
    });
})();