今回はchrome拡張を使って、kintoneの通知をデスクトップ通知するサンプルを紹介します。 「kintoneのメール通知を設定して、メールをデスクトップ通知すればよいのでは?」とは言わずに温かい目でお願いいたします。
サンプル
定期的に、kintoneの通知をデスクトップ通知します。
コード
chrome拡張を利用します。 読み込み方法は下記などを参考にしてください。
https://qiita.com/querykuma/items/b41cd108e5df25ebbfda#chrome-で動かす
〇ファイル構成
下記を全て同じ階層に置きます。
・manifest.json
・content-login.js
・content-ntf.js
・event.js
・options.html
・options.js
・notification.svg
・manifest.json
{
"name": "kintone desktop notification",
"version": "1.0.0",
"manifest_version": 2,
"description": "Desktop notification of kintone notification.",
"background": {
"scripts": ["event.js"],
"persistent": false
},
"content_scripts": [{
"matches": ["https://*.cybozu.com/login*"],
"js": ["content-login.js"]
}, {
"matches": ["https://*.cybozu.com/k*"],
"include_globs": ["*#/ntf/all*"],
"js": ["content-ntf.js"]
}],
"options_page": "options.html",
"permissions": [
"notifications",
"alarms",
"tabs",
"storage"
]
}
・content-login.js
kintoneに自動ログインするためのスクリプトです。 kintoneのログインページで動作します。
new MutationObserver(event => {
if(event[0].target.style.display === 'none') return;
chrome.runtime.sendMessage('login-error');
}).observe(document.getElementsByClassName('login-error-message')[0], {attributes: true});
chrome.storage.local.get(null, options => {
if(`${options.subdomain}.cybozu.com` !== location.host) return;
if(!options.user || !options.password) return;
document.getElementById("username-:0-text").value = options.user;
document.getElementById("password-:1-text").value = options.password;
document.getElementsByClassName('login-button')[0].click();
});
・content-ntf.js
通知情報を取得するスクリプトです。 kintoneの通知ページで動作します。
chrome.storage.local.get(null, options => {
if(`${options.subdomain}.cybozu.com` !== location.host) return;
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
sendResponse([].map.call(document.getElementsByClassName('ocean-ntf-ntflist-content')[0].childNodes, item => ({
subject: item.getElementsByClassName('ocean-ntf-ntfitem-subject')[0].innerText,
space: item.getElementsByClassName('ocean-ntf-ntfitem-space')[0].innerText,
detail: item.getElementsByClassName('ocean-ntf-ntfitem-detail')[0].innerText,
date: item.getElementsByClassName('ocean-ntf-ntfitem-date')[0].innerText,
user: item.getElementsByClassName('ocean-ntf-ntfitem-user')[0].innerText,
})));
});
});
・event.js
定期的にkintoneの通知の確認、デスクトップ通知を行うスクリプトです。
{
const icon = 'notification.svg';
let url;
let createAlarm;
const initialize = () => {
chrome.storage.local.get(null, options => {
if(!options.subdomain || !options.frequency) return;
url = `https://${options.subdomain}.cybozu.com/k/#/ntf/all`;
createAlarm = () => {
chrome.alarms.create('', {
when: Date.now() + (options.frequency * 1000)
});
};
createAlarm();
});
};
chrome.notifications.onClicked.addListener(() => {
chrome.tabs.create({
url: url,
});
});
chrome.runtime.onMessage.addListener(message => {
if(message !== 'login-error') return;
chrome.notifications.create('', {
type: 'basic',
iconUrl: icon,
title: 'kintone notification',
message: 'Incorrect login name or password.'
});
chrome.alarms.clearAll();
chrome.runtime.openOptionsPage();
});
chrome.alarms.onAlarm.addListener(() => {
chrome.tabs.create({
url: url,
active: false
}, tab => {
new Promise(resolve => {
let timer = setInterval(() =>{
chrome.tabs.get(tab.id, tab => {
if(chrome.runtime.lastError){
console.log(chrome.runtime.lastError.message);
clearInterval(timer);
return;
}
if(tab.status === 'complete' && (tab.url === url || tab.pendingUrl === url)){
clearInterval(timer);
resolve();
}
});
}, 1000);
}).then(() => {
chrome.tabs.sendMessage(tab.id, {}, response => {
if(chrome.runtime.lastError){
console.log(chrome.runtime.lastError.message);
return;
}
if(response.length){
chrome.notifications.create('', {
type: 'list',
iconUrl: icon,
title: 'kintone notification',
message: '',
items: response.map(item => ({
title: item.space,
message: item.detail,
})),
});
}
chrome.tabs.remove(tab.id);
});
});
});
createAlarm();
});
chrome.storage.onChanged.addListener(initialize);
initialize();
chrome.runtime.onInstalled.addListener(chrome.runtime.openOptionsPage());
}
・options.html
オプション画面です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>kintone desktop notification | options</title>
</head>
<body>
<h1>kintone desktop notification | options</h1>
<div>subdomain: <input type="text" id="subdomain"></div>
<div>frequency: <input type="number" id="frequency"> sec</div>
<div>user: <input type="text" id="user"></div>
<div>password: <input type="password" id="password"></div>
<div><button id="save">save</button></div>
<script src="options.js"></script>
</body>
</html>
・options.js
オプション画面で動作するスクリプトです。
document.addEventListener("DOMContentLoaded", () => {
chrome.storage.local.get(null, options => {
document.getElementById('subdomain').value = options.subdomain || '';
document.getElementById('frequency').value = options.frequency || '';
document.getElementById('user').value = options.user || '';
document.getElementById('password').value = options.password || '';
});
});
document.getElementById('save').addEventListener('click', () => {
chrome.storage.local.set({
subdomain: document.getElementById('subdomain').value,
frequency: document.getElementById('frequency').value,
user: document.getElementById('user').value,
password: document.getElementById('password').value,
}, () => {
alert('saved');
});
});
・notification.svg
デスクトップ通知のアイコンです。 デモでは、こちらのサイトの画像を利用しました。
<!--?xml version="1.0" encoding="utf-8"?-->
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="_x32_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="width: 256px; height: 256px; opacity: 1;" xml:space="preserve">
<style type="text/css">
.st0{fill:#4B4B4B;}
</style>
<g>
<path class="st0" d="M481.551,383.102c-2.204-43.823-19.916-63.781-35.542-81.385c-14.808-16.669-30.116-33.906-39.582-80.383
c-15.159-74.382-44.741-126.043-86.277-151.151c0.168-1.92,0.268-3.84,0.268-5.759c0-8.731-1.72-17.179-5.109-25.142
c-4.841-11.461-12.904-21.236-23.272-28.247C281.402,3.815,268.931,0,255.994,0c-8.715,0-17.179,1.719-25.125,5.092
c-11.502,4.875-21.285,12.938-28.28,23.305c-7.178,10.568-11.002,23.056-11.002,36.027c0,1.928,0.067,3.856,0.234,5.768
c-41.52,25.117-71.119,76.761-86.26,151.143c-9.466,46.477-24.775,63.714-39.583,80.383
c-15.626,17.604-33.339,37.562-35.525,81.385c-0.418,8.08,1.419,20.134,12.403,31.677c10.451,10.994,33.055,26.812,108.196,37.304
c7.964,1.102,16.093,2.086,24.224,2.955c5.526,15.543,15.375,28.998,28.13,38.923c14.491,11.294,32.822,18.046,52.588,18.039
c19.782,0.008,38.096-6.745,52.587-18.039c12.737-9.924,22.604-23.38,28.13-38.923c8.13-0.868,16.277-1.853,24.241-2.955
c75.141-10.492,97.729-26.31,108.179-37.304C480.116,403.236,481.952,391.182,481.551,383.102z M130.569,226.426
c13.539-66.452,41.336-124.774,91.77-142.604c-0.785-1.386-1.553-2.788-2.188-4.265c-1.97-4.65-3.055-9.808-3.055-15.133
c0-8.03,2.454-15.585,6.644-21.761c4.207-6.202,10.117-11.127,17.112-14.082c4.657-1.986,9.8-3.072,15.142-3.072
c8.014,0,15.559,2.455,21.753,6.661c6.21,4.199,11.118,10.109,14.074,17.104c1.986,4.65,3.072,9.817,3.072,15.15
c0,7.012-1.887,13.689-5.192,19.407c50.418,17.855,78.197,76.168,91.719,142.595c15.008,73.672,45.058,85.675,62.17,113.355
c-55.976,15.993-119.815,25.1-187.594,25.1c-67.779,0-131.602-9.106-187.595-25.1C85.511,312.101,115.561,300.098,130.569,226.426z
M292.905,473.828c-10.217,7.939-22.954,12.646-36.911,12.655c-13.956-0.009-26.694-4.716-36.912-12.655
c-5.71-4.449-10.567-9.941-14.373-16.151c20.234,1.51,38.58,2.22,51.285,2.22c12.704,0,31.052-0.71,51.285-2.22
C303.489,463.887,298.631,469.379,292.905,473.828z M255.994,434.388c-44.007,0-202.052-10.017-200.066-50.008
c0.735-14.541,3.356-25.45,7.228-34.466l-2.971,10.284c58.614,16.978,125.192,26.552,195.808,26.552
c70.617,0,137.178-9.574,195.825-26.552l-2.988-10.284c3.873,9.015,6.494,19.924,7.229,34.466
C458.063,424.371,300,434.388,255.994,434.388z" style="fill: rgb(58, 171, 210);"></path>
<path class="st0" d="M261.636,78.355c0.968-0.392,1.904-0.851,2.788-1.428c2.404-1.62,4.34-3.965,5.46-6.645
c0.768-1.803,1.184-3.756,1.184-5.859c0-3.164-0.934-6.01-2.57-8.43c-1.62-2.404-3.957-4.333-6.645-5.468
c-1.803-0.776-3.74-1.186-5.86-1.186c-3.172,0-5.993,0.944-8.414,2.563c-2.421,1.636-4.358,3.965-5.476,6.645
c-0.768,1.802-1.186,3.756-1.186,5.876c0,3.155,0.935,5.994,2.571,8.414c1.619,2.404,3.957,4.34,6.644,5.476l0.133,0.042
c1.904-0.101,3.79-0.168,5.727-0.168C257.914,78.188,259.783,78.254,261.636,78.355z" style="fill: rgb(58, 171, 210);"></path>
</g>
</svg>
設定
オプション画面で、「サブドメイン」、「デスクトップ通知の頻度」、「kintoneのログインユーザー名」、「kintoneのログインパスワード」を設定します。 オプション画面は、拡張機能のオプションから開くことができます。 また、拡張機能のインストール時に自動で開きます。
注意書き
・chromeの動作中にのみ、本プログラムは動作します。
・ブラウザのデスクトップ通知が許可されていない場合は動作しません。
・kintoneの通知を取得する際、ブラウザのタブを開いたり閉じたりします。
・Basic認証には対応しておりません。設定している場合は、予め手動でログインする必要があります。
・kintoneの仕様変更により、正しく動作しなくなる可能性があります。
0件のコメント