YouTube SuperChat货币转换

将各种货币的金额转为CNY

目前為 2024-07-21 提交的版本,檢視 最新版本

// ==UserScript==
// @name         YouTube SuperChat货币转换
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  将各种货币的金额转为CNY
// @author       kksskkoopp
// @match        https://www.youtube.com/*
// @grant        GM_xmlhttpRequest
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// @connect      *://*.exchangerate-api.com/
// @license      MIT
// @run-at document-start
// ==/UserScript==
/* globals  $ */
(function() {
    'use strict';

    // 汇率API信息
    let targetCurrencyCode = 'CNY'; // 目标币种
    let targetCurrencyPrecision = 1 // 目标币种保留的小数位数;
    // 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 = {
        '$': 'USD', // 美元
        '¥': 'JPY', // 日元
        '₱': 'PHP', // 菲律宾比索
        '£': 'GBP', // 英镑
        '€': 'EUR', // 欧元
        '₩': 'KRW', // 韩元
        '₽': 'RUB', // 卢布
        '₹': 'INR', // 卢比
        '฿': 'THB', // 泰铢
        '₣': 'FRF', // 法朗
        '₫': 'VND', // 越南盾
        
        
        
        
        'A$': 'AUD', // 澳大利亚元
        'NZ$': 'NZD', // 新西兰元
        'R$': 'BRL', // 巴西雷亚尔
        'HK$': 'HKD', // 港币
        'NT$': 'TWD', // 新台币
        'CA$': 'CAD', // 加拿大元



        'AED': 'AED', // 阿联酋迪拉姆
        'ARS': 'ARS', // 阿根廷比索
        'SGD': 'SGD', // 新加坡元
        'MYR': 'MYR'  // 马来西亚林吉特
        
        
        
    };

    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(`错误:error-type:${data.error-type}`);
                    console.error(`详情见https://www.exchangerate-api.com/docs/standard-requests`);
                }
            },
            onerror: function() {
                console.error('无法获取汇率');
            }
        });
    }


    // 解析金额和货币类型
    function parseAmountAndCurrency(text) {
        // 去除空白字符
        text = text.replace(/\s+/g, '');
        // 遍历currencyMap字典,找到匹配的货币符号
        for (let [symbol, code] of Object.entries(currencyMap)) {
            if (text.startsWith(symbol)) {
                // 提取金额部分,并去除货币符号和千位分隔符
                let amount = parseFloat(text.replace(symbol, '').replace(/,/g, ''));
                return { amount, fromCurrencyCode: code };
            }
        }
        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');
                        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}`;
                                        $(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);
    });
})();