🔗

お手軽にchrome拡張機能を作った話

に公開

初めに

私が勤める会社では、セキュリティ上の問題で世の中に転がっているchromeの拡張機能が使えません。
じゃぁどうすればいいか?
作ればいいじゃないか。
というわけで、作ってみました。

何を作るのか?

現在開いているTabのURL、ページタイトルをリッチテキスト形式で取得する機能です。
資料を共有したいとき、私はよくメールにリッチテキスト形式で資料の情報を貼り付けて送ります。
毎回「URLを取得して、貼って、資料名を取得して、貼って。。。」というのが、
地味にめんどくさかったのです。

どうやって作るのか?

今までchromeの拡張機能なんて作ったこともありません。
その辺の知識も全くありません、
というわけで、ChatGPT君に丸投げしてみました。

チョコっとこだわりポイント。

私の会社ではGWSを利用しており、Googleの資料を共有する機会がまぁまぁあります。
ですが、Googleのファイルのページタイトルは
資料1 - Google スプレッドシート
のように表示されています。
後ろのがまっっったくいりません😠
というわけなので、ハイフン(-)以降は削除し、残った後ろの半角スペースをtrimしてもらいました。

出来上がったもの

こちらです。
chrome拡張機能の作り方については、いろんな人が教えてくれているから、調べてくださいね。

ファイル構成

/chrome-extension
 ├── manifest.json
 ├── popup.html
 ├── popup.js
 ├── background.js
 ├── icon.png

manifest.json

manifest.json
{
    "manifest_version": 3,
    "name": "Link取得機能",
    "version": "1.0",
    "description": "開いているページのタイトルとURLを取得して表示し、クリップボードにコピーします。",
    "permissions": ["tabs", "activeTab", "clipboardWrite"],
    "action": {
      "default_popup": "popup.html",
      "default_icon": "icon.png"
    },
    "background": {
      "service_worker": "background.js"
    }
  }

popup.html

popup.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>リンク取得</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 10px; text-align: center; }
        a { display: block; margin: 10px 0; }
    </style>
</head>
<body>
    <h3>現在のページ</h3>
    <a id="pageLink" href="#" target="_blank">リンクを取得中...</a>
    <p id="copyStatus"></p>
    <script src="popup.js"></script>
</body>
</html>

popup.js

popup.js
document.addEventListener("DOMContentLoaded", async () => {
    let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    if (tab) {
        // タイトルから最初の "-" 以降を削除し、末尾のスペースを trim
        let formattedTitle = tab.title.split(" - ")[0].trim();

        let linkElement = document.getElementById("pageLink");
        linkElement.textContent = formattedTitle;
        linkElement.href = tab.url;

        // クリップボードにリッチテキスト形式でコピー
        const richText = `<a href="${tab.url}">${formattedTitle}</a>`;
        const plainText = `${formattedTitle} (${tab.url})`;

        try {
            await navigator.clipboard.write([
                new ClipboardItem({
                    "text/plain": new Blob([plainText], { type: "text/plain" }),
                    "text/html": new Blob([richText], { type: "text/html" })
                })
            ]);
            document.getElementById("copyStatus").textContent = "クリップボードにコピーしました!";
        } catch (err) {
            console.error("コピーに失敗:", err);
            document.getElementById("copyStatus").textContent = "コピーに失敗しました。";
        }

        // ポップアップの幅をテキストの長さに応じて調整
        let bodyWidth = Math.min(Math.max(formattedTitle.length * 8, 200), 600);
        document.body.style.width = bodyWidth + "px";
    }
});

background.js

background.js
document.addEventListener("DOMContentLoaded", async () => {
    let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

    if (tab) {
        // タイトルから最初の "-" 以降を削除し、末尾のスペースを trim
        let formattedTitle = tab.title.split(" - ")[0].trim();

        let linkElement = document.getElementById("pageLink");
        linkElement.textContent = formattedTitle;
        linkElement.href = tab.url;

        // クリップボードにリッチテキスト形式でコピー
        const richText = `<a href="${tab.url}">${formattedTitle}</a>`;
        const plainText = `${formattedTitle} (${tab.url})`;

        try {
            await navigator.clipboard.write([
                new ClipboardItem({
                    "text/plain": new Blob([plainText], { type: "text/plain" }),
                    "text/html": new Blob([richText], { type: "text/html" })
                })
            ]);
            document.getElementById("copyStatus").textContent = "クリップボードにコピーしました!";
        } catch (err) {
            console.error("コピーに失敗:", err);
            document.getElementById("copyStatus").textContent = "コピーに失敗しました。";
        }

        // ポップアップの幅をテキストの長さに応じて調整
        let bodyWidth = Math.min(Math.max(formattedTitle.length * 8, 200), 600);
        document.body.style.width = bodyWidth + "px";
    }
});

ChatGPT君が出してくれたものをまま使っています。
何も書き換えていません。
何が書いてあるかもあまり見ていません🙄

iconはhttps://icooon-mono.com/より拝借しました。
いつもお世話になっています。

実行してみた

chromeの拡張機能メニューから、「パッケージ化されていない拡張機能を読み込む」を押下して取り込み。

ちゃんとメニューにも表示されてる。うんうん。

スプレッドシート上で実行してみて、ちゃんとできました!

メールに張り付けてみたら、ちゃんとうまくリンクもファイル名も貼れています。
よしよし。

たまに失敗しちゃうみたい🤦
何回もやってればそのうちうまくいくから、気にしないことにしました。

最後に

知識もないのにここまで作れちゃうなんて恐ろしい。
これはもう、AIに頼りっきりになるしかないぜ🤗

Discussion