集中力を上げるchrome拡張機能をChatGPTで爆速で作った

## まえがき
詐欺タイトルですみません。
XやYoutubeなど集中力が妨げられるサイトを指定して閲覧できないようブロックする拡張機能をChatGPTで作成したという話です。

以前は「BlockSite」という拡張機能で、ついつい見てしまうサイトをブロックしていたのですが、4サイト以上は有料だったため自分で作成しました。
こちらの全プログラムと記事はすべてChatGPTに書いてもらい、僕はコピペしただけで
思いつきから完成まで2時間程です。
エンジニアの仕事がAIに置き換わるというのが実感できた今日この頃です。


## 1. はじめに

書籍『やばい集中力』では、インターネットでの無駄な閲覧が集中力を大きく奪うという内容がありました。  
気になってしまうサイトにアクセスすると、ブロックページが表示されるChrome拡張機能を自作することにしました。  
これにより、気が散りがちなサイトへのアクセスを抑制し、より生産的な作業環境を実現できると考えています。

## 2. ディレクトリ構成

拡張機能は以下のようなディレクトリ構成で作成しました。

```
block-sites/ 
├── background.js // バックグラウンド（Service Worker）スクリプト 
├── block.html // ブロック表示用ページ 
├── style.css // ブロックページのスタイルシート 
├── manifest.json // 拡張機能の設定ファイル（Manifest V3） 
├── options.html // オプション（設定画面）ページ 
└── options.js // オプション画面用スクリプト
```

## 3. ファイル・プログラムの説明

### manifest.json

拡張機能の基本設定ファイルです。  
Manifest V3に対応し、`declarativeNetRequest`を利用して動的ルールを設定できるようにしています。  
また、ユーザーが指定したブロックURLに対応するため、`options_page`と`storage`の権限も付与しています。

```json:manifest.json
{
  "manifest_version": 3,
  "name": "block-sites",
  "version": "1.0",
  "description": "指定したURLをブロックし、集中力向上を目指すChrome拡張です。",
  "permissions": [
    "declarativeNetRequest",
    "storage"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "options_page": "options.html",
  "background": {
    "service_worker": "background.js"
  },
  "web_accessible_resources": [
    {
      "resources": ["block.html", "style.css"],
      "matches": ["<all_urls>"]
    }
  ]
}
```

### background.js
Service Workerとして動作し、chrome.declarativeNetRequest API を用いてユーザーが指定したURLパターンに対する動的ルールを更新する処理を実装しています。

```javascript:background.js
// 動的ルールを更新する関数
function updateBlockRules(urls) {
  chrome.declarativeNetRequest.getDynamicRules((currentRules) => {
    const currentIds = currentRules.map(rule => rule.id);
    const newRules = urls.map((url, index) => {
      return {
        id: 100 + index,
        priority: 1,
        action: {
          type: "redirect",
          redirect: { extensionPath: "/block.html" }
        },
        condition: {
          urlFilter: url,
          resourceTypes: ["main_frame"]
        }
      };
    });
    chrome.declarativeNetRequest.updateDynamicRules({
      removeRuleIds: currentIds,
      addRules: newRules
    }, () => {
      if (chrome.runtime.lastError) {
        console.error("ルール更新エラー:", chrome.runtime.lastError.message);
      } else {
        console.log("動的ルール更新完了:", newRules);
      }
    });
  });
}

// 拡張機能インストール時に保存済みのブロックURLでルールを更新
chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.sync.get(["blockUrls"], (data) => {
    const urls = data.blockUrls || [];
    updateBlockRules(urls);
  });
});

// options.html からのメッセージを受信してルールを更新
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "updateRules" && Array.isArray(message.urls)) {
    updateBlockRules(message.urls);
    sendResponse({ status: "ok" });
  }
});
```

### options.html と options.js
ユーザーがブロックしたいURLパターンを入力するための設定画面です。
入力されたURLはchrome.storageに保存され、背景スクリプトへ更新メッセージが送信されます。


```HTML:options.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ブロックURLの設定</title>
</head>
<body>
  <h1>ブロックする URL の設定</h1>
  <form id="blockForm">
    <textarea id="urls" rows="10" cols="50" placeholder="1行に1つのURLパターンを入力してください"></textarea>
    <br>
    <button type="submit">保存</button>
  </form>
  <script src="options.js"></script>
</body>
</html>
```
```javascript:options.js
document.addEventListener("DOMContentLoaded", () => {
  const form = document.getElementById("blockForm");
  const textarea = document.getElementById("urls");

  // 保存済みのブロックURLを読み込む
  chrome.storage.sync.get(["blockUrls"], (data) => {
    if (data.blockUrls && Array.isArray(data.blockUrls)) {
      textarea.value = data.blockUrls.join("\n");
    }
  });

  // フォーム送信時の処理
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const urls = textarea.value.split("\n").map(url => url.trim()).filter(url => url.length > 0);
    chrome.storage.sync.set({ blockUrls: urls }, () => {
      console.log("ブロックURLを保存しました:", urls);
      chrome.runtime.sendMessage({ type: "updateRules", urls: urls }, (response) => {
        console.log("ルール更新の応答:", response);
      });
    });
  });
});
```
### block.html と style.css
ブロック対象のサイトにアクセスした際に表示されるページです。
シンプルかつ視認性の高いデザインになっています。
```html:block.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>アクセスブロック中</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="block-container">
    <h1>アクセスがブロックされました</h1>
    <p>このサイトは管理者によって制限されています。</p>
  </div>
</body>
</html>
```
```css:style.css
body {
  margin: 0;
  padding: 0;
  background-color: #f9f9f9;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
.block-container {
  text-align: center;
  background-color: #fff;
  border: 2px solid #d9534f;
  border-radius: 10px;
  padding: 40px 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.block-container h1 {
  margin-bottom: 20px;
  color: #d9534f;
  font-size: 2.5em;
}
.block-container p {
  font-size: 1.2em;
  color: #333;
}
```

## 4. 利用方法とGitHub紹介
利用方法
インストール

GitHubからリポジトリをクローンまたはZIPでダウンロードします。
Chromeのchrome://extensions/にアクセスし、デベロッパーモードをオンにして「パッケージ化されていない拡張機能を読み込む」を選択し、ダウンロードしたフォルダを指定します。
ブロックURLの設定

拡張機能のオプション画面（options.html）にアクセスし、ブロックしたいURLパターン（例：||example.com^）を1行ずつ入力して保存します。
設定後、対象サイトにアクセスすると、ブロックページ（block.html）にリダイレクトされることを確認してください。
設定の更新

ブロックURLを変更する場合は、再度オプション画面で修正し、保存するだけで動的ルールが更新されます。
### GitHubリポジトリ
このプロジェクトはオープンソースとしてGitHubで公開しています。
詳細や最新版、バグ報告、プルリクエストなどは下記のリポジトリをご参照ください。

GitHub: https://github.com/k-hiii/block-sites
## 5. まとめ
Chrome拡張「block-sites」は、集中力向上を目的として不要なサイトへのアクセスをブロックするシンプルなツールです。
「やばい集中力」で得たインスピレーションをもとに、ブラウザ上で簡単に設定・更新できるように実装しました。
ぜひ、皆さんも試してみてください！