🌏

ページ情報からREST APIを叩くChrome Extensionを作成する

2024/09/21に公開

モチベーション

IT部門がREST APIを叩く時は、curlコマンドを使ったり Postmanやtalend api tester などのツールを使うことが多いですが、
非エンジニアにとってはこれらのツールを使うのはハードルが高いです。
そこで、Chrome Extensionを使ってワンボタンでREST APIを叩ける簡易的なツールを作成しました。
具体的には、Notionのページ情報を送信するとページをPDFファイルに変換して返すAPIを叩くような動作を実装しました。

とりあえず調べてみる

chrome拡張開発といっても全く見当がつかないので、まずは調べてみます。

https://qiita.com/tkawa15/items/302e85dfe69d95fd64cc

どうやら、chrome拡張は右上のPopup,DOM操作を行うContent Script,バックグラウンドで動作するBackground Scriptの3つの要素で構成されているようです。
リクエストを送りたいだけならPopupだけでいいかな?

https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world?hl=ja
ハローワールドがあるのでとりあえずやってみます。

ハローワールドを改造する

チュートリアルを進めると以下のファイル構成になりました。
(詳しくは↑のURLのチュートリアルを進めてください)

- manifest.json
- popup.js
- hello.html
- hello_extensions.png

チュートリアルでは、ポップアップ表示時にコンソールログを出力するようになっていたので、これをREST APIを叩くように改造してみます。

まず、htmlにメッセージを表示する代わりにボタンを追加します。

<!DOCTYPE html>
<html>
<head>
    <title>Request Extensions</title>
    <script src="popup.js"></script>
</head>
<body>
    <button id="sendRequestButton">Convert Request</button>
</body>
</html>

次に、ボタンを押下した時にリクエストを送るようにpopup.jsを修正します。

document.addEventListener("DOMContentLoaded", function () {
  document.getElementById("sendRequestButton").addEventListener("click", async function () {
    try {
      const tabs = await chrome.tabs.query({ active: true, currentWindow: true });

      if (tabs.length === 0 || !tabs[0].url) {
        alert("No active tab or URL is undefined.");
        return;
      }

      const url = tabs[0].url;
      if (!url.includes("notion.so")) {
        alert("Not a Notion page.");
        return;
      }

      let pageId;
      try {
        pageId = url.split("/").pop().split("-").pop();
      } catch (error) {
        alert("Error: " + error.message);
        throw error;
      }

      const response = await fetch("{リクエストURL}", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ pageId: pageId }),
      });

      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      const blob = await response.blob();
      const downloadUrl = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = downloadUrl;
      a.download = `doc.pdf`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(downloadUrl);

      alert("Success: PDF downloaded");
    } catch (error) {
      console.log(error);
      if (error.message.includes("Failed to fetch")) {
        alert("Error: Connection refused. Please ensure the server is running.");
      } else if (error instanceof TypeError) {
        alert("Error: TypeError: Failed to fetch");
      } else {
        alert("Error: " + error.message);
      }
    }
  });
});

タブからページURLを抽出して、Notionのページであるかを判定し、ページIDを取得してリクエストを送るようにしました。
タブのようなChrome拡張特有のAPIは以下のURLで確認できます。
https://developer.chrome.com/docs/extensions/reference?hl=ja

最後にmanifest.jsonを修正します。
これは、tab情報を読み込むpermissionを追加するためです。

{
    "manifest_version": 3,
    "name": "Hello Extensions",
    "description": "Base Level Extension",
    "version": "1.0",
    "permissions": ["tabs","activeTab"],
    "action": {
      "default_popup": "hello.html",
      "default_icon": "hello_extensions.png"
    }
  }

全て完了したら以下の手順で拡張機能を読み込みます。
https://note.com/id_helpdesk/n/naa2ca000c3e5

起動できました!
alt text

感想

細かいことは気にしないで作ればある程度お手軽に作れることがわかりました。
とはいえ、現状ボタン押下時にマウスがwaitingにならなかったりデプロイが手動でユーザに行ってもらう必要があるなど課題は多いのでやれることは多そうです。
というか今の状態だったら talend api tester に慣れてもらった方が早そうですね
とりあえず何をすればいいかわからない状態の方に少しでも手助けになれば幸いです。

GitHubで編集を提案

Discussion