Greasy Fork

Greasy Fork is available in English.

妖火帖子AI总结(太长不看)

调用OpenAI或其他支持completions功能API对妖火论坛帖子内容及评论进行摘要总结

目前为 2025-02-12 提交的版本,查看 最新版本

// ==UserScript==
// @name         妖火帖子AI总结(太长不看)
// @namespace    https://www.yaohuo.me/bbs/userinfo.aspx?touserid=20740
// @version      1.0.6
// @description  调用OpenAI或其他支持completions功能API对妖火论坛帖子内容及评论进行摘要总结
// @author       SiXi
// @match        https://www.yaohuo.me/bbs*
// @match        https://yaohuo.me/bbs*
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @icon         https://www.yaohuo.me/css/favicon.ico
// @license      Apache 2
// @require      https://code.jquery.com/jquery-3.6.0.min.js
// ==/UserScript==

(function() {
    'use strict';

    // 用户配置参数
    const OPENAI_BASE_URL = 'https://api.gptgod.online/v1/chat/completions';  //模型的base_url,需要使用支持completions功能的url
    const OPENAI_API_KEY = 'sk-XXXXXXXXXXXX';  //密钥
    const OPENAI_MODEL = 'glm-4-flash';  //模型名称,火山方舟申请的模型是填'推理接入点'名称,ep开头那个

    // 创建按钮并插入页面
    $(document).ready(function() {
        $('.Postinfo .Postime').each(function() {
            const postInfo = $(this).closest('.Postinfo');
            const button = $('<button class="ai-summary-btn">AI总结</button>')
                .css({
                    'padding': '5px 10px',
                    'background-color': '#4CAF50',
                    'color': 'white',
                    'border': 'none',
                    'border-radius': '5px',
                    'cursor': 'pointer'
                })
                .insertAfter(postInfo.find('.Postime'))
                .on('click', function() {
                    handleButtonClick($(this), postInfo);
                });
        });
    });

    // 获取评论内容
    function getComments() {
        const comments = [];
        $('.recontent .retext').each(function() {
            const commentText = $(this).text().trim();
            if (commentText && !$(this).closest('.quoted-content').length) {
                comments.push(commentText);
            }
        });
        return comments;
    }

    // 处理按钮点击事件
    function handleButtonClick(button, postInfo) {
        // 点击后禁用按钮并显示加载提示
        button.prop('disabled', true).text('AI阅读中...');

        // 获取帖子标题
        const title = postInfo.find('.biaotiwenzi').text().trim();
        if (!title) {
            alert("未找到帖子标题!");
            button.prop('disabled', false).text('AI总结');
            return;
        }

        // 获取帖子内容
        const content = postInfo.closest('.content').find('.bbscontent').text().trim();
        if (!content) {
            alert("未找到帖子内容!");
            button.prop('disabled', false).text('AI总结');
            return;
        }

        const comments = getComments();

        const fullContent = `帖子标题:${title}\n\n原帖内容:\n${content}\n\n评论区内容:\n\n${comments.map((comment, index) => `${index + 1}. ${comment}`).join('\n')}`;

        fetchSummary(fullContent, button);
    }

    function fetchSummary(content, button) {
        GM_xmlhttpRequest({
            method: 'POST',
            url: `${OPENAI_BASE_URL}`,
            headers: {
                'Authorization': `Bearer ${OPENAI_API_KEY}`,
                'Content-Type': 'application/json'
            },
            data: JSON.stringify({
                model: OPENAI_MODEL,
                messages: [
                    {
                        role: "system",
                        content: "你是一个帮助用户总结帖子的助手。请分别总结原帖内容和评论区的主要观点。原帖内容用1-3句话总结,评论区的观点用1-2句话总结。保持口语化,突出重点,不要使用任何标记格式。总结内容用'原帖内容'和'妖友观点'前缀进行回复。"
                    },
                    {
                        role: "user",
                        content: `请总结:\n\n${content}`
                    }
                ],
                stream: false
            }),
            onload: function(response) {
                console.log("太长不看_发起请求:", response);
                try {
                    const result = JSON.parse(response.responseText);
                    let summary = result.choices[0].message.content.trim();

                    summary = summary.replace("妖友观点:", "<hr>妖友观点:");

                    showSummaryPopup(summary);
                    button.prop('disabled', false).text('AI总结');
                } catch (error) {
                    console.error("解析AI响应失败:", error);
                    showErrorPopup("太长不看_请求失败,请稍后再试。");
                    button.prop('disabled', false).text('AI总结');
                }
            },
            onerror: function(error) {
                console.error("太长不看_请求失败:", error);
                showErrorPopup("网络请求失败,请检查您的网络连接。");
                button.prop('disabled', false).text('AI总结');
            }
        });
    }

    function showSummaryPopup(summary) {
        const popup = $('<div class="ai-summary-popup"></div>')
            .css({
                'position': 'fixed',
                'top': '50%',
                'left': '50%',
                'transform': 'translate(-50%, -50%)',
                'background-color': 'rgba(0,0,0,0.8)',
                'color': 'white',
                'padding': '20px',
                'border-radius': '10px',
                'max-width': '80%',
                'max-height': '80vh',
                'overflow-y': 'auto',
                'z-index': '10000',
                'word-wrap': 'break-word',
                'font-size': '16px',
                'line-height': '1.6'
            })
            .html(`
                <div style="margin-bottom: 15px;">${summary}</div>
                <button class="ai-summary-close-btn" style="
                    position: absolute;
                    top: 10px;
                    right: 10px;
                    background: none;
                    border: none;
                    color: white;
                    font-size: 20px;
                    cursor: pointer;
                ">X</button>
            `)
            .appendTo('body');

        popup.find('.ai-summary-close-btn').on('click', function() {
            popup.remove();
        });

        // 点击其他区域关闭浮窗
        $(document).on('click', function(e) {
            if (!$(e.target).closest('.ai-summary-popup').length) {
                popup.remove();
            }
        });
    }

    // 显示错误提示浮窗
    function showErrorPopup(message) {
        const popup = $('<div class="ai-error-popup"></div>')
            .css({
                'position': 'fixed',
                'top': '50%',
                'left': '50%',
                'transform': 'translate(-50%, -50%)',
                'background-color': 'rgba(255,0,0,0.7)',
                'color': 'white',
                'padding': '20px',
                'border-radius': '10px',
                'z-index': '10000'
            })
            .html(`<p>${message}</p><button class="ai-error-close-btn">X</button>`)
            .appendTo('body');

        // 关闭错误浮窗
        popup.find('.ai-error-close-btn').on('click', function() {
            popup.remove();
        });
    }
})();