SmartStrm助手 - 转存触发任务

监听天翼云盘、夸克网盘和115网盘转存成功事件,根据转存路径触发 SmartStrm 任务

// ==UserScript==
// @name         SmartStrm助手 - 转存触发任务
// @namespace    https://github.com/Cp0204/SmartStrm
// @license      AGPL
// @icon         https://raw.githubusercontent.com/Cp0204/SmartStrm/refs/heads/main/img/icon.svg
// @version      1.0
// @description  监听天翼云盘、夸克网盘和115网盘转存成功事件,根据转存路径触发 SmartStrm 任务
// @author       Cp0204
// @match        https://cloud.189.cn/web/share?code=*
// @match        https://pan.quark.cn/s/*
// @match        https://115cdn.com/s/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @connect      *
// ==/UserScript==

(function () {
    'use strict';

    // 设置webhook URL的函数
    function setWebhookUrl() {
        const inputUrl = prompt('请输入 SmartStrm Webhook 地址: ', GM_getValue('webhook', ''));
        if (inputUrl !== null) {
            GM_setValue('webhook', inputUrl);
            alert('已保存 Webhook 地址: \n' + inputUrl + '\n\n如填错可在油猴菜单中重新设置');
        }
    }

    // 注册菜单命令,用于设置webhook URL
    GM_registerMenuCommand('设置Webhook地址', setWebhookUrl);

    // 获取已保存的webhook URL
    let webhook = GM_getValue('webhook', '');

    // 如果没有设置webhook,则提示用户设置
    if (!webhook) {
        setWebhookUrl();
        webhook = GM_getValue('webhook', '');
        if (!webhook) {
            return;
        }
    }

    // 根据当前域名判断处理逻辑
    if (window.location.hostname === 'cloud.189.cn') {
        initCloud189();
    } else if (window.location.hostname === 'pan.quark.cn') {
        initQuark();
    } else if (window.location.hostname === '115cdn.com') {
        init115();
    }

    // 天翼云盘处理逻辑
    function initCloud189() {
        let saveSuccess = false;
        const originalOpen = XMLHttpRequest.prototype.open;
        const originalSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
            this._url = url;
            originalOpen.apply(this, arguments);
        };
        XMLHttpRequest.prototype.send = function (body) {
            this.addEventListener('load', function () {
                try {
                    if (this._url.includes('api/open/batch/checkBatchTask.action')) {
                        const response = JSON.parse(this.responseText);
                        // taskStatus=4 任务成功
                        if (response.taskStatus === 4) {
                            saveSuccess = true;
                            console.log('检测到天翼云盘转存成功');
                        }
                    }
                    // 监听系统发出的 getLastSavePath.action 请求,但仅在转存成功后才处理
                    else if (this._url.includes('api/open/getLastSavePath.action') && saveSuccess) {
                        const response = JSON.parse(this.responseText);
                        if (response.code === 'success') {
                            const savepath = response.data.filePath;
                            sendWebhook(savepath, 'cloud189');
                            saveSuccess = false;
                        }
                    }
                } catch (e) {
                    console.error('SmartStrm助手解析响应出错:', e);
                }
            });
            originalSend.apply(this, arguments);
        };
    }

    // 夸克网盘处理逻辑
    function initQuark() {
        const originalOpen = XMLHttpRequest.prototype.open;
        const originalSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
            this._url = url;
            originalOpen.apply(this, arguments);
        };
        XMLHttpRequest.prototype.send = function (body) {
            this.addEventListener('load', function () {
                try {
                    if (this._url.includes('drive-pc.quark.cn/1/clouddrive/task')) {
                        const response = JSON.parse(this.responseText);
                        // status=2 任务成功
                        if (response.data && response.data.status === 2) {
                            console.log('检测到夸克网盘转存成功');
                            let pathElement = document.querySelector('.path-name');
                            const savepath = pathElement ? pathElement.title.replace('全部文件', '').trim() : "";
                            sendWebhook(savepath, 'quark');
                        }
                    }
                } catch (e) {
                    console.error('SmartStrm助手解析响应出错:', e);
                }
            });
            originalSend.apply(this, arguments);
        };
    }

    // 115网盘处理逻辑
    function init115() {
        const originalOpen = XMLHttpRequest.prototype.open;
        const originalSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
            this._url = url;
            originalOpen.apply(this, arguments);
        };
        XMLHttpRequest.prototype.send = function (body) {
            this.addEventListener('load', function () {
                try {
                    if (this._url.includes('webapi/share/receive')) {
                        const response = JSON.parse(this.responseText);
                        // state=true 任务成功
                        if (response.state === true) {
                            const cid = localStorage.getItem('SEL_F_DIR').split('|')[1];
                            GM_xmlhttpRequest({
                                method: 'GET',
                                url: `https://115cdn.com/webapi/files?aid=1&cid=${cid}&max_size=&offset=0&limit=50&show_dir=1&nf=1&qid=0&natsort=1&source=&format=json&type=`,
                                onload: function (response) {
                                    try {
                                        const data = JSON.parse(response.responseText);
                                        if (data.errNo == 20130827) {
                                            console.error('获取115网盘保存路径失败', '堆屎山的 115 API');
                                            return;
                                        } else if (data.errNo != 0) {
                                            console.error('获取115网盘保存路径失败', response.responseText);
                                            return;
                                        }
                                        // console.log('获取115网盘保存路径成功', response.responseText);
                                        let savepath = '';
                                        if (data.path && data.path.length > 1) {
                                            // 构建路径,从第二个元素开始(第一个是根目录)
                                            for (let i = 1; i < data.path.length; i++) {
                                                savepath += '/' + data.path[i].name;
                                            }
                                            console.log('保存路径:', savepath);
                                            sendWebhook(savepath, 'open115');
                                        }
                                    } catch (e) {
                                        console.error('解析115网盘路径出错:', e);
                                    }
                                },
                                onerror: function (error) {
                                    console.error('获取115网盘路径失败:', error);
                                }
                            });
                        }
                    }
                } catch (e) {
                    console.error('SmartStrm助手解析响应出错:', e);
                }
            });
            originalSend.apply(this, arguments);
        };
    }

    // 发送webhook通知
    function sendWebhook(savepath, driver) {
        const webhook = GM_getValue('webhook', '');
        if (!webhook) {
            console.error('Webhook地址未设置');
            return;
        }
        GM_xmlhttpRequest({
            method: 'POST',
            url: webhook,
            headers: {
                'Content-Type': 'application/json'
            },
            data: JSON.stringify({
                event: 'web_save',
                data: {
                    driver: driver,
                    savepath: savepath
                },
            }),
            onload: function (response) {
                const data = JSON.parse(response.responseText);
                if (data.success) {
                    console.log('Webhook发送成功:', data.message, data.task);
                } else {
                    console.error('Webhook发送成功,但触发失败:', data.message);
                }
            },
            onerror: function (error) {
                console.error('Webhook发送失败:', error);
            }
        });
    }
    console.log('SmartStrm助手已启动');
})();