🤖

Chrome拡張を作って、日常のちょっとした不便を減らしてみた話

に公開

こんにちは!ソーシャルデータバンク株式会社・エンジニアリング部のくすみです。
Social Databank Advent Calendar 2025 23 日目の記事です!

Chrome 拡張を作って、日常のちょっとした不便を減らしてみた話

最近、Chrome で作業していると
「タブ多すぎでは?」と思う瞬間が増えてきました。

気づくと 20 個以上開いていて、
「あとで読むやつ」「今は使ってないやつ」が大量に残っているという状態です。

分かってはいるんですが、集中しているとつい増やしてしまうんですよね。

だったらもう、
自分で気をつけるのをやめて、Chrome に見張らせよう
と思い、Chrome 拡張を作ってみました。

タブが増えすぎたら教えてくれる拡張

最初に作ったのは、タブ監視用の Chrome 拡張です。

やっていることはかなり単純です。

  • ⏱ 一定間隔(5 秒)で全ウィンドウのタブ数をチェック
  • 🚨 合計が 20 個を超えたら、現在アクティブなタブに警告を表示

「今、タブ多いですよ〜」とだけ教えてくれれば、十分という考えです。

挙動

  1. 新規タブを開く
  2. Chrome 拡張ツールがタブ数を判定
  3. 20 個以上のタブを開いている場合は警告が表示

実際のコード(一部)

manifest.json

{
  "manifest_version": 3,
  "name": "Tab Watcher",
  "version": "1.1",
  "description": "開いているタブを監視し、20個以上のタブがあればブラウザ上で警告",
  "permissions": ["tabs", "scripting", "activeTab"],
  "background": {
    "service_worker": "background.js"
  }
}

今回はタブの数を取得したかったので `tabs`
ページ上に警告を出したかったので `scripting` を指定

background.js;

const TAB_LIMIT = 20;
const CHECK_INTERVAL = 5000;

async function checkTabs() {
  const tabs = await chrome.tabs.query({});
  const [activeTab] = await chrome.tabs.query({
    active: true,
    currentWindow: true,
  });
  if (!activeTab) return;

  if (tabs.length > TAB_LIMIT) {
    await showInPageAlert(activeTab.id, {
      title: "🚨タブが多すぎます!",
      message: `現在 ${tabs.length} / 上限 ${TAB_LIMIT}`,
    });
  }
}

画面上に表示される警告

勝手なイメージでしたが、今開いているウィンドウ内のタブ数しか取得できないと思っていました。
実際に調べてみると、Chrome 拡張ではブラウザ全体のタブ情報を取得でき、ウィンドウをまたいだタブ数もまとめて扱えることが分かりました。
そのため、今開いているすべてのウィンドウのタブ数を取得した上で、判定できました!

気づかずに増やしすぎてしまったタブに気づける拡張ツールが作成できました。

Chrome 拡張、思ったより色んなことができる

Chrome 拡張って、なんとなく難しそうかつ、自由度が少なそうなイメージがありました。
しかし、実際に触ってみると意外とそんなことなかったです。

  • 開いているタブの情報を取れる
  • ページに要素を差し込める
  • 裏で定期処理もできる

もちろん権限の指定は必要ですが、manifest.json にちゃんと書けば問題なく動きます。

むしろ「この拡張は何をしたいのか?」をちゃんと考えないと書けないので、設計の整理にもなりました。

次は AI 要約の Chrome 拡張を作ってみた

次に作ったのが、
開いているページの内容を AI が要約する Chrome 拡張です。

こちらは、

  • 今見ているページの本文を取得
  • OpenAI API に投げる
  • 要約結果をポップアップに表示

という流れです。

難しいニュース記事などをサクッと把握するために作成しました。

実際のコード(一部)

manifest.json

{
  "manifest_version": 3,
  "name": "AI Summarizer",
  "version": "1.1",
  "description": "Webページの内容をAIが要約します",
  "permissions": ["activeTab", "scripting", "storage"],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "host_permissions": ["https://*/*", "http://*/*"]
}
popup.js;

async function runSummarize(addPrompt = "") {
  const resultEl = document.getElementById("result");
  resultEl.textContent = "🤔 思考中...";

  const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

  const [{ result: text }] = await chrome.scripting.executeScript({
    target: { tabId: tab.id },
    // 入力上限にぶつからないよう、とりあえず4000文字まで
    func: () => document.body.innerText.slice(0, 4000),
  });

  const response = await chrome.runtime.sendMessage({
    action: "summarize",
    text,
    addPrompt,
  });
  resultEl.textContent = response.summary;
}
background.js;

chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.action === "summarize") {
    summarizeText(msg.text, msg.addPrompt).then((summary) => {
      sendResponse({ summary });
    });
    return true;
  }
});

async function summarizeText(text, addPrompt) {
  const apiKey = "あなたのAPIキーをここに入力";
  const safeText = (text || "").trim().slice(0, 4000);

  const systemMessage =
    "あなたは優秀な要約アシスタントです。わかりやすく説明してください。";
  const userPrompt =
    (typeof addPrompt === "string" ? addPrompt.trim() : "") || "要約して";

  const messages = [
    { role: "system", content: systemMessage },
    { role: "user", content: `${userPrompt}\n\n${safeText}` },
  ];

  const res = await fetch("https://api.openai.com/v1/chat/completions", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({
      model: "gpt-4o-mini",
      messages,
      temperature: 0.4,
    }),
  });

  const data = await res.json();
  return data.choices?.[0]?.message?.content?.trim() ?? "要約に失敗しました。";
}

なお、今回 Open AI の API キーが必要なので取得する必要があります。
https://platform.openai.com/api-keys

ここで取得できたキーを使用して、要約させると...

画面上に表示される要約

この記事では、ソーシャルデータバンク株式会社の開発部のくすみさんが、日常の不便を解消するために自作したChrome拡張機能について紹介しています。

まず、くすみさんは「タブが増えすぎて集中できない」という問題を解決するために、タブの数を監視し、20個を超えた場合に警告を出す拡張機能「Tab Watcher」を作成しました。これにより、開いているタブの数を簡単に把握できるようになり、作業の効率が向上しました。

次に、彼は「AI Summarizer」という拡張機能を開発しました。この機能は、現在表示しているウェブページの内容をAIが要約し、ポップアップで表示します。これにより、難しい記事を短時間で理解できるようになります。

くすみさんは、Chrome拡張は思ったよりも簡単に作成できると感じ、開発を通じて設計の整理にも役立ったと述べています。彼の体験は、他の人にも自分のアイデアを形にするきっかけになるかもしれません!

いい感じに要約できていますね!

使ってみた感想

本文取得 → OpenAI に送る → AI が思考する → 返ってくる、というフローを辿っているので、
要約文を取得するまでにはそれなりに時間がかかります。

ただ、その分しっかりとした要約が返ってくるので、
ざっと内容を把握したいときにはかなり便利だと感じました。

長めの記事でも、「だいたい何が書いてあるか」を短時間で掴めるので、
読むかどうかを判断するのが楽になります。

ちょっとした確認用途としては、想像していた以上に使い勝手がよかったです。

作ってみて思ったこと

拡張ツールを作るって意外と「難しくない」ということです。
もちろん、manifest の記述内容は新たに学習する必要がある分野でしたが、複雑なものではなく、公式ドキュメントを見ながら進めれば十分対応できる内容でした。

JavaScript と少しの設定ファイルが書ければ、普段使っているブラウザの動きをある程度コントロールできるのは、想像以上に楽しかったです。

「こんな機能があったらいいな」と思ったものを、そのまま自分で形にできるのは、Chrome 拡張ならではの面白さだと感じました。

今回のように、自分用のちょっとしたツールを作る目的であれば、そこまで身構えずに始めてみてもいいのかなと思います。

おわりに

今回、Chrome 拡張をいくつか作ってみて、思っていたよりも気軽に試せるものなんだなと感じました。

普段使っているブラウザだからこそ、少し手を入れるだけでも使い勝手が変わるのが面白いところです。

また何か「ちょっと不便だな」と感じることがあれば、その都度、Chrome 拡張で試してみようと思います。

コードは GitHub に置いているので、興味があれば覗いてみてください。

最後まで読んでいただき、ありがとうございました。

ソーシャルデータバンク テックブログ

Discussion