
Tampermonkeyでスケジュール通知機能を作ってみた
こんにちは!昨年12月に入社したエンジニアのジョンダビンです。
実は私は、作業に夢中になり、スケジュール登録をしておいた予定を忘れてしまったことがあります。
特に最近は在宅勤務となり、周りに他のメンバーがいないので、更に気付きにくい状態となってしまいました。
そこで今日は自分が使っているスケジュール通知機能について紹介しようと思います。
1. 注意事項
こちらの機能は以下の問題があります。
ChromeからJavascriptへの制限により、Chromeのタブがバックグラウンドにいると、Javascriptが停止し、正常に動かなくなります。
つまり常にスケジュールページを開いたまま、フロントを出してあげないと正常に動きません。
解決方法は未だ思いつかないですが、多分Chromeの拡張機能でできそうな気がします。ですが、そもそもそれが面倒でこちらで作ったため、微妙なところです。。。
もし解決方法が見つかったらまた更新します。
2. Tampermonkeyについて
まずTampermonkeyについて簡単に紹介します。
Tampermonkeyは、ブラウザー拡張機能として利用可能な寄付ウェアのユーザースクリプトマネージャーです。このソフトウェアを使用すると、ユーザーはユーザースクリプトを追加して使用できます。ユーザースクリプトは、Webページの変更に使用できるJavaScriptプログラムです。
その場でJavaScriptを書いて更新すればすぐ実行できるので、結構便利で昔から使っていました。
chrome ウェブストアでインストールできます。
3. 通知機能作成
基本説明
それでは実際に作ってみましょう!
新規スクリプトを追加するとまず以下のページが開かれます。

上の部分はスクリプトの設定部分です。こちらのmatchは、自分がこのスクリプトを実行したいウェブサイトのurlを設定するところです。他の項目はそのままの意味なので説明は省略します。
そして自分が実行したい部分のcodeを下の部分に書けば、マッチしたウェブサイトで自動的にcodeの実行します。
4. 機能実装
やりたいことはすごく単純で簡単です。
5分ごとに処理を実行し、スケジュールで次の予定時間が近づいたら、windowsの通知機能で通知を送る。

構造的にはすごく簡単なので、このままdocument.getElementsByClassNameでデータを絞り、時間を計算すれば問題なさそうです。
そして最後に「var notification = new Notification(“通知”);」これで通知を行えば終わりです。
イメージとしてはこんな感じです。
最後に自分のコードを貼っておきます。適当に書いたので、あまり参考にはならないと思いますが、一応問題なく動きます。
<pre class="prism line-numbers language-js"><code class=" language-js"><span class="token comment">// ==UserScript==</span>
<span class="token comment">// @name スケジュール通知</span>
<span class="token comment">// @namespace http://tampermonkey.net/</span>
<span class="token comment">// @version 0.1</span>
<span class="token comment">// @description スケジュール通知</span>
<span class="token comment">// @auhtor You</span>
<span class="token comment">// @match http://example.com</span>
<span class="token comment">// @grant none</span>
<span class="token comment">// ==/UserScript==</span>
<span class="token punctuation">(</span><span class="token keyword def">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token keyword def">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">//通知権限請求</span>
Notification<span class="token punctuation">.</span><span class="token function">requestPermission</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//今日のスケジュールリスト</span>
<span class="token keyword">var</span> schedules <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span><span class="token string">'hoge'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span><span class="token string">'hogehoge'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> schedules<span class="token punctuation">.</span>length<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token function">RunNotification</span><span class="token punctuation">(</span>schedules<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">300000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//実施間隔 5分に一回実行</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword def">function</span> <span class="token function">RunNotification</span><span class="token punctuation">(</span>schedule<span class="token punctuation">)</span><span class="token punctuation">{</span>
<span class="token keyword">var</span> nowTime <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> year <span class="token operator">=</span> nowTime<span class="token punctuation">.</span><span class="token function">getFullYear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> month <span class="token operator">=</span> nowTime<span class="token punctuation">.</span><span class="token function">getMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token comment">//getDateはそのまま日数が取得できるがなぜか月は0から始まる謎仕様、、</span>
<span class="token keyword">var</span> day <span class="token operator">=</span> nowTime<span class="token punctuation">.</span><span class="token function">getDate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> startTime <span class="token operator">=</span> schedule<span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span><span class="token string">'hoge'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>textContent<span class="token punctuation">.</span><span class="token function">substring</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> fullStartTime <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span>year<span class="token operator">+</span><span class="token string">'-'</span><span class="token operator">+</span>month<span class="token operator">+</span><span class="token string">'-'</span><span class="token operator">+</span>day<span class="token operator">+</span><span class="token string">' '</span><span class="token operator">+</span>startTime<span class="token operator">+</span><span class="token string">':00'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> remainTime <span class="token operator">=</span> <span class="token punctuation">(</span>fullStartTime<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> nowTime<span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token operator">/</span><span class="token number">60000</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>remainTime <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> remainTime <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
<span class="token keyword">var</span> title <span class="token operator">=</span> schedule<span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span><span class="token string">'hoge'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>textContent<span class="token punctuation">;</span>
<span class="token comment">// 通知処理</span>
<span class="token keyword">var</span> notification <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Notification</span><span class="token punctuation">(</span>title<span class="token operator">+</span><span class="token string">' 開始'</span><span class="token operator">+</span>remainTime<span class="token operator">+</span><span class="token string">'分前'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
5. まとめ
実はすでにスケジュール通知機能を他の方法で実現した文章が上がっていましたが、見た感じ色々と面倒だったので、こちらの方法で試してみました。
結果としてはスケジュールページをずっと出してあげないと止まっちゃうので、微妙な感じになりましたが、、
また時間があれば解決方法を探してまた更新しておきます。