您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
获取bilibili的直播弹幕内容并自动发送回复弹幕
// ==UserScript== // @name 雨天的自动回复机器人 // @namespace http://tampermonkey.net/ // @version 0.0.1 // @description 获取bilibili的直播弹幕内容并自动发送回复弹幕 // @author 雨天lul // @include /https?:\/\/live\.bilibili\.com\/?\??.*/ // @include /https?:\/\/live\.bilibili\.com\/\d+\??.*/ // @include /https?:\/\/live\.bilibili\.com\/(blanc\/)?\d+\??.*/ // @run-at document-start // @require https://cdn.jsdelivr.net/gh/google/brotli@5692e422da6af1e991f9182345d58df87866bc5e/js/decode.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/pako_inflate.min.js // @grant none // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js // @license MIT // ==/UserScript== //填入自己的id,检测弹幕的时候过滤掉自己发送的弹幕 var selfId = '4955333'; var autoReply = false; //cgd (function () { console.log('autoreply st') const HEADER_SIZE = 16 const WS_BODY_PROTOCOL_VERSION_NORMAL = 0 const WS_BODY_PROTOCOL_VERSION_HEARTBEAT = 1 const WS_BODY_PROTOCOL_VERSION_DEFLATE = 2 const WS_BODY_PROTOCOL_VERSION_BROTLI = 3 const OP_HEARTBEAT_REPLY = 3 const OP_SEND_MSG_REPLY = 5 let textEncoder = new TextEncoder() let textDecoder = new TextDecoder() function main() { if (window.bliveproxy) { // 防止多次加载 return } initApi() hook() } function initApi() { window.bliveproxy = api } let api = { addCommandHandler(cmd, handler) { let handlers = this._commandHandlers[cmd] if (!handlers) { handlers = this._commandHandlers[cmd] = [] } handlers.push(handler) }, removeCommandHandler(cmd, handler) { let handlers = this._commandHandlers[cmd] if (!handlers) { return } this._commandHandlers[cmd] = handlers.filter(item => item !== handler) }, // 私有API _commandHandlers: {}, _getCommandHandlers(cmd) { // if (this._commandHandlers[cmd] != null) { // console.log('HAND EXT ' + cmd); // } else { // console.log('HAND NE! ' + cmd); // } return this._commandHandlers[cmd] || null } } function hook() { window.WebSocket = new Proxy(window.WebSocket, { construct(target, args) { let obj = new target(...args) return new Proxy(obj, proxyHandler) } }) } let proxyHandler = { get(target, property) { let value = target[property] if ((typeof value) === 'function') { value = value.bind(target) } return value }, set(target, property, value) { if (property === 'onmessage') { let realOnMessage = value value = function (event) { myOnMessage(event, realOnMessage) } } target[property] = value return value } } function myOnMessage(event, realOnMessage) { if (!(event.data instanceof ArrayBuffer)) { realOnMessage(event) return } let data = new Uint8Array(event.data) function callRealOnMessageByPacket(packet) { realOnMessage({ ...event, data: packet }) } try { handleMessage(data, callRealOnMessageByPacket) } catch (e) { console.log('handlemessage Error: ' + e.message) // console.log(data) } } function makePacketFromCommand(command) { let body = textEncoder.encode(JSON.stringify(command)) return makePacketFromUint8Array(body, OP_SEND_MSG_REPLY) } function makePacketFromUint8Array(body, operation) { let packLen = HEADER_SIZE + body.byteLength let packet = new ArrayBuffer(packLen) // 不需要压缩 let ver = operation === OP_HEARTBEAT_REPLY ? WS_BODY_PROTOCOL_VERSION_HEARTBEAT : WS_BODY_PROTOCOL_VERSION_NORMAL let packetView = new DataView(packet) packetView.setUint32(0, packLen) // pack_len packetView.setUint16(4, HEADER_SIZE) // raw_header_size packetView.setUint16(6, ver) // ver packetView.setUint32(8, operation) // operation packetView.setUint32(12, 1) // seq_id let packetBody = new Uint8Array(packet, HEADER_SIZE, body.byteLength) for (let i = 0; i < body.byteLength; i++) { packetBody[i] = body[i] } return packet } function handleMessage(data, callRealOnMessageByPacket) { let offset = 0 while (offset < data.byteLength) { let dataView = new DataView(data.buffer, offset) let packLen = dataView.getUint32(0) // let rawHeaderSize = dataView.getUint16(4) let ver = dataView.getUint16(6) let operation = dataView.getUint32(8) // let seqId = dataView.getUint32(12) let body = new Uint8Array(data.buffer, offset + HEADER_SIZE, packLen - HEADER_SIZE) if (operation === OP_SEND_MSG_REPLY) { switch (ver) { case WS_BODY_PROTOCOL_VERSION_NORMAL: body = textDecoder.decode(body) body = JSON.parse(body) handleCommand(body, callRealOnMessageByPacket) break case WS_BODY_PROTOCOL_VERSION_DEFLATE: body = pako.inflate(body) handleMessage(body, callRealOnMessageByPacket) break case WS_BODY_PROTOCOL_VERSION_BROTLI: body = BrotliDecode(body) handleMessage(body, callRealOnMessageByPacket) break default: { let packet = makePacketFromUint8Array(body, operation) callRealOnMessageByPacket(packet) break } } } else { let packet = makePacketFromUint8Array(body, operation) callRealOnMessageByPacket(packet) } offset += packLen } } function handleCommand(command, callRealOnMessageByPacket) { if (command instanceof Array) { for (let oneCommand of command) { this.handleCommand(oneCommand) } return } let cmd = command.cmd || '' let pos = cmd.indexOf(':') if (pos != -1) { cmd = cmd.substr(0, pos) } // console.log('!! ' + cmd); let handlers = api._getCommandHandlers(cmd) if (handlers) { for (let handler of handlers) { handler(command) } } // console.log(command) let packet = makePacketFromCommand(command) callRealOnMessageByPacket(packet) } main() setTimeout(() => { //添加面板 var div = document.getElementById('control-panel-ctnr-box'); var btn = document.createElement('button'); btn.innerHTML = '自动回复:' + (autoReply ? '开' : '关'); btn.style.background = '#23ade5'; btn.style.color = 'white'; btn.style.cursor = 'pointer';; btn.style.padding = '6px 12px'; btn.style.border = '0'; btn.style.borderRadius = '4px'; btn.id = 'autoReplyBtn'; div.appendChild(btn); btn.addEventListener('click', () => { autoReply = !autoReply; btn.innerHTML = '自动回复:' + (autoReply ? '开' : '关'); }); }, 1000); })(); async function sendDM(sendMsg) { let shortUid = window.location.href.split('live.bilibili.com/')[1]; let room = await fetch(`http://api.live.bilibili.com/room/v1/Room/room_init?id=${shortUid}`, { method: 'GET', credentials: 'include' }) let roomid = await room.json(); roomid = roomid['data']['room_id']; let scrf = document.cookie.split(';').map(c => c.trim()).filter(c => c.startsWith('bili_jct='))[0].split('bili_jct=')[1]; let send = await fetch('https://api.live.bilibili.com/msg/send', { method: 'POST', credentials: 'include', headers: { 'accept': 'application/json, text/javascript, */*; q=0.01', 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: `color=16777215&fontsize=25&mode=1&msg=${sendMsg}&rnd=16082868&roomid=${roomid}&csrf_token=${scrf}&csrf=${scrf}` }); let sendApiRes = await send.json(); if (sendApiRes['message'] !== "") { console.log(`发送弹幕:【${sendMsg}】失败,原因:${sendApiRes['message']}。\n`); } else { console.log(`发送弹幕:【${sendMsg}】成功\n`); }; } (async function () { bliveproxy.addCommandHandler('DANMU_MSG', command => { console.log('get ' + command.info[1]); if (autoReply) { let info = command.info console.log('info--DANMU_MSG') console.log('user: ' + command.info[2][1] + ' : ' + command.info[2][0]); console.log('cont: ' + command.info[1]); var _dm = command.info[1]; var _userid = command.info[2][0]; var _username = command.info[2][1]; if (_userid == selfId.toString()) { console.log('idok'); if (_dm.match(/确实/)) { sendDM(_username + ', 确实'); } // } else if (_username.match(/^[a-zA-Z\_]*$/)) {//纯英文id // console.log('纯英文id: ' + _userid); else if (_dm.match(/晚安/)) { sendDM(_username + '晚安'); } } } } // if (command.info[1].toString().substr(0, 5) != 'reply') // sendDM('reply-- ' + command.info[2][1]) ); bliveproxy.addCommandHandler('ROOM_REAL_TIME_MESSAGE_UPDATE', command => { if (autoReply) { let info = command console.log('info--ROOM_REAL_TIME_MESSAGE_UPDATE ' + Object.keys(info.data)) console.log(Object.values(info.data)); console.log(''); } }); // bliveproxy.addCommandHandler('NOTICE_MSG', command => { // let info = command // console.log('info--NOTICE_MSG ' + Object.keys(info.data)) // console.log(Object.values(info.data)); // console.log(''); // }); // bliveproxy.addCommandHandler('INTERACT_WORD', command => { // let info = command // console.log('info--INTERACT_WORD ' + Object.keys(info.data)) // console.log(Object.values(info.data)); // console.log(''); // }); // bliveproxy.addCommandHandler('STOP_LIVE_ROOM_LIST', command => { // let info = command // console.log('info--STOP_LIVE_ROOM_LIST ' + Object.keys(info.data)) // console.log(Object.values(info.data)); // console.log(''); // }); // bliveproxy.addCommandHandler('NOTICE_MSG', command => { // let info = command // console.log('info--NOTICE_MSG ' + Object.keys(info.data)) // console.log(Object.values(info.data)); // console.log(''); // }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址