リマインダーをエレクトロンでアプリ化し日々の予定をOS側から通知させる
| 2025/08/31
エレクトロンでWEB技術を活かしたイカしたアプリ開発
- カレンダーを作るはいいが、通知が来ないと忘れてしまう
WEBでいろいろなことができるようになっても、WEBはブラウザで完結。もどかしく思うことが結構あります。
たとえばカレンダーを作り予定を設定しても、その予定日に「予定があるよ」と教えてくれないと、気づかずに忘れてしまう。
こういう不満を解決してくれるのがJSベースのエレクトロン。
- エレクトロンの簡単な説明
HTML、CSS、JavaScriptで開発できるのでこれまで培ったWEB技術をそのまま生かせる。
エレクトロンでビルドしたアプリはOSへインストールでき、アプリとして使用できるので、サウンドでの通知とかいろいろ便利に生活へ応用できる。つまり新しい世界が広がるよ。
シンプルで簡単操作のカレンダーがない
- なかなか満足できるカレンダーがない
発端はシンプルで手軽に扱えるカレンダーアプリがないこと。いろいろカレンダーアプリはあるがメールとかチャットとかいろいろ他の機能と一緒になっていたり操作が面倒だったり、ホントに予定を組むだけのシンプルなカレンダーがない。
そこでWEBアプリとして作ってしまおうと発起。
- カレンダー機能だけで十分のはずが
最初からリマインダーなんて考えてない。いつも目に入るところにカレンダーがあって、ちゃっちゃと予定を記述でき予定を忘れなければOK。
・・・・・ところが、予定を入れてもそれだじゃあ、だめだったんです。
その時刻前に何かしら通知とかないと、忘れてしまう!
歯医者にいくの忘れました・・・。通知の必要性を実感しました・・・・。
そこでカレンダーだけで十分のはずが、リマインダー開発という長い苦しい道のりを歩むことに・・・・・。
HTMLで基本のカレンダーを作成
- まずはシンプルなカレンダーを開発
カレンダーは単純に30日分のマスを並べればいいわけではありません。
月ごとに「31日」「30日」「28日」など日数が違い、さらに「1日が何曜日から始まるか」もバラバラ。
これを処理するために、まず以下のコードを書きます。
let current = new Date();
const year = current.getFullYear();
const month = current.getMonth();
const firstDay = new Date(year, month, 1).getDay();
ここで
year → その年(例: 2025)
month → その月(0始まりで1月は0)
firstDay → その月1日の曜日(0=日曜, 1=月曜 … 6=土曜)
を取得できます。
これを使うと「9月は月曜から始まるから、カレンダーの最初に空白が1つ必要だな」といった処理が可能になります。
もしこれをやらずに日付を単純に並べてしまうと、毎月「日付と曜日がズレたカレンダー」になってしまうのです。
つまり、この数行は「カレンダーをちゃんとカレンダーらしく見せるための基礎工事」といえます。
const calendar = document.getElementById("calendar");
calendar.innerHTML = "";
const year = current.getFullYear();
const month = current.getMonth();
document.getElementById("monthYear").textContent = `${year}年 ${month+1}月`;
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
//その月の1日が始まるまで空のセルを埋める
for (let i = 0; i < firstDay; i++) {
const empty = document.createElement("div");
calendar.appendChild(empty);
}
for (let d = 1; d <= daysInMonth; d++) {
const day = document.createElement("div");
const dateStr = `${year}-${month+1}-${d}`;
day.className = "day";
day.textContent = d;
calendar.appendChild(day);
}
}
- 簡易的にlocalStorageへ保存する
現状、せっかく予定を入れても、ブラウザを閉じると消えてしまいます。
そのためlocalStorageを使い簡易的にデータを保存します。
保存するフォーマットはオブジェクトリテラルで日付をキーにしてJSONファイルにします。
下記はそのサンプル
{
"2025-09-01": {
"title": "歯医者",
"body": "15時の予約"
}
}
- localStorageでデータをやり取りする時の決まり事
localStorageへ実際に保存されるときは「文字列オンリー」なので、オブジェクトを入れるときは必ず JSON.stringify が必要になります。
取り出すときは逆に JSON.parse でオブジェクトに戻す必要があります。
まあ、localStorageへの読み込みと書きこみ用のコードはほぼ呪文と同じなので数学の公式のように覚えておけばOKです。
//jsonファイルの読み込み
const raw = localStorage.getItem("desktop_callendar");
return raw ? JSON.parse(raw) : {};
//jsonファイルのlocalStorageへの保存
localStorage.setItem("desktop_callendar", JSON.stringify(allNotes));
簡易的にlocalStorageへ保存する:https://labo.studio-happyvalley.com/calendar_1st/localStorage/
- 祝日を設定する
カレンダーといえば祝日。祝日を設定します。
考え方は祝日をオブジェクトにしてカレンダーの玉をレンダリング中にチェックしてもしも祝日だった場合は
祝日名と祝日用のクラスを追加します。
localStorageに予定情報を保存する:https://labo.studio-happyvalley.com/calendar_1st/localStoragePlus/
予定データを消えないようにPHPで保存する
- まずはJSONファイルに予定書き込み、専用フォルダへ保存
これまでlocalStorageへデータを保存してきましたが、何かの拍子にブラウザのストレージが空になることって結構あります。
いつブラウザに不具合が発生するか心配するのでは実用になりません。
そこでサーバー側にデータを保存します。これならブラウザに何かあっても予定は残り、またほかのブラウザでアクセスしても同じ予定を共有できます。
仕様は、JavaScriptで予定をJSONファイルに整形しそのデータをPHPへ送信、その後PHP側でファイルやデータベースに保存します。
データの保存ファイル名ですが、今回は自分専用のリマインダーなので、個人のアカウントを保存用のファイル名に設定しています。
最初に起動した時、カレンダー用のIDを求めるモーダルウインドウが開きます。
そこへ入力する任意のアカウント|IDがその人専用のファイル名ということになります。
まあ、アカウントとパスワードを兼ねた仕様になります。
初めてであれば新たにファイルを作成し、すでに作って有ればそのファイルを読み込む仕様です。
//JavaScriptから送信
fetch("save.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
date: "2025-09-01",
title: "歯医者",
memo: "15時に予約"
})
});
//PHP側(save.php)
<?php
$data = json_decode(file_get_contents("php://input"), true);
// 簡単にファイル保存する例
$file = 'schedule.json';
$current = file_exists($file) ? json_decode(file_get_contents($file), true) : [];
$current[] = $data;
file_put_contents($file, json_encode($current, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
?>
これで、予定を書き込むたびに schedule.json に追記され、ページをリロードしてもデータが残ります。
今回は自分専用なのでファイル保存でも十分。
後で本格的に配布やらグループで共有などするならSQLiteやMySQLに移行すると管理しやすいです。
ただし今回はエレクトロン用なので、データベースは別の機会で解説します。
PHPを使ってサーバーへ保存:https://labo.studio-happyvalley.com/calendar_1st/complete/