Greasy Fork

Greasy Fork is available in English.

猫耳迎宾机器人

一个简单的迎宾机器人

当前为 2024-10-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         猫耳迎宾机器人
// @version      1.7.6.8
// @description  一个简单的迎宾机器人
// @author       洋子
// @match        https://fm.missevan.com/live/*
// @icon         https://static.maoercdn.com/avatars/202408/25/2bf1715cfc845d8b4da511d8f5345fec210801.jpg?x-oss-process=style/avatar
// @grant        none
// @namespace    http://greasyfork.icu/users/1357490
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/index.js
// ==/UserScript==

(function() {
'use strict';

// 从当前网址获取房间号
let roomId = window.location.pathname.split("/").pop();

// 欢迎用户列表
let welcomedUsers = [];

// 存储已处理的消息 ID
let processedMsgIds = new Set();

// 全局变量,用于存储歌曲列表
let songList = [];
let isWelcomingEnabled = true;
let isHistoryFetchingEnabled = true;

// 打卡数据文件
const checkInDataKey = "checkInData";

// DP 字符数据文件
const dpLibraryKey = "dpLibrary";

// 欢迎词数据文件
const welcomeMessagesKey = "welcomeMessages";

// 字符编号
let nextDpId = parseInt(localStorage.getItem('nextDpId') || '0', 10);


// 创建可隐藏的控制面板和按钮的容器
function createControlPanelContainer() {
const container = document.createElement('div');
container.style.position = 'fixed';
container.style.top = '10px';
container.style.left = '10px'; // 从左侧展开
container.style.zIndex = '10000';

const panel = document.createElement('div');
panel.style.backgroundColor = '#f0f0f0';
panel.style.border = '1px solid #ccc';
panel.style.width = '400px'; // 调整宽度
panel.style.height = '300px'; // 调整高度
panel.style.display = 'none'; // 默认隐藏
panel.style.position = 'relative'; // 使面板在容器内定位
panel.style.display = 'flex'; // 使用flex布局

// 左侧菜单
const menu = document.createElement('div');
menu.style.width = '100px'; // 左侧菜单的宽度
menu.style.borderRight = '1px solid #ccc';
menu.style.padding = '10px';
menu.style.display = 'flex';
menu.style.flexDirection = 'column';

// 创建左侧菜单项
const createMenuButton = (text) => {
    const button = document.createElement('button');
    button.textContent = text;
    button.style.marginBottom = '5px';
    button.style.backgroundColor = 'transparent';  // 隐藏按钮背景
    button.style.border = 'none';  // 隐藏按钮边框
    button.style.cursor = 'pointer';  // 设置为手型指针
    return button;
};

const indexTab = createMenuButton('主 页');
const basicSettingsTab = createMenuButton('基本设置');
const dpSettingsTab = createMenuButton('灯牌设置');
const welcomeSettingsTab = createMenuButton('欢迎设置');
const ShortcutsTab = createMenuButton('快捷工具');

// 将菜单项添加到菜单容器
menu.appendChild(document.createElement('hr'));  // 创建横线
menu.appendChild(indexTab);
menu.appendChild(document.createElement('hr'));  // 创建横线
menu.appendChild(basicSettingsTab);
menu.appendChild(document.createElement('hr'));  // 创建横线
menu.appendChild(dpSettingsTab);
menu.appendChild(document.createElement('hr'));  // 创建横线
menu.appendChild(welcomeSettingsTab);
menu.appendChild(document.createElement('hr'));  // 创建横线
menu.appendChild(ShortcutsTab);
menu.appendChild(document.createElement('hr'));  // 创建横线

// 右侧内容区
const contentArea = document.createElement('div');
contentArea.style.flex = '1';
contentArea.style.padding = '10px';
contentArea.style.overflowY = 'auto'; // 允许滚动

const indexContent = `
<h3>主页</h3>
<p>本脚本无偿提供给所有猫耳FM主播使用,内容不定时更新。</p>
<p>作者:S洋子 | Mid:3368718</p>
<p>发布地址/历史更新:<a href="http://greasyfork.icu/zh-CN/scripts/505115-%E7%8C%AB%E8%80%B3%E8%BF%8E%E5%AE%BE%E6%9C%BA%E5%99%A8%E4%BA%BA/versions?version=1444876" target="_blank">点击跳转</a></p>
<p>说明书:<a href="https://docs.qq.com/doc/DRmFyTHZDTHdPaW1H" target="_blank">点击跳转</a></p>
`;

const basicSettingsContent = `
<h3>基本设置</h3>
<div>
    <label for="roomIdInput">房间号:</label>
    <input type="text" id="roomIdInput" value="${roomId}">
</div>
<div>
    <label for="welcomeToggle">启用/禁用欢迎用户功能:</label>
    <input type="checkbox" id="welcomeToggle" ${isWelcomingEnabled ? 'checked' : ''}>
</div>
<div>
    <label for="historyToggle">启用/禁用信息回应功能:</label>
    <input type="checkbox" id="historyToggle" ${isHistoryFetchingEnabled ? 'checked' : ''}>
</div>
<button id="saveSettingsBtn">保存设置</button>
`;

const dpSettingsContent = `
<h3>灯牌设置</h3>
<div>
    <label for="dpInput">灯牌字符:</label>
    <textarea id="dpInput" rows="4" cols="50" placeholder="输入多行 DP 字符..."></textarea>
</div>
<div>
    <label for="dpId">灯牌编号:</label>
    <input type="number" id="dpId" min="0">
</div>
<div>
    <label for="dpDesc">灯牌描述:</label>
    <input type="text" id="dpDesc">
</div>
<button id="saveDpBtn">保存灯牌</button>
`;

// 欢迎设置内容
const welcomeSettingsContent = `
<h3>欢迎设置</h3>
<div>
<label for="welcomeMessagesInput">欢迎词:</label>
<textarea id="welcomeMessagesInput" rows="4" cols="50" placeholder="输入多个欢迎词,使用/n/分隔..."></textarea>
</div>
<button id="saveWelcomeMessagesBtn">保存欢迎词</button>
<p style="font-size: 16px;">多行示例:</p>
<p style="font-size: 14px;">欢迎 {username}</p>
<p style="font-size: 14px;">拼音是 {pinyin}</p>
<p style="font-size: 14px;">加入时间是 {date}</p>
<p style="font-size: 14px;">/n/</p>
<p style="font-size: 16px;">单行行示例:</p>
<p style="font-size: 14px;">嗨 {username},拼音:{pinyin},今天是 {date},欢迎加入!/n/</p>
<hr>
<p style="font-size: 16px;">用法:</p>
<p style="font-size: 14px;"><p style="font-size: 14px;"><p style="font-size: 14px;">每段欢迎词以/n/符号隔开</p>
<p style="font-size: 14px;"><p style="font-size: 14px;">{username}代表要欢迎的用户名,{pinyin}代表用户名的拼音,{date}代表加入直播间的日期</p>
<p style="font-size: 16px;">注:/n/分隔符号不可少 {username} {pinyin} {date}一定要切换成英文输入法输入,或者直接复制</p>
<hr>
<p style="font-size: 16px;">看不明白的可以直接复制上面的示例</p>
`;

const ShortcutsContent = `
<h3>快捷工具</h3>
<button id="jumpButton">音频投稿</button>
`;

// 默认显示主页内容
contentArea.innerHTML = indexContent;

const resetButtonStyles = () => {
    indexTab.style.fontWeight = 'normal';
    basicSettingsTab.style.fontWeight = 'normal';
    dpSettingsTab.style.fontWeight = 'normal';
    welcomeSettingsTab.style.fontWeight = 'normal';
};


// 切换到主页
indexTab.addEventListener('click', () => {
    contentArea.innerHTML = indexContent;
    resetButtonStyles();
    indexTab.style.fontWeight = 'bold';
});

// 切换到基本设置
basicSettingsTab.addEventListener('click', () => {
    contentArea.innerHTML = basicSettingsContent;
    resetButtonStyles();
    basicSettingsTab.style.fontWeight = 'bold';

    document.getElementById('saveSettingsBtn').addEventListener('click', () => {
        roomId = document.getElementById('roomIdInput').value;
        isWelcomingEnabled = document.getElementById('welcomeToggle').checked;
        isHistoryFetchingEnabled = document.getElementById('historyToggle').checked;
        alert("设置已保存!");
    });
});

// 切换到 DP 设置
dpSettingsTab.addEventListener('click', () => {
    contentArea.innerHTML = dpSettingsContent;
    resetButtonStyles();
    dpSettingsTab.style.fontWeight = 'bold';

    document.getElementById('saveDpBtn').addEventListener('click', () => {
        const dpId = parseInt(document.getElementById('dpId').value.trim(), 10);
        const dpChar = document.getElementById('dpInput').value.trim();
        const dpDesc = document.getElementById('dpDesc').value.trim();

        if (dpId >= 0 && dpChar && dpDesc) {
            dpLibrary.set(dpId, { char: dpChar, desc: dpDesc });
            saveDpLibrary();
            alert("DP 字符已保存!");
            document.getElementById('dpId').value = '';
            document.getElementById('dpInput').value = '';
            document.getElementById('dpDesc').value = '';
        } else {
            alert("请填写正确的 DP 编号、字符和描述!");
        }
    });
});

// 切换到快捷设置
ShortcutsTab.addEventListener('click', () => {
    contentArea.innerHTML = ShortcutsContent;
    resetButtonStyles();
    ShortcutsTab.style.fontWeight = 'bold';

    document.getElementById('jumpButton').onclick = () => window.open('https://www.missevan.com/msound/create', '_blank');

});


// 加载用户自定义欢迎词并显示在输入框中
const loadCustomWelcomeMessages = () => {
    const messages = localStorage.getItem('customWelcomeMessages');
    return messages ? messages.split('/n/') : [];
};

// 在欢迎设置选项卡中添加事件监听
welcomeSettingsTab.addEventListener('click', () => {
    contentArea.innerHTML = welcomeSettingsContent;
    resetButtonStyles();
    welcomeSettingsTab.style.fontWeight = 'bold';

    // 加载并显示欢迎词
    const customMessages = loadCustomWelcomeMessages();
    document.getElementById('welcomeMessagesInput').value = customMessages.join('/n/');

    // 保存按钮事件
    document.getElementById('saveWelcomeMessagesBtn').addEventListener('click', () => {
        let newMessages = document.getElementById('welcomeMessagesInput').value;

        // 去掉每条消息前后的空格或多余的换行符
        let cleanedMessages = newMessages.split('/n/').map(message => message.trim());

        // 将清理后的欢迎词重新组合并保存
        localStorage.setItem('customWelcomeMessages', cleanedMessages.join('/n/'));

        alert("欢迎词已保存!");
    });

});

panel.appendChild(menu);
panel.appendChild(contentArea);

// 创建控制面板按钮
const toggleButton = document.createElement('button');
toggleButton.style.background = 'url(https://static.maoercdn.com/avatars/202408/25/2bf1715cfc845d8b4da511d8f5345fec210801.jpg?x-oss-process=style/avatar) no-repeat center center';
toggleButton.style.backgroundSize = 'cover';
toggleButton.style.border = 'none';
toggleButton.style.width = '50px';
toggleButton.style.height = '50px';
toggleButton.style.cursor = 'pointer';
toggleButton.textContent = ''; // 默认显示文字,便于访问性

container.appendChild(toggleButton);
container.appendChild(panel);
document.body.appendChild(container);

// 切换控制面板显示
toggleButton.addEventListener('click', () => {
    panel.style.display = panel.style.display === 'none' ? 'flex' : 'none';
});

return container;
}

// 创建并添加控制面板容器到页面
createControlPanelContainer();




// 从 localStorage 读取打卡数据
function loadCheckInData() {
const data = localStorage.getItem(checkInDataKey);
return data ? JSON.parse(data) : {};
}

// 保存打卡数据到 localStorage
function saveCheckInData() {
localStorage.setItem(checkInDataKey, JSON.stringify(Object.fromEntries(checkInData)));
}

// 初始化打卡数据
const checkInData = new Map(Object.entries(loadCheckInData()));

// 从 localStorage 读取 DP 字符库
function loadDpLibrary() {
const data = localStorage.getItem(dpLibraryKey);
const dpLibraryData = data ? JSON.parse(data) : {};

// 恢复 DP 字符库
return new Map(Object.entries(dpLibraryData).map(([id, { char, desc }]) => [parseInt(id, 10), { char, desc }]));
}

// 保存 DP 字符库到 localStorage
function saveDpLibrary() {
// 将 dpLibrary 转换为对象
const dpLibraryData = Object.fromEntries(dpLibrary);
localStorage.setItem(dpLibraryKey, JSON.stringify(dpLibraryData));
}

// 初始化 DP 字符库
let dpLibrary = loadDpLibrary();

// 从 localStorage 读取欢迎词库
function loadWelcomeMessages() {
const data = localStorage.getItem(welcomeMessagesKey);
const welcomeMessagesData = data ? JSON.parse(data) : {};

// 恢复欢迎词
return welcomeMessagesData.messages || [];
}

// 保存欢迎词库到 localStorage
function saveWelcomeMessages(welcomeMessages) {
const welcomeMessagesObj = { messages: welcomeMessages };
localStorage.setItem(welcomeMessagesKey, JSON.stringify(welcomeMessagesObj));
}

// 初始化欢迎词库
let welcomeMessages = loadWelcomeMessages();



// 过滤消息中的屏蔽词
function filterMessage(message, filterWords) {
filterWords.forEach(word => {
    let regex = new RegExp(word, 'g');
    message = message.replace(regex, '***');
});
return message;
}

// 屏蔽词数组示例
let filterWords = ["不良词1", "不良词2"];

// 生成UUID v4
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random() * 16 | 0,
        v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
});
}

// 封装的发送消息函数
async function sendMessage(message, retries = 3) {
let filteredMessage = filterMessage(message, filterWords);
const maxLength = 200 // 每段消息的最大字符数
const url = 'https://fm.missevan.com/api/chatroom/message/send';

// 将消息分段
let messageChunks = [];
for (let i = 0; i < filteredMessage.length; i += maxLength) {
    messageChunks.push(filteredMessage.slice(i, i + maxLength));
}

const sendChunk = async (chunk) => {
    const data = {
        room_id: roomId,
        message: chunk,
        uuid: generateUUID()
    };

    const options = {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'user-agent': navigator.userAgent,
            'cookie': document.cookie,
            'origin': 'missevan.com',
            'referer': `https://fm.missevan.com/live/${roomId}`
    },
        body: JSON.stringify(data)
    };

    for (let attempt = 1; attempt <= retries; attempt++) {
        try {
            const response = await fetch(url, options);
            const responseData = await response.json();
            if (responseData.code === 0) {
                console.log('消息发送成功:', responseData);
                return true; // 成功退出
            } else {
                console.error('发送失败:', responseData);
                if (attempt === retries) {
                    console.error('达到最大重试次数,消息未发送');
                }
            }
        } catch (error) {
            console.error('请求错误:', error);
            if (attempt === retries) {
                console.error('达到最大重试次数,消息未发送');
            }
        }
    }
    return false; // 发送失败
};

// 按顺序发送每个分段
for (let chunk of messageChunks) {
    let success = await sendChunk(chunk);
    if (!success) {
        console.error('部分消息发送失败,停止发送剩余分段');
        break; // 如果某个分段发送失败,停止发送
    }
}
}


// 预存的欢迎消息
const defaultWelcomeMessages = [
'|欢迎@{username}\n|[拼音]:{pinyin}\n|日期:{date}',
'欢迎@{username} 在 {date}加入直播间!\n拼音:{pinyin},'
];

// 从 localStorage 读取用户自定义欢迎词
function loadCustomWelcomeMessages() {
const customMessages = localStorage.getItem('customWelcomeMessages');
return customMessages ? customMessages.split('/n/') : [];
}

// 生成欢迎消息
function getWelcomeMessage(username, pinyinUsername, formattedDate) {
const customMessages = loadCustomWelcomeMessages();
const messagesToUse = customMessages.length > 0 ? customMessages : defaultWelcomeMessages;

const randomWelcomeMessage = messagesToUse[Math.floor(Math.random() * messagesToUse.length)];
return randomWelcomeMessage.replace('{username}', username)
    .replace('{pinyin}', pinyinUsername)
    .replace('{date}', formattedDate);
}

// 每秒检测用户加入
setInterval(() => {
if (!isWelcomingEnabled) return;

const appElement = document.querySelector('app');
if (appElement) {
    const appContent = appElement.innerHTML;
    const parser = new DOMParser();
    const doc = parser.parseFromString(appContent, 'text/html');
    const chatboxDiv = doc.querySelector('div#Room');
    if (chatboxDiv) {
        const joinDivs = chatboxDiv.querySelectorAll('div.join-queue-effect.show.clickable');
        if (joinDivs.length > 0) {
            joinDivs.forEach((userDiv) => {
                let usernameDiv = userDiv.querySelector('.username');
                let username = usernameDiv ? usernameDiv.textContent.trim() : '';
                if (username && !welcomedUsers.includes(username)) {
                    welcomedUsers.push(username);

                    let currentDate = new Date();
                    let formattedDate = currentDate.toLocaleString('zh-CN', {
                        year: 'numeric',
                        month: '2-digit',
                        day: '2-digit',
                        hour: '2-digit',
                        minute: '2-digit',
                        second: '2-digit',
                        hour12: false
                    });

                    let pinyinUsername = pinyinPro.pinyin(username, { style: pinyinPro.STYLE_NORMAL });

                    // 获取欢迎消息
                    let welcomeMessage = getWelcomeMessage(username, pinyinUsername, formattedDate);

                    sendMessage(welcomeMessage);
                    console.log(`用户 ${username} (${pinyinUsername}) 已加入并发送欢迎消息`);
                }
            });
        }
    } else {
        console.log('未找到 id 为 ChatBox 的 div');
    }
} else {
    console.log('未找到 <app> 标签');
}

// 欢迎匿名用户
const joinQueueElement = document.querySelector('.join-queue-effect');
if (joinQueueElement) {
    const joinUserText = joinQueueElement.querySelector('.join-user').textContent;
    const now = new Date();
    const date = now.toLocaleTimeString(); // 获取当前时间

    // 使用模板字符串插入变量
    sendMessage(`|欢迎 ${joinUserText}\n|日期: ${date}`);
} else {
    console.log('未找到元素');
}

}, 1000); // 每秒检测一次


// 每秒获取一次历史消息并检查内容
setInterval(async function() {
if (!isHistoryFetchingEnabled) return;

const url = `https://fm.missevan.com/api/v2/chatroom/history/message?room_id=${roomId}`;

try {
    const response = await fetch(url);
    const data = await response.json();

    if (data.code === 0 && data.info && data.info.history) {
        const currentTimestamp = Date.now(); // 获取当前时间戳

        data.info.history.forEach(async messageData => {
            const { msg_id, create_time, message, user } = messageData;
            const timeDiff = currentTimestamp - create_time;

            // 检查时间差,若在 1 秒内则处理
            if (timeDiff <= 1000 && !processedMsgIds.has(msg_id)) {


                // 检测用户输入 DP 字符
                if (message.startsWith("dp ")) {
                    const dpInput = message.substring(3).trim();
                    const dpId = parseInt(dpInput, 10);

                    if (!isNaN(dpId) && dpLibrary.has(dpId)) {
                        const dpData = dpLibrary.get(dpId);
                        await sendMessage(`${dpData.char}`);
                    }
                }

                if (message === "dp") {
                    // 随机发送一个 DP 字符
                    const dpIds = Array.from(dpLibrary.keys());
                    if (dpIds.length >= 0) {
                        const randomId = dpIds[Math.floor(Math.random() * dpIds.length)];
                        const dpData = dpLibrary.get(randomId);
                        await sendMessage(`${dpData.char}`);
                    } else {
                        await sendMessage("DP 字符库为空!");
                    }
                }

                if (message === "dp列表") {
                    // 发送所有 DP 字符的编号和描述
                    if (dpLibrary.size > 0) {
                        let response = "DP 字符列表:\n";
                        // 按编号排序
                        const sortedDpLibrary = Array.from(dpLibrary.entries()).sort((a, b) => a[0] - b[0]);
                        sortedDpLibrary.forEach(([id, value]) => {
                            response += `编号: ${id} - 描述: ${value.desc}\n\n`;
                        });
                        await sendMessage(response.trim());
                    } else {
                        await sendMessage("DP 字符库为空!");
                    }
                }

                // 处理 DP 字符添加命令
                if (message.startsWith("dp添加 ") || message.startsWith("dp+ ")) {
                    const dpInput = message.substring(6).trim();
                    if (dpInput) {
                        // 使用递增的编号
                        const dpId = nextDpId++;
                        dpLibrary.set(dpId, { char: dpInput, desc: '' });

                        // 保存 DP 字符库和更新编号
                        saveDpLibrary();
                        localStorage.setItem('nextDpId', nextDpId.toString());

                        await sendMessage(`DP 字符已添加:编号 ${dpId}\n字符: ${dpInput}`);
                    } else {
                        await sendMessage("请提供 DP 字符!");
                    }
                }

                // 处理删除命令
                if (message.startsWith("dp删除 ") || message.startsWith("dp- ")) {
                    const dpId = parseInt(message.substring(4).trim(), 10);
                    if (dpLibrary.has(dpId)) {
                        dpLibrary.delete(dpId);
                        saveDpLibrary(); // 保存更新后的 DP 字符库
                        await sendMessage(`编号 ${dpId} 的 DP 字符已删除!`);
                    } else {
                        await sendMessage(`编号 ${dpId} 的 DP 字符不存在!`);
                    }
                }

                // 检查是否匹配到“我是谁”信息
                if (message === "我是谁") {
                    const userId = user.user_id;
                    const username = user.username;
                    const level = user.titles.find(title => title.type === 'level')?.level;

                    console.log('匹配到“我是谁”信息:');
                    console.log('用户ID:', userId);
                    console.log('用户名:', username);
                    console.log('等级:', level);

                    // 将用户ID、用户名和等级传递给fetchPageData函数
                    await fetchPageData(userId, username, level);
                }

                // 检查用户是否输入了 "直播间" 命令
                if (message === "直播间") {
                    console.log('用户请求直播间信息');

                    // 调用 zhibojian 函数并传递 roomId
                    await zhibojian(roomId);
                }

                //点歌功能
                if (message.startsWith("点歌 ")) {
                    const songName = message.substring(3).trim();
                    requestSong('add', songName);
                    requestSong('show');
                } else if (message.startsWith("删歌 ")) {
                    const songName = message.substring(3).trim();
                    requestSong('delete', songName);
                    requestSong('show');
                } else if (message === "歌单") {
                    requestSong('show');
                }

                // 打卡功能
                if (message === "dd" || message === "打卡") {
                    const username = user.username;
                    const currentDate = new Date();
                    const checkInTime = currentDate.toLocaleString(); // 打卡时间

                    // 从打卡数据中获取用户信息
                    if (checkInData.has(username)) {
                        const userData = checkInData.get(username);

                        // 解析最后打卡时间
                        const lastCheckInDate = new Date(userData.lastCheckInTime);

                        // 比较日期(只比较年月日)
                        const lastCheckInDay = lastCheckInDate.toISOString().split('T')[0];
                        const currentDay = currentDate.toISOString().split('T')[0];

                        if (lastCheckInDay === currentDay) {
                            // 用户今天已经打过卡
                            await sendMessage(`用户 ${username},今天已经打过卡了!`);
                        } else {
                            // 用户未打过卡,添加新打卡记录
                            userData.count += 1;
                            userData.lastCheckInTime = checkInTime;
                            checkInData.set(username, userData);

                            // 构建打卡完成消息
                            let message = `打卡成功!\n\n| 用户名: ${username}\n| 打卡次数: ${userData.count}\n| 打卡时间: ${userData.lastCheckInTime}`;

                            // 调用 sendMessage 函数发送消息
                            await sendMessage(message);

                            // 保存打卡数据至 localStorage
                            saveCheckInData();
                        }
                    } else {
                        // 用户不在打卡数据中,初始化打卡记录
                        checkInData.set(username, { count: 1, lastCheckInTime: checkInTime });

                        // 构建打卡完成消息
                        let message = `打卡成功!\n\n| 用户名: ${username}\n| 打卡次数: 1\n| 打卡时间: ${checkInTime}`;

                        // 调用 sendMessage 函数发送消息
                        await sendMessage(message);

                        // 保存打卡数据至 localStorage
                        saveCheckInData();
                    }
                }



                // 查看所有打卡数据功能
                if (message === "查看打卡数据") {
                    if (checkInData.size > 0) {
                        // 构建查看打卡数据的消息
                        let message = `所有用户的打卡数据:\n\n`;

                        checkInData.forEach((userData, username) => {
                            message += `| 用户名: ${username}\n| 打卡次数: ${userData.count}\n| 最后打卡时间: ${userData.lastCheckInTime}\n\n`;
                        });

                        // 调用 sendMessage 函数发送所有打卡数据
                        await sendMessage(message);
                    } else {
                        // 如果没有任何打卡数据
                        await sendMessage(`没有任何打卡数据。`);
                    }
                }



                //帮助
                if (message === "帮助") {
                    sendMessage(`请访问:https://docs.qq.com/doc/DRmFyTHZDTHdPaW1H`);
                }

                processedMsgIds.add(msg_id); // 将处理过的消息 ID 添加到集合中
            }
        });
    } else {
        console.error('无法获取消息历史:', data);
    }
} catch (error) {
    console.error('请求失败:', error);
}
}, 1000); // 每秒请求一次

// 修改fetchPageData函数以接受userId、username和level参数
async function fetchPageData(userId, username, level) {
try {
    // 使用模板字符串动态插入 userId
    const url = `https://www.missevan.com/${userId}/`;
    console.log('Fetching URL:', url);

    const response = await fetch(url);
    const html = await response.text();

    // 创建一个 DOMParser 来解析 HTML
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');

    // 提取信息
    const botText = doc.querySelector('#t_u_n_a')?.textContent.trim();
    const followCount = doc.querySelector('.home-follow span')?.textContent.trim();
    const fanCount = doc.querySelector('.home-fans span')?.textContent.trim();

    // 提取注册日期,使用正则从 span 中提取日期部分
    const timeSpan = doc.querySelector('.time')?.textContent.trim();
    const dateMatch = timeSpan?.match(/注册于 (\d{4}-\d{2}-\d{2})/);
    const date = dateMatch ? dateMatch[1] : '未找到日期';

    // 提取鱼干数量
    const fishCount = doc.querySelector('.fish')?.textContent.trim();

    // 格式化消息内容
    let message = `|用户名: ${username}\n|等级: ${level}\n|个性签名: ${botText}\n|关注人数: ${followCount}\n|粉丝人数: ${fanCount}\n|鱼干: ${fishCount}`;

    // 调用 sendMessage 函数发送消息
    await sendMessage(message);

} catch (error) {
    console.error('网页抓取失败:', error);
}
}

async function zhibojian(roomid) {
const url = `https://fm.missevan.com/api/v2/live/${roomid}`;

try {
    // 发送请求并获取响应
    const response = await fetch(url);
    const data = await response.json();

    // 提取房间信息
    const room_info = data['info']['room'];
    const room_name = room_info['name'];
    const room_id = room_info['room_id'];
    const accumulation = room_info['statistics']['accumulation'];
    const online = room_info['statistics']['online'];
    const attention_count = room_info['statistics']['attention_count'];
    const vip_status = room_info['statistics']['vip'];
    const score = room_info['statistics']['score'];
    const open_time_timestamp = room_info['status']['open_time'];

    // 将时间戳转换为 Date 对象
    const open_time = new Date(open_time_timestamp);

    // 获取当前时间
    const current_time = new Date();

    // 计算时间差
    const time_diff = current_time - open_time;

    // 计算天、小时、分钟和秒数
    const days = Math.floor(time_diff / (1000 * 60 * 60 * 24));
    const hours = Math.floor((time_diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
    const minutes = Math.floor((time_diff % (1000 * 60 * 60)) / (1000 * 60));
    const seconds = Math.floor((time_diff % (1000 * 60)) / 1000);

    // 格式化开播时间和时长
    const open_time_str = `${open_time.getFullYear()}-${(open_time.getMonth() + 1).toString().padStart(2, '0')}-${open_time.getDate().toString().padStart(2, '0')} ${open_time.getHours().toString().padStart(2, '0')}:${open_time.getMinutes().toString().padStart(2, '0')}`;
    const time_diff_str = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;

    // 发送消息
    const message = `|房间名称: ${room_name}\n|房间ID: ${room_id}\n|在线人数: ${online}\n|累积人数: ${accumulation}\n|关注人数: ${attention_count}\n|贵族人数: ${vip_status}\n|热度: ${score}\n|开播时间: ${open_time_str}\n|开播时长: ${time_diff_str}`;
    // 调用 sendMessage 函数发送消息
    await sendMessage(message);

} catch (error) {
    console.error('Error fetching room data:', error);
}
}


// 点歌功能实现
function requestSong(action, songName = null) {
try {
    if (action === 'add' && songName) {
        // 添加歌曲
        if (!songList.includes(songName)) {
            songList.push(songName);
            sendMessage(`已添加歌曲: ${songName}`);
        } else {
            sendMessage(`歌曲: ${songName} 已在列表中`);
        }
    } else if (action === 'delete' && songName) {
        // 删除歌曲
        const index = songList.indexOf(songName);
        if (index !== -1) {
            songList.splice(index, 1);
            sendMessage(`已删除歌曲: ${songName}`);
        } else {
            sendMessage(`歌曲: ${songName} 不在列表中`);
        }
    } else if (action === 'show') {
        // 显示歌曲列表
        if (songList.length > 0) {
            const songListStr = songList.join('\n');
            sendMessage(`<歌曲列表>:\n${songListStr}`);
        } else {
            sendMessage("歌曲列表为空");
        }
    }
} catch (error) {
    console.error(`点歌功能发生异常: ${error}`);
}
}

})();