3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ブックマークレットでさくっと再配布を簡単にする方法

Posted at

ブックマークレットでサクッとWEBページを自動で動かしたい時ありますよね?

例えば、ChatGPTを社内展開したけど毎回独自のプロンプトのテンプレート配布するのつらいなーって時ないですか?

あったとします。

(あとGPTs使えばいいじゃん、とか他サービス使えば・・とかまぁ方法はありますが今回はブックマークレットに絞ってお話しします)

そんな時にブックマークレットって形でChromeのブックマークに以下のJavaScriptを登録すれば動くわけです

Chromeで使えるぽちー通せばJSが実行できるブックマークレット

image.png

ブックマークレットの中身のJS

(わからない単語を入力するとプロンプトにしてChatJPTの入力欄に入力して実行までを教えてくれる)

javascript:(function() {
    var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    var popupX = window.screenX + (windowWidth - 400) / 2;
    var popupY = window.screenY + (windowHeight - 200) / 2;
    
    var popup = window.open("", "わからない単語を入力してね", "width=400,height=200,left=" + popupX + ",top=" + popupY);
    
    var html = `
    <html>
    <head>
    <title>Popup</title>
    <style>
    body {
    background-color: rgba(255, 255, 255, 0.5);
    font-family: Arial, sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    }
    input[type="text"] {
    width: 80%;
    padding: 10px;
    margin-bottom: 10px;
    border: none;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    }
    button {
    padding: 10px 20px;
    margin: 5px;
    border: none;
    border-radius: 5px;
    background-color: #007BFF;
    color: white;
    cursor: pointer;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    }
    button:hover {
    background-color: #0056b3;
    }
    #closeBtn {
    background-color: #6c757d;
    }
    #closeBtn:hover {
    background-color: #5a6268;
    }
    </style>
    </head>
    <body>
    <input type="text" id="inputText" placeholder="テキストを入力してください">
    <div>
    <button id="executeBtn">実行</button>
    <button id="closeBtn">閉じる</button>
    </div>
    
    
        <script>
          document.getElementById("executeBtn").addEventListener("click", function() {
            var inputText = document.getElementById("inputText").value;
            var promptText = \`\${inputText}について教えてください。\`;
            
            var textarea = window.opener.document.getElementById("prompt-textarea");
            textarea.value = promptText;
            textarea.dispatchEvent(new Event('input', { bubbles: true }));
            
            setTimeout(function() {
              var button = window.opener.document.querySelector('button[data-testid="send-button"]');
              button.dispatchEvent(new MouseEvent('click', { bubbles: true }));
              
              window.close();
            }, 300);
          });
          
          document.getElementById("closeBtn").addEventListener("click", function() {
            window.close();
          });
          
          var activeWindow = window.opener;
          var activeWindowRect = activeWindow.getBoundingClientRect();
          var popupX = activeWindowRect.left + (activeWindowRect.width - 400) / 2;
          var popupY = activeWindowRect.top + (activeWindowRect.height - 200) / 2;
          window.moveTo(popupX, popupY);
        </script>
      </body>
    </html>
    `;
    
    popup.document.open();
    popup.document.write(html);
    popup.document.close();
    })();

(長いね。。)


こんな感じで動きます

demo (bookmarkバーにあるブックマークレットをポチる>ポップアップが出てそこに「雷鳥」と入力>実行> ChatGPTのテキストに自動で入力され、送信ボタンも自動でクリックされている)

便利ではあるがこれって再配布で死ぬよね?

ただこのJSが今後変わった時に配布するの正直だるすぎます
あ、このプロンプト変えたいなーとかChatGPTの仕様が変わってタグが変わったようとかあると、
「あ、この修正版のJSをまたブックマークレットの編集画面でコピペしてください :pray:
。。。これはしんどすぎます。

JSの中身を外だししましょう

まぁ普通にWEBアプリ作ってれば当然っちゃ当然なんですがブックマークレットってサクッと作れちゃうものなのでそこに全部書いてただけなんで、
JSの中身を単純にどっか(S3)とかにおいて以下のようにしても同じように動くわけです

で、ブックマークレットのJSをS3において呼び出した例です

ブックマークレット改善版

javascript:(function(){
  var script = document.createElement('script');
  script.src = 'https://hogefuga.s3.ap-northeast-1.amazonaws.com/chat_gpt_helper.js';
  document.body.appendChild(script);
})();

chat_gpt_helper.jsの中身を例えばS3にアップしておきます

    var windowWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var windowHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    var popupX = window.screenX + (windowWidth - 400) / 2;
    var popupY = window.screenY + (windowHeight - 200) / 2;
    
    var popup = window.open("", "わからない単語を入力してね", "width=400,height=200,left=" + popupX + ",top=" + popupY);
    
    var html = `
    <html>
    <head>
    <title>Popup</title>
    <style>
    body {
    background-color: rgba(255, 255, 255, 0.5);
    font-family: Arial, sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0;
    }
    input[type="text"] {
    width: 80%;
    padding: 10px;
    margin-bottom: 10px;
    border: none;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    }
    button {
    padding: 10px 20px;
    margin: 5px;
    border: none;
    border-radius: 5px;
    background-color: #007BFF;
    color: white;
    cursor: pointer;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
    }
    button:hover {
    background-color: #0056b3;
    }
    #closeBtn {
    background-color: #6c757d;
    }
    #closeBtn:hover {
    background-color: #5a6268;
    }
    </style>
    </head>
    <body>
    <input type="text" id="inputText" placeholder="テキストを入力してください">
    <div>
    <button id="executeBtn">実行</button>
    <button id="closeBtn">閉じる</button>
    </div>
    
    
        <script>
          document.getElementById("executeBtn").addEventListener("click", function() {
            var inputText = document.getElementById("inputText").value;
            var promptText = \`\${inputText}について教えてください。\`;
            
            var textarea = window.opener.document.getElementById("prompt-textarea");
            textarea.value = promptText;
            textarea.dispatchEvent(new Event('input', { bubbles: true }));
            
            setTimeout(function() {
              var button = window.opener.document.querySelector('button[data-testid="send-button"]');
              button.dispatchEvent(new MouseEvent('click', { bubbles: true }));
              
              window.close();
            }, 300);
          });
          
          document.getElementById("closeBtn").addEventListener("click", function() {
            window.close();
          });
          
          var activeWindow = window.opener;
          var activeWindowRect = activeWindow.getBoundingClientRect();
          var popupX = activeWindowRect.left + (activeWindowRect.width - 400) / 2;
          var popupY = activeWindowRect.top + (activeWindowRect.height - 200) / 2;
          window.moveTo(popupX, popupY);
        </script>
      </body>
    </html>
    `;
    
    popup.document.open();
    popup.document.write(html);
    popup.document.close();

あとは先ほどと同じように動かせます。

変更あった時はサクッとGithubにmerge

で、変更あったら呼び出しているJSを変更したら使っているユーザーに変更が反映されるわけです :thumbsup:
例えばGithubのリリース用ブランチにmergeしたら
S3にJSをアップするみたいなCI/CD組んでおけば、
ブックマークレットの中身が更新配布がよりやりやすいですね

まとめ

ちょっとこのWEBページでスクレイピングしたりRPA的に自動実行したい!!
という要望が社内で上がった時などに、
サクッとブックマークレット化して対応するのも良いかもですね。
ただそのままブックマークレットに全部JSを突っ込むのではなく、
外だし管理して再配布も楽になるようにするといいですね。

3
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?