作業中についついSNSや動画サイトを開いてしまい、集中力が途切れてしまうことはありませんか?
「今度こそ集中するぞ!」と意気込んでも、気がつくとTwitterやYouTubeを開いてしまい、気づけば数時間経過…なんて経験、きっと多くの方が持っているのではないでしょうか。
そこで今回は、ポモドーロテクニックとサイトブロック機能を組み合わせたChrome拡張機能を開発してみました。この記事では、
- Chrome拡張機能の開発のススメ
- AI agent(Codex)の活用方法
も含めて、Chrome拡張機能の作り方を詳しく解説していきます!
6/15日現在は、この拡張機能のリリースを申請中です。
ローカルでの使用方法を以下に記載してあります。
📱 完成した拡張機能の機能
まずは、今回作成した拡張機能の主な機能をご紹介します:
- 25分間のポモドーロタイマー
- タイマー実行中の集中力を妨げるサイトの自動ブロック
- アイコン上に残り時間を表示
- ブロック中のカスタムページ表示
- タイマー完了時の通知表示
デモ動画
↑画質が荒いのですが、お許しください
🎯 なぜこの拡張機能を作ったのか
私自身、研究や仕事において在宅ワークが増える中で集中力の維持に課題を感じていました。特に:
- 意志力に頼る限界: 「見ないようにしよう」と思っても、つい開いてしまう
- 既存ツールの不満: 市販のサイトブロッカーは設定が複雑で使いづらい
- ポモドーロテクニックとの組み合わせ: 25分という区切りでブロックしたい
これらの課題を解決するため、シンプルで使いやすい拡張機能を自作することにしました。
🤖 AI agentを活用した開発プロセス
今回の開発では、CodexというChatGPT内で動作するAI開発エージェントを積極的に活用しました。AIツールを使うことで、開発効率が大幅に向上したので、その過程もご紹介します。
AIとの対話例
私: 「ポモドーロタイマー付きのサイトブロッカーChrome拡張機能を作りたいです。Manifest V3で、25分間特定のサイトをブロックする機能を実装したいのですが、どのような構成にすべきでしょうか?」
Codex: 「Manifest V3でのサイトブロック機能でしたら、declarativeNetRequestを使用するのが最適です。以下のような構成をお勧めします…」
このように、AIと対話しながら設計を固めていきました。特に以下の点でAIが有効でした:
- 技術選択の相談: 使用パッケージの最新仕様に関するアドバイス
- コード生成: 基本的な構造の雛形作成
- デバッグ支援: エラーの原因特定と解決策の提案
- ベストプラクティスの確認: セキュリティやパフォーマンスの観点
🏗️ 拡張機能の構成
Chrome拡張機能は以下のファイルで構成されています:
pomodoro-blocker-extension/
├── manifest.json # 拡張機能の設定ファイル
├── popup.html # ポップアップUI
├── popup.js # タイマー制御ロジック
├── background.js # サイトブロック制御
└── icons/ # アイコンファイル
└── icon.png
📝 開発ステップバイステップ
Step 1: manifest.jsonの設定
Chrome拡張機能の心臓部となるmanifest.json
から始めます:
{
"manifest_version": 3,
"name": "Pomodoro Blocker",
"version": "1.0",
"description": "25分間タイマー+特定サイトを集中のためブロックする拡張機能",
"permissions": [
"activeTab",
"storage",
"declarativeNetRequest",
"notifications"
],
"host_permissions": [
"*://facebook.com/*",
"*://twitter.com/*",
"*://youtube.com/*"
// その他ブロック対象サイト
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html"
}
}
ポイント:
-
manifest_version: 3
で最新版を使用 -
declarativeNetRequest
でサイトブロック機能を実装 -
storage
でタイマー状態を永続化
Step 2: ポップアップUI(popup.html)
ユーザーがクリックする拡張機能のポップアップを作成:
lang="ja">
charset="UTF-8">
Pomodoro Blocker
body {
width: 300px;
height: 200px;
font-family: Arial, sans-serif;
text-align: center;
padding: 20px;
}
.timer-display {
font-size: 48px;
font-weight: bold;
color: #333;
margin: 20px 0;
}
button {
padding: 10px 20px;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
}
.start-btn {
background-color: #4CAF50;
color: white;
}
.stop-btn {
background-color: #f44336;
color: white;
}
Pomodoro Blocker
id="timer-display" class="timer-display">25:00
class="controls">
"popup.js">
Step 3: タイマー制御(popup.js)
ポップアップの動作を制御するJavaScriptを実装:
class PomodoroTimer {
constructor() {
this.duration = 25 * 60; // 25分(秒単位)
this.timeLeft = this.duration;
this.isRunning = false;
this.timerDisplay = document.getElementById('timer-display');
this.startBtn = document.getElementById('start-btn');
this.stopBtn = document.getElementById('stop-btn');
this.initializeEventListeners();
this.loadState();
}
initializeEventListeners() {
this.startBtn.addEventListener('click', () => this.startTimer());
this.stopBtn.addEventListener('click', () => this.stopTimer());
}
startTimer() {
this.isRunning = true;
this.startTime = Date.now();
this.startCountdown();
// バックグラウンドスクリプトにブロック開始を通知
chrome.runtime.sendMessage({
action: 'startBlocking',
duration: this.timeLeft
});
}
startCountdown() {
this.intervalId = setInterval(() => {
const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
this.timeLeft = Math.max(0, this.duration - elapsed);
this.updateDisplay();
if (this.timeLeft 0) {
this.timerComplete();
}
}, 1000);
}
updateDisplay() {
const minutes = Math.floor(this.timeLeft / 60);
const seconds = this.timeLeft % 60;
this.timerDisplay.textContent =
`${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}
}
document.addEventListener('DOMContentLoaded', () => {
new PomodoroTimer();
});
Step 4: サイトブロック機能(background.js)
拡張機能のコア機能である、サイトブロック処理を実装:
class PomodoroBlocker {
constructor() {
this.blockedSites = [
'facebook.com',
'twitter.com',
'x.com',
'instagram.com',
'youtube.com',
'netflix.com',
'reddit.com'
// その他ブロック対象サイト
];
this.initializeEventListeners();
}
initializeEventListeners() {
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.action) {
case 'startBlocking':
this.startBlocking(message.duration);
break;
case 'stopBlocking':
this.stopBlocking();
break;
}
});
}
async startBlocking(duration) {
this.isBlocking = true;
// declarativeNetRequest用のルールを作成
this.blockingRules = this.blockedSites.map((site, index) => ({
id: index + 1,
priority: 1,
action: {
type: 'redirect',
redirect: {
url: 'data:text/html;charset=utf-8,' +
encodeURIComponent(this.createBlockPageContent(site))
}
},
condition: {
urlFilter: `||${site}^`,
resourceTypes: ['main_frame']
}
}));
// ブロックルールを適用
await chrome.declarativeNetRequest.updateDynamicRules({
addRules: this.blockingRules
});
// 指定時間後に自動停止
setTimeout(() => {
this.stopBlocking();
}, duration * 1000);
}
createBlockPageContent(blockedSite) {
return `
サイトがブロックされています
🍅
ポモドーロタイマーが終了するまでお待ちください。
集中して作業を続けましょう!
`;
}
}
new PomodoroBlocker();
🔧 開発で工夫したポイント
1. Manifest V3対応
Chrome拡張機能は2024年からManifest V3が必須となりました。従来のwebRequestからdeclarativeNetRequestへの移行が必要で、この部分でAIの助けが特に有効でした。
2. 状態の永続化
ブラウザを閉じてもタイマーが継続するよう、chrome.storage.localを使用して状態を保存しています。
3. リアルタイム表示
拡張機能のアイコンにバッジで残り時間を表示し、ユーザーが常に進捗を確認できるようにしました。
🚀 インストールと使い方
インストール方法
リリースは申請中なので、以下のようにローカルで使用してください。
- GitHubからコードをダウンロード
- Chrome の
chrome://extensions/
にアクセス - 「デベロッパーモード」を有効にする
- 「パッケージ化されていない拡張機能を読み込む」をクリック
- ダウンロードしたフォルダを選択
使い方
- Chrome ツールバーの拡張機能アイコンをクリック
- 「開始」ボタンでポモドーロタイマーを開始
- 25分間、指定したサイトが自動的にブロックされます
- タイマー完了時に通知が表示されます
🎨 あなた専用の拡張機能にカスタマイズ!
ブロック対象サイトの変更
background.js
のblockedSites
配列を編集することで、ブロック対象を自由に変更できます:
this.blockedSites = [
'facebook.com',
'twitter.com',
'your-favorite-distraction.com' // 追加
];
タイマー時間の変更
popup.js
のduration
変数を変更することで、25分以外の時間に設定可能です:
this.duration = 45 * 60; // 45分に変更
💡 AIツール活用のコツ
今回の開発を通じて学んだ、AIツールを効果的に活用するコツをまとめます:
1. 具体的な質問をする
❌ 悪い例: 「Chrome拡張機能を作りたい」
✅ 良い例: 「Manifest V3でサイトブロック機能を持つChrome拡張機能を作りたい。declarativeNetRequestを使用して、特定のドメインにアクセスした際にカスタムページにリダイレクトする方法を教えて」
2. エラーメッセージを共有する
エラーが発生した際は、エラーメッセージ全体をAIに共有することで、的確な解決策を得られます。
3. 段階的に開発する
すべてを一度に実装しようとせず、機能ごとに分けてAIに相談することで、より良いコードが得られます。
🔮 今後の改善案
現在の拡張機能をさらに発展させるアイデア:
- 統計機能: 1日の集中時間や達成回数の記録
- カスタムタイマー: 5分、15分、30分など複数の時間設定
- ホワイトリスト機能: 仕事で必要なサイトの除外設定
- 同期機能: 複数デバイス間での設定共有
- 集中度分析: ブロックを試みた回数の分析
📚 参考リソース
Qita記事
Document集
まとめ
今回は、ポモドーロテクニックとサイトブロック機能を組み合わせたChrome拡張機能を開発しました。AIツールを活用することで、効率的に開発を進めることができ、特に最新のパッケージ仕様への対応において大きな助けとなりました。
この拡張機能を使うことで、作業中の誘惑を物理的に断ち切り、25分間の集中時間を確保できるようになります。ぜひ皆さんも試してみて、必要に応じてカスタマイズしてみてください!
何か質問やご意見がありましたら、コメント欄でお聞かせください。また、機能追加のアイデアなどもお待ちしています!
Views: 0