// ==UserScript==
// @name JIRA未处理任务通知
// @namespace https://blog.csdn.net/weixin_43515759
// @version 1.0
// @description Polls an API endpoint and sends a notification if conditions are met
// @author 72.1k
// @match http://10.1.1.200:8080/*
// @grant GM_notification
// ==/UserScript==
(function () {
'use strict';
// 每10s查询一次
const INTERVAL = 10 * 1000;
// 设置api接口
const API_URL = '/rest/issueNav/1/issueTable';
const CACHE_KEY = 'jira-bug-cache'
// 开始运行
run()
function run() {
pollAPI()
setInterval(pollAPI, INTERVAL);
}
// Function to poll the API endpoint
function pollAPI() {
fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Atlassian-Token': 'no-check',
'X-Requested-With': 'XMLHttpRequest',
},
// body内容从/issues/?filter=-1页面中的接口/rest/issueNav/1/issueTable获取
body: 'startIndex=0&filterId=-1&jql=resolution+%3D+Unresolved+AND+assignee+in+(currentUser())+ORDER+BY+updatedDate+DESC&layoutKey=split-view'
})
.then(response => response.json())
.then(data => {
const issueTable = data.issueTable || {}
const table = issueTable.table || []
// 检测第一次运行
const cacheData = readCache()
if (cacheData.length <= 0) {
const keys = table.map(item => item.key)
saveCache(keys)
return
}
table.map(item => {
const { key, status, summary } = item || {}
if (["挂起"].includes(status)) return
// 新数据
if (!cacheData.includes(key)) {
saveCache(key)
sendNotification(key, '您有一个新的任务待处理', summary)
}
})
})
.catch(error => console.error(error));
}
// 发送通知
function sendNotification(key, title, text) {
const NOTIFICATION_OPTIONS = {
title,
text,
image: '/favicon.ico',
timeout: 0,
onclick() {
window.open(`/browse/${key}`)
},
};
GM_notification(NOTIFICATION_OPTIONS);
}
// 保存key到缓存
function saveCache(key) {
if(typeof key === 'object'){
setStorageJSON(CACHE_KEY, key)
return
}
// 读缓存
const cacheData = readCache()
// 修改值
if (!cacheData.includes(key)) {
cacheData.push(key)
// 写缓存
setStorageJSON(CACHE_KEY, cacheData)
}
}
// 读取key缓存
function readCache() {
return getStorageJSON(CACHE_KEY, '[]')
}
/**
* Storage
* @param {*} name 名称
* @param {*} value 值
*/
function setStorage(name, value) {
return localStorage.setItem(name, value)
}
function getStorage(name) {
return localStorage.getItem(name)
}
function setStorageJSON(name, value = {}) {
return localStorage.setItem(name, JSON.stringify(value))
}
function getStorageJSON(name, defultData = '{}') {
return JSON.parse(localStorage.getItem(name) || defultData)
}
function removeStorage(name) {
return localStorage.removeItem(name)
}
function clearStorage() {
return localStorage.clear()
}
})();
缺点:需要浏览器和页面一直开启,才会有通知
将JIRA加入固定标签页