月曜日, 6月 16, 2025
- Advertisment -
ホームニューステックニュース【AI agent活用】作業中のSNS断ちを強制する!!ポモドーロタイマー付きChrome拡張機能を作ってみた #JavaScript - Qiita

【AI agent活用】作業中のSNS断ちを強制する!!ポモドーロタイマー付きChrome拡張機能を作ってみた #JavaScript – Qiita



【AI agent活用】作業中のSNS断ちを強制する!!ポモドーロタイマー付きChrome拡張機能を作ってみた #JavaScript - Qiita

作業中についついSNSや動画サイトを開いてしまい、集中力が途切れてしまうことはありませんか?

「今度こそ集中するぞ!」と意気込んでも、気がつくとTwitterやYouTubeを開いてしまい、気づけば数時間経過…なんて経験、きっと多くの方が持っているのではないでしょうか。

そこで今回は、ポモドーロテクニックサイトブロック機能を組み合わせたChrome拡張機能を開発してみました。この記事では、

  • Chrome拡張機能の開発のススメ
  • AI agent(Codex)の活用方法

も含めて、Chrome拡張機能の作り方を詳しく解説していきます!

6/15日現在は、この拡張機能のリリースを申請中です。
ローカルでの使用方法を以下に記載してあります。

📱 完成した拡張機能の機能

まずは、今回作成した拡張機能の主な機能をご紹介します:

  • 25分間のポモドーロタイマー
  • タイマー実行中の集中力を妨げるサイトの自動ブロック
  • アイコン上に残り時間を表示
  • ブロック中のカスタムページ表示
  • タイマー完了時の通知表示

デモ動画

chrome-test.gif

↑画質が荒いのですが、お許しください

🎯 なぜこの拡張機能を作ったのか

私自身、研究や仕事において在宅ワークが増える中で集中力の維持に課題を感じていました。特に:

  1. 意志力に頼る限界: 「見ないようにしよう」と思っても、つい開いてしまう
  2. 既存ツールの不満: 市販のサイトブロッカーは設定が複雑で使いづらい
  3. ポモドーロテクニックとの組み合わせ: 25分という区切りでブロックしたい

これらの課題を解決するため、シンプルで使いやすい拡張機能を自作することにしました。

🤖 AI agentを活用した開発プロセス

今回の開発では、CodexというChatGPT内で動作するAI開発エージェントを積極的に活用しました。AIツールを使うことで、開発効率が大幅に向上したので、その過程もご紹介します。

AIとの対話例

: 「ポモドーロタイマー付きのサイトブロッカーChrome拡張機能を作りたいです。Manifest V3で、25分間特定のサイトをブロックする機能を実装したいのですが、どのような構成にすべきでしょうか?」

Codex: 「Manifest V3でのサイトブロック機能でしたら、declarativeNetRequestを使用するのが最適です。以下のような構成をお勧めします…」

このように、AIと対話しながら設計を固めていきました。特に以下の点でAIが有効でした:

  1. 技術選択の相談: 使用パッケージの最新仕様に関するアドバイス
  2. コード生成: 基本的な構造の雛形作成
  3. デバッグ支援: エラーの原因特定と解決策の提案
  4. ベストプラクティスの確認: セキュリティやパフォーマンスの観点

🏗️ 拡張機能の構成

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">
    </span>Pomodoro Blocker<span class="nt"/>
    <span class="nt"/>
        <span class="nt">body</span> <span class="p">{</span>
            <span class="nl">width</span><span class="p">:</span> <span class="m">300px</span><span class="p">;</span>
            <span class="nl">height</span><span class="p">:</span> <span class="m">200px</span><span class="p">;</span>
            <span class="nl">font-family</span><span class="p">:</span> <span class="n">Arial</span><span class="p">,</span> <span class="nb">sans-serif</span><span class="p">;</span>
            <span class="nl">text-align</span><span class="p">:</span> <span class="nb">center</span><span class="p">;</span>
            <span class="nl">padding</span><span class="p">:</span> <span class="m">20px</span><span class="p">;</span>
        <span class="p">}</span>
        
        <span class="nc">.timer-display</span> <span class="p">{</span>
            <span class="nl">font-size</span><span class="p">:</span> <span class="m">48px</span><span class="p">;</span>
            <span class="nl">font-weight</span><span class="p">:</span> <span class="nb">bold</span><span class="p">;</span>
            <span class="nl">color</span><span class="p">:</span> <span class="m">#333</span><span class="p">;</span>
            <span class="nl">margin</span><span class="p">:</span> <span class="m">20px</span> <span class="m">0</span><span class="p">;</span>
        <span class="p">}</span>
        
        <span class="nt">button</span> <span class="p">{</span>
            <span class="nl">padding</span><span class="p">:</span> <span class="m">10px</span> <span class="m">20px</span><span class="p">;</span>
            <span class="nl">font-size</span><span class="p">:</span> <span class="m">16px</span><span class="p">;</span>
            <span class="nl">border</span><span class="p">:</span> <span class="nb">none</span><span class="p">;</span>
            <span class="nl">border-radius</span><span class="p">:</span> <span class="m">5px</span><span class="p">;</span>
            <span class="nl">cursor</span><span class="p">:</span> <span class="nb">pointer</span><span class="p">;</span>
        <span class="p">}</span>
        
        <span class="nc">.start-btn</span> <span class="p">{</span>
            <span class="nl">background-color</span><span class="p">:</span> <span class="m">#4CAF50</span><span class="p">;</span>
            <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
        <span class="p">}</span>
        
        <span class="nc">.stop-btn</span> <span class="p">{</span>
            <span class="nl">background-color</span><span class="p">:</span> <span class="m">#f44336</span><span class="p">;</span>
            <span class="nl">color</span><span class="p">:</span> <span class="no">white</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="nt"/>
<span class="nt"/>
<span class="nt"/>
    <span class="nt"><h2/></span>Pomodoro Blocker<span class="nt"/>
    <span class="nt"><p> <span class="na">id=</span><span class="s">"timer-display"</span> <span class="na">class=</span><span class="s">"timer-display"</span><span class="nt">></span>25:00<span class="nt"/></p></span>
    
    <span class="nt"><p> <span class="na">class=</span><span class="s">"controls"</span><span class="nt">></span>
        <span class="nt"><button> <span class="na">id=</span><span class="s">"start-btn"</span> <span class="na">class=</span><span class="s">"start-btn"</span><span class="nt">></span>開始<span class="nt"/></button></span>
        <span class="nt"><button> <span class="na">id=</span><span class="s">"stop-btn"</span> <span class="na">class=</span><span class="s">"stop-btn"</span><span class="nt">></span>停止<span class="nt"/></button></span>
    <span class="nt"/></p></span>
    
    <span class="nt"><script data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore" data-jetpack-boost="ignore"><![CDATA[<span class="na">src=]]></script></span><span class="s">"popup.js"</span><span class="nt">></span>
<span class="nt"/>
<span class="nt"/>
</span></span></span></code></pre>
</div>
</div>
<h3 data-sourcepos="171:1-171:44">
<a href="#step-3-%E3%82%BF%E3%82%A4%E3%83%9E%E3%83%BC%E5%88%B6%E5%BE%A1popupjs"><i class="fa fa-link"/></a>Step 3: タイマー制御(popup.js)</h3>
<p data-sourcepos="173:1-173:64">ポップアップの動作を制御するJavaScriptを実装:</p>
<div class="code-frame" data-lang="javascript" data-sourcepos="175:1-231:3">
<div class="highlight">
<pre><code><span class="kd">class</span> <span class="nc">PomodoroTimer</span> <span class="p">{</span>
    <span class="nf">constructor</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">duration</span> <span class="o">=</span> <span class="mi">25</span> <span class="o">*</span> <span class="mi">60</span><span class="p">;</span> <span class="c1">// 25分(秒単位)</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">timeLeft</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">duration</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">isRunning</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
        
        <span class="k">this</span><span class="p">.</span><span class="nx">timerDisplay</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">timer-display</span><span class="dl">'</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">startBtn</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">start-btn</span><span class="dl">'</span><span class="p">);</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">stopBtn</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">stop-btn</span><span class="dl">'</span><span class="p">);</span>
        
        <span class="k">this</span><span class="p">.</span><span class="nf">initializeEventListeners</span><span class="p">();</span>
        <span class="k">this</span><span class="p">.</span><span class="nf">loadState</span><span class="p">();</span>
    <span class="p">}</span>
    
    <span class="nf">initializeEventListeners</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">startBtn</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="k">this</span><span class="p">.</span><span class="nf">startTimer</span><span class="p">());</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">stopBtn</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="k">this</span><span class="p">.</span><span class="nf">stopTimer</span><span class="p">());</span>
    <span class="p">}</span>
    
    <span class="nf">startTimer</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">isRunning</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">startTime</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">();</span>
        <span class="k">this</span><span class="p">.</span><span class="nf">startCountdown</span><span class="p">();</span>
        
        <span class="c1">// バックグラウンドスクリプトにブロック開始を通知</span>
        <span class="nx">chrome</span><span class="p">.</span><span class="nx">runtime</span><span class="p">.</span><span class="nf">sendMessage</span><span class="p">({</span>
            <span class="na">action</span><span class="p">:</span> <span class="dl">'</span><span class="s1">startBlocking</span><span class="dl">'</span><span class="p">,</span>
            <span class="na">duration</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">timeLeft</span>
        <span class="p">});</span>
    <span class="p">}</span>
    
    <span class="nf">startCountdown</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">intervalId</span> <span class="o">=</span> <span class="nf">setInterval</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
            <span class="kd">const</span> <span class="nx">elapsed</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">floor</span><span class="p">((</span><span class="nb">Date</span><span class="p">.</span><span class="nf">now</span><span class="p">()</span> <span class="o">-</span> <span class="k">this</span><span class="p">.</span><span class="nx">startTime</span><span class="p">)</span> <span class="o">/</span> <span class="mi">1000</span><span class="p">);</span>
            <span class="k">this</span><span class="p">.</span><span class="nx">timeLeft</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">duration</span> <span class="o">-</span> <span class="nx">elapsed</span><span class="p">);</span>
            
            <span class="k">this</span><span class="p">.</span><span class="nf">updateDisplay</span><span class="p">();</span>
            
            <span class="k">if </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">timeLeft</span> <span class="o"> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">this</span><span class="p">.</span><span class="nf">timerComplete</span><span class="p">();</span>
            <span class="p">}</span>
        <span class="p">},</span> <span class="mi">1000</span><span class="p">);</span>
    <span class="p">}</span>
    
    <span class="nf">updateDisplay</span><span class="p">()</span> <span class="p">{</span>
        <span class="kd">const</span> <span class="nx">minutes</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">floor</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">timeLeft</span> <span class="o">/</span> <span class="mi">60</span><span class="p">);</span>
        <span class="kd">const</span> <span class="nx">seconds</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">timeLeft</span> <span class="o">%</span> <span class="mi">60</span><span class="p">;</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">timerDisplay</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> 
            <span class="s2">`</span><span class="p">${</span><span class="nx">minutes</span><span class="p">.</span><span class="nf">toString</span><span class="p">().</span><span class="nf">padStart</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="dl">'</span><span class="s1">0</span><span class="dl">'</span><span class="p">)}</span><span class="s2">:</span><span class="p">${</span><span class="nx">seconds</span><span class="p">.</span><span class="nf">toString</span><span class="p">().</span><span class="nf">padStart</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="dl">'</span><span class="s1">0</span><span class="dl">'</span><span class="p">)}</span><span class="s2">`</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="nb">document</span><span class="p">.</span><span class="nf">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">DOMContentLoaded</span><span class="dl">'</span><span class="p">,</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
    <span class="k">new</span> <span class="nc">PomodoroTimer</span><span class="p">();</span>
<span class="p">});</span>
</span></code></pre>
</div>
</div>
<h3 data-sourcepos="233:1-233:58">
<span id="step-4-サイトブロック機能backgroundjs" class="fragment"/><a href="#step-4-%E3%82%B5%E3%82%A4%E3%83%88%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E6%A9%9F%E8%83%BDbackgroundjs"><i class="fa fa-link"/></a>Step 4: サイトブロック機能(background.js)</h3>
<p data-sourcepos="235:1-235:78">拡張機能のコア機能である、サイトブロック処理を実装:</p>
<div class="code-frame" data-lang="javascript" data-sourcepos="237:1-337:3">
<div class="highlight">
<pre><code><span class="kd">class</span> <span class="nc">PomodoroBlocker</span> <span class="p">{</span>
    <span class="nf">constructor</span><span class="p">()</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">blockedSites</span> <span class="o">=</span> <span class="p">[</span>
            <span class="dl">'</span><span class="s1">facebook.com</span><span class="dl">'</span><span class="p">,</span>
            <span class="dl">'</span><span class="s1">twitter.com</span><span class="dl">'</span><span class="p">,</span>
            <span class="dl">'</span><span class="s1">x.com</span><span class="dl">'</span><span class="p">,</span>
            <span class="dl">'</span><span class="s1">instagram.com</span><span class="dl">'</span><span class="p">,</span>
            <span class="dl">'</span><span class="s1">youtube.com</span><span class="dl">'</span><span class="p">,</span>
            <span class="dl">'</span><span class="s1">netflix.com</span><span class="dl">'</span><span class="p">,</span>
            <span class="dl">'</span><span class="s1">reddit.com</span><span class="dl">'</span>
            <span class="c1">// その他ブロック対象サイト</span>
        <span class="p">];</span>
        
        <span class="k">this</span><span class="p">.</span><span class="nf">initializeEventListeners</span><span class="p">();</span>
    <span class="p">}</span>
    
    <span class="nf">initializeEventListeners</span><span class="p">()</span> <span class="p">{</span>
        <span class="nx">chrome</span><span class="p">.</span><span class="nx">runtime</span><span class="p">.</span><span class="nx">onMessage</span><span class="p">.</span><span class="nf">addListener</span><span class="p">((</span><span class="nx">message</span><span class="p">,</span> <span class="nx">sender</span><span class="p">,</span> <span class="nx">sendResponse</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
            <span class="k">switch </span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">action</span><span class="p">)</span> <span class="p">{</span>
                <span class="k">case</span> <span class="dl">'</span><span class="s1">startBlocking</span><span class="dl">'</span><span class="p">:</span>
                    <span class="k">this</span><span class="p">.</span><span class="nf">startBlocking</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">duration</span><span class="p">);</span>
                    <span class="k">break</span><span class="p">;</span>
                <span class="k">case</span> <span class="dl">'</span><span class="s1">stopBlocking</span><span class="dl">'</span><span class="p">:</span>
                    <span class="k">this</span><span class="p">.</span><span class="nf">stopBlocking</span><span class="p">();</span>
                    <span class="k">break</span><span class="p">;</span>
            <span class="p">}</span>
        <span class="p">});</span>
    <span class="p">}</span>
    
    <span class="k">async</span> <span class="nf">startBlocking</span><span class="p">(</span><span class="nx">duration</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">isBlocking</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
        
        <span class="c1">// declarativeNetRequest用のルールを作成</span>
        <span class="k">this</span><span class="p">.</span><span class="nx">blockingRules</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">blockedSites</span><span class="p">.</span><span class="nf">map</span><span class="p">((</span><span class="nx">site</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=></span> <span class="p">({</span>
            <span class="na">id</span><span class="p">:</span> <span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
            <span class="na">priority</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
            <span class="na">action</span><span class="p">:</span> <span class="p">{</span> 
                <span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">redirect</span><span class="dl">'</span><span class="p">,</span> 
                <span class="na">redirect</span><span class="p">:</span> <span class="p">{</span> 
                    <span class="na">url</span><span class="p">:</span> <span class="dl">'</span><span class="s1">data:text/html;charset=utf-8,</span><span class="dl">'</span> <span class="o">+</span> 
                         <span class="nf">encodeURIComponent</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nf">createBlockPageContent</span><span class="p">(</span><span class="nx">site</span><span class="p">))</span> 
                <span class="p">}</span> 
            <span class="p">},</span>
            <span class="na">condition</span><span class="p">:</span> <span class="p">{</span> 
                <span class="na">urlFilter</span><span class="p">:</span> <span class="s2">`||</span><span class="p">${</span><span class="nx">site</span><span class="p">}</span><span class="s2">^`</span><span class="p">,</span>
                <span class="na">resourceTypes</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">main_frame</span><span class="dl">'</span><span class="p">]</span>
            <span class="p">}</span>
        <span class="p">}));</span>

        <span class="c1">// ブロックルールを適用</span>
        <span class="k">await</span> <span class="nx">chrome</span><span class="p">.</span><span class="nx">declarativeNetRequest</span><span class="p">.</span><span class="nf">updateDynamicRules</span><span class="p">({</span>
            <span class="na">addRules</span><span class="p">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">blockingRules</span>
        <span class="p">});</span>
        
        <span class="c1">// 指定時間後に自動停止</span>
        <span class="nf">setTimeout</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
            <span class="k">this</span><span class="p">.</span><span class="nf">stopBlocking</span><span class="p">();</span>
        <span class="p">},</span> <span class="nx">duration</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">);</span>
    <span class="p">}</span>
    
    <span class="nf">createBlockPageContent</span><span class="p">(</span><span class="nx">blockedSite</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="s2">`



    <meta charset="UTF-8"/>
    <title>サイトがブロックされています
    


    

🍅

ポモドーロタイマーが終了するまでお待ちください。

集中して作業を続けましょう!

`
; } } new PomodoroBlocker();

🔧 開発で工夫したポイント

1. Manifest V3対応

Chrome拡張機能は2024年からManifest V3が必須となりました。従来のwebRequestからdeclarativeNetRequestへの移行が必要で、この部分でAIの助けが特に有効でした。

2. 状態の永続化

ブラウザを閉じてもタイマーが継続するよう、chrome.storage.localを使用して状態を保存しています。

3. リアルタイム表示

拡張機能のアイコンにバッジで残り時間を表示し、ユーザーが常に進捗を確認できるようにしました。

🚀 インストールと使い方

インストール方法

リリースは申請中なので、以下のようにローカルで使用してください。

  1. GitHubからコードをダウンロード
  2. Chrome の chrome://extensions/ にアクセス
  3. 「デベロッパーモード」を有効にする
  4. 「パッケージ化されていない拡張機能を読み込む」をクリック
  5. ダウンロードしたフォルダを選択

使い方

  1. Chrome ツールバーの拡張機能アイコンをクリック
  2. 「開始」ボタンでポモドーロタイマーを開始
  3. 25分間、指定したサイトが自動的にブロックされます
  4. タイマー完了時に通知が表示されます

🎨 あなた専用の拡張機能にカスタマイズ!

ブロック対象サイトの変更

background.jsblockedSites配列を編集することで、ブロック対象を自由に変更できます:

this.blockedSites = [
    'facebook.com',
    'twitter.com',
    'your-favorite-distraction.com'  // 追加
];

タイマー時間の変更

popup.jsduration変数を変更することで、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分間の集中時間を確保できるようになります。ぜひ皆さんも試してみて、必要に応じてカスタマイズしてみてください!

何か質問やご意見がありましたら、コメント欄でお聞かせください。また、機能追加のアイデアなどもお待ちしています!





Source link

Views: 0

RELATED ARTICLES

返事を書く

あなたのコメントを入力してください。
ここにあなたの名前を入力してください

- Advertisment -