bilibili notify+

自动监听bilibili直播推送信息,当所关注者(包括悄悄关注)开启直播时自动打开直播网页的javascript脚本。30s获取一次关注列表的开播情况。自动开启一次后若主播不更改直播间标题、超过一定时间(可通过TimeOutMin设置)、重新设定白名单则不会再次打开。使用方法:在白名单模式(本修改仅限白名单模式)下输入想要自动开启的关注的主播的名字确认。

安装此脚本?
作者推荐脚本

您可能也喜欢bilibili notify

安装此脚本
  1. // ==UserScript==
  2. // @name bilibili notify+
  3. // @namespace heroesm
  4. // @match http://live.bilibili.com/feed/getList/1
  5. // @match https://live.bilibili.com/feed/getList/1
  6. // @match *api.live.bilibili.com/ajax/feed/list*
  7. // @match https://t.bilibili.com/*
  8. // @match https://live.bilibili.com/*
  9. // @grant unsafeWindow
  10. // @grant GM_setValue
  11. // @grant GM_getValue
  12. // @grant GM_deleteValue
  13. // @grant GM_listValues
  14. // @grant GM_removeValueChangeListener
  15. // @grant GM_addValueChangeListener
  16. // @version 1.2
  17. //
  18. // @description 自动监听bilibili直播推送信息,当所关注者(包括悄悄关注)开启直播时自动打开直播网页的javascript脚本。30s获取一次关注列表的开播情况。自动开启一次后若主播不更改直播间标题、超过一定时间(可通过TimeOutMin设置)、重新设定白名单则不会再次打开。使用方法:在白名单模式(本修改仅限白名单模式)下输入想要自动开启的关注的主播的名字确认。
  19. // ==/UserScript==
  20.  
  21. function main(){
  22. "use strict";
  23.  
  24. //var sAltAPI = '//api.live.bilibili.com/ajax/feed/list?pagesize=30&page=1';
  25. var sAltAPI = '//api.bilibili.com/x/polymer/web-dynamic/v1/portal';
  26. var running = true;
  27. var rProFilter, rConFilter,tarr;
  28. var rFilter = /./;
  29. var sMode = 'pro';
  30. var aTimer = [];
  31. var aAltRoomid = null;
  32. var sTitle = '';
  33. var isBuilt = false;
  34. var fArr = [];
  35. var TimeOutMin = 30;
  36. var reflashTime = 60*1000;
  37.  
  38. function reload(){
  39. run()
  40. }
  41. function prepare(){
  42. Document.prototype.$ = Document.prototype.querySelector;
  43. Element.prototype.$ = Element.prototype.querySelector;
  44. Document.prototype.$$ = Document.prototype.querySelectorAll;
  45. Element.prototype.$$ = Element.prototype.querySelectorAll;
  46. }
  47. function start(){
  48. var timer = setTimeout(function(){
  49. reload()
  50. }, reflashTime);
  51. aTimer.push(timer);
  52. document.$('#pause').style.display = 'unset';
  53. document.$('#start').style.display = 'none';
  54. document.title = sTitle;
  55. return timer;
  56. }
  57. function stop(){
  58. var nTimer = aTimer.pop();
  59. while (nTimer){
  60. clearTimeout(nTimer);
  61. nTimer = aTimer.pop();
  62. }
  63. document.$('#pause').style.display = 'none';
  64. document.$('#start').style.display = 'unset';
  65. sTitle = document.title;
  66. document.title = '已暂停';
  67. }
  68. function resetLocalStorage(){
  69. localStorage.removeItem('sfArr');
  70. fArr=[];
  71. for (var i=0;i<tarr.length;i++){
  72. fArr[i]={name:tarr[i],title:""};
  73. };
  74. localStorage.sfArr=JSON.stringify(fArr);
  75. }
  76. function listChanged(){
  77. if(fArr.length!=tarr.length){
  78. return 1;
  79. };
  80. for (var i = 0;i<tarr.length;i++){
  81. if(fArr[i].name!=tarr[i]){
  82. return 1;
  83. };
  84. }
  85. return 0;
  86. }
  87. function update(){
  88. try{
  89. // var sCon = document.$('#con').value.trim();
  90. // localStorage.bilinotify_con = sCon;
  91. // rConFilter = new RegExp(sCon);
  92. var sPro = document.$('#pro').value.trim();
  93. localStorage.bilinotify_pro = sPro;
  94.  
  95. tarr = JSON.parse('["' + sPro.replace(/\|/g, '","') + '"]');
  96. if (localStorage.sfArr){
  97. fArr=JSON.parse(localStorage.sfArr);
  98. if(listChanged()){
  99. resetLocalStorage();
  100. }
  101. }
  102. else{
  103. resetLocalStorage();
  104. }
  105. rProFilter = new RegExp(sPro);
  106. } catch(e){console.log(e);}
  107. localStorage.bilinotify_mod = sMode = 'pro';
  108. // localStorage.bilinotify_mod = sMode = document.$('input[name=mode]:checked').value;
  109. if (sMode == 'pro'){
  110. rFilter = rProFilter;
  111. }
  112. else{
  113. // rFilter = rConFilter;
  114. }
  115. }
  116. function checkopen(item){
  117. var con = Boolean(sMode == 'con');
  118. var sName = item.nickname || item.uname;
  119.  
  120. function opWin(url,roomid){
  121. if(typeof GM_getValue("room"+roomid) === 'undefined'||(new Date()).getTime()-GM_getValue("room"+roomid)>10*60*1000){
  122. window.open(url + '###')
  123. }
  124. }
  125. if(con ^ rFilter.test(sName)){
  126. for (var i=0;i<tarr.length;i++){
  127. if(sName==fArr[i].name){
  128. var timeout = !localStorage.getItem("room"+item.room_id)||(new Date().getTime()-localStorage.getItem("room"+item.room_id))>(1000*60*TimeOutMin);
  129. if(fArr[i].title==""||fArr[i].title!=item.title||timeout){
  130. fArr[i].title=item.title;
  131. localStorage.setItem("room"+item.room_id,(new Date()).getTime());
  132. localStorage.sfArr=JSON.stringify(fArr);
  133. opWin(item.jump_url,item.room_id);
  134. }
  135. }
  136. }
  137.  
  138. }
  139. }
  140. function build(){
  141. if (isBuilt){
  142. return
  143. }
  144. isBuilt = true;
  145. var style = document.createElement('style');
  146. style.id = 'bilinotify_css';
  147. style.innerHTML = [
  148. 'input[type=text] {width: 50%;}'
  149. ].join('\n');
  150. document.head.appendChild(style);
  151. document.querySelector('#app').insertAdjacentHTML(
  152. 'beforebegin',
  153. // document.body.insertAdjacentHTML(
  154. // 'beforeend',
  155. [
  156. // '<div class="con">',
  157. // ' <input type="radio" name="mode" value="con">',
  158. // ' <span>使用该正则表达式按昵称进行排除:</span>',
  159. // '<input id="con" type="text" placeholder="不想看的A的昵称|B的昵称|C的昵称">',
  160. // '</div>',
  161. '<div id="temp"style="position: relative; z-index: 1;">',
  162. '<style>display:block</style>',
  163. '<div class="pro">',
  164. ' <input type="radio" name="mode" value="pro" checked>',
  165. ' <span>使用该正则表达式按昵称进行匹配:</span>',
  166. ' <input id="pro" type="text" placeholder="想看的A的昵称|B的昵称|C的昵称">',
  167. '</div>',
  168. '<div>',
  169. ' <button id="confirm">确认</button>',
  170. ' <button id="pause">暂停</button>',
  171. ' <button id="start">继续</button>',
  172. ' <button id="hidden">隐藏</button>',
  173. '</div>',
  174. '</div>'
  175. ].join('\n')
  176. );
  177. // if (localStorage.bilinotify_con){
  178. // document.$('#con').value = localStorage.bilinotify_con;
  179. // }
  180. if (localStorage.bilinotify_pro){
  181. document.$('#pro').value = localStorage.bilinotify_pro;
  182. }
  183. if (localStorage.bilinotify_mod){
  184. document.$('input[type=radio][value=' + localStorage.bilinotify_mod + ']').checked = true;
  185. }
  186. update();
  187. document.$('#confirm').onclick = update;
  188. document.$('#start').onclick = start;
  189. document.$('#pause').onclick = stop;
  190. document.$('#hidden').onclick = function (){document.$('#temp').style.display="none";};
  191. }
  192. function process(sRes){
  193. try{
  194. prepare();
  195. }catch(e){}
  196. var Obj = JSON.parse(sRes);
  197. build();
  198. var Data = Obj.data;
  199. //window.temp.innerHTML = sRes;
  200. if(Obj.code == 401){
  201. window.temp.innerHTML += '<br /><br />未登录(不可用)';
  202. document.title = '未登录(不可用)';
  203. }
  204. else if(Data.live_users.count>0) {
  205. document.title = "(!)有" + Data.live_users.count + "个直播";
  206. for(var x=0, item, sHTML; x<Data.live_users.count; x++){
  207. item = Data.live_users.items[x];
  208. //if (aAltRoomid != null && aAltRoomid.indexOf(item.roomid) == -1){
  209. // window.temp.innerHTML += 'erroneous response from server';
  210. // document.title = '信息错误';
  211. // throw 'erroneous response from server';
  212. //}
  213. sHTML = ([
  214. '<br />',
  215. '<br />',
  216. '<div style="clear:both;">',
  217. ' <a style="float:left;" href="${item.jump_url}"><img style="width:100px; height: 100px;" src="${item.face}"></img></a>',
  218. ' <div style="float:left;">',
  219. ' <span>${item.nickname||item.uname}</span>',
  220. ' <br>',
  221. ' <a href="${item.jump_url}">${item.roomname||item.title}</a>',
  222. ' </div>',
  223. '</div>'
  224. ].join('\n').replace(/\$\{([^\}]+)\}/g, function(sMatch, sP1){
  225. return eval(sP1);
  226. }));
  227. //window.temp.innerHTML += sHTML
  228. checkopen(item);
  229. }
  230. }
  231. else{
  232. window.temp.innerHTML += '<br /><br />无直播';
  233. document.title = "无直播";
  234. }
  235. sTitle = document.title;
  236. start();
  237. console.log('ended');
  238. }
  239. function getAltList(callback){
  240. var xhr = new XMLHttpRequest();
  241. xhr.timeout = 5000;
  242. var sRes = '';
  243. xhr.ontimeout = xhr.onerror = function(e){
  244. console.log('timeout when getting alternative list');
  245. setTimeout(function(){
  246. reload()
  247. }, 5000);
  248.  
  249. };
  250. xhr.onload = function(e){
  251. try{
  252. sRes = xhr.response;
  253. callback(sRes);
  254. }catch(e){
  255. console.log(e.toString());
  256. setTimeout(function(){
  257. reload()
  258. }, 30000);
  259. }
  260. }
  261. xhr.withCredentials = true;
  262. xhr.open('get', sAltAPI)
  263. xhr.send();
  264. }
  265.  
  266. function run(){
  267. getAltList(function(sRes){
  268. sRes = sRes || document.body.childNodes[0].textContent
  269. process(sRes);
  270. });
  271. }
  272. run();
  273. }
  274.  
  275. function setcookie(){
  276. const regex = /[blanc|com]\/(\d+)/;
  277. let roomid = window.location.href.match(regex)[1];
  278.  
  279. // (function e(){
  280. // GM_setValue("room"+roomid,(new Date()).getTime());
  281. // console.log(GM_getValue("room"+roomid));
  282. // setTimeout(()=>{e()},5*60*1000);
  283. // })()
  284.  
  285. setInterval(() => {
  286. setTimeout(()=>{
  287. GM_setValue("room"+roomid,(new Date()).getTime());},0)
  288. }, 5*60*1000);
  289.  
  290. window.onbeforeunload = GM_deleteValue("room"+roomid);
  291. window.addEventListener('unload', function (event) {
  292. GM_deleteValue("room"+roomid);
  293. });
  294. }
  295. if (window.location.href.indexOf("live.bili") !== -1) {
  296. setcookie();}
  297. else{
  298. try{
  299. main();
  300. }catch(e){
  301. console.log(e.toString());
  302. setTimeout(function(){
  303. window.location.reload();
  304. }, 30000);
  305. }
  306. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址