PR

【ChatGPT】検索ツール(ライバルチェック)をJavaScriptを作ってみた

ChatGPTでブログの記事作成で役立つツールを作れないか、と試しに作ってみました。

作ったツールは「メインキーワード」と「よく調べるキーワード」を入力し、それらから検索のための(ライバルチェックのための)リンク文字列をリアルタイムで生成する、という簡単なもの。(特定ジャンルの記事作成に役立てる用)

実際の動作とChatGPTへ指示したプロンプト、実際の生成コードのご紹介です。

「JIN Quick cheker 01」と名付けました(笑)ご参考までに。

検索&ライバルチェックツール

実際作ってみたツールがこちら。

【JIN Quick cheker 01】

【使い方】

  • ①:メインキーワードを入力:
    人物名など。例)新垣結衣
  • ②:検索キーワードを入力
    良く検索/ライバルチェックするキーワード。
    例)年齢、結婚相手
  • ③:グーグルかヤフーか
    どちらの検索エンジンを使うか選択
  • ④:allintitle
    付加するを選択すると検索に「allintitle:」が付加され、タイトルにメインキーワード、検索キーワードがすべて含まれたものだけが表示される(その件数が分かる)
  • ⑤:リンク文字列
    ①~④が反映されたリンク文字列が表示される。
    クリックして、実際に検索して件数などをチェックする

【補足】
検索キーワード(②)に複数のキーワードを入れると、⑤「リンク文字列」も複数になりますが、Ctrlキーを押しながらリンクをクリックしていくと順次ブラウザの別タブに表示されてチェックしやすいと思います。(お試しください)

ちなみに「② 検索キーワードを入力」「③ グーグル/ヤフー選択」「④ allintitle付加」は(クッキーに)保存するようにしているので、この記事を再び表示した時に、その保存内容が反映されます。

※)入力内容は第三者には分かりません
(勿論私にも分かりません ^-^;))

ChatGPTへ指示したプロンプト

プログラムを作成するためにChatGPTに指示したプロンプトは以下。

(ブラウザ上で入力された値に応じてリアルタイムにリンクを作成してほしい、
ということから JavaScriptでのプログラムコード生成にしてます)

Code
以下のJavaScriptを作って。

------------------------------------
仕様全体
------------------------------------
・入力ボックス1がある

・テキストボックス2がある

・ラジオボタン3がある
 グーグルかヤフーを選択できる(デフォルトはGoogle)

・ラジオボタン4がある
「allintitle:」を付ける、付けないを選択できる(デフォルトは「付ける」)

・リンク文字列を生成して表示する
入力ボックス1,テキストボックス2,ラジオボタン3、ラジオボタン4の内容に従って、
テキストボックス2の内容を1行1行リンク文字列にする。

入力ボックス1,テキストボックス2,ラジオボタン3、ラジオボタン4の内容が変更された場合、リアルタイムにリンク文字列も変更する。

ただし入力ボックス1に入力がない場合には、リンク文字列は表示しない。

------------------------------------
各項目の仕様
------------------------------------
■入力ボックス1について
入力ボックス1のラベルは「メインキーワード」。
入力できる最大文字数:20。


■テキストボックス2について
テキストボックス2のラベルは「検索キーワード」。
テキストボックス2は複数行入力できる。
入力できる最大文字数:50。

テキストボックス2の内容は、クッキーに保存され、
ページロード時に自動的にクッキーの内容がテキストボックス2にセットされる。


■ラジオボタン3について
ラジオボタン3のラベルはなし。

ラジオボタンは、項目名の前に付ける。
「●」をラジオボタンだとすると以下。

●グーグル ●ヤフー

ラジオボタン3の選択は、クッキーに保存され、
ページロード時に自動的にクッキーの内容がラジオボタン3にセットされる。


■ラジオボタン4について
ラジオボタン3のラベルは「allintitle」。

ラジオボタンは、項目名の前に付ける。
「●」をラジオボタンだとすると以下。

allintitle ●付加する ●なし


■リンク文字列について
たとえば入力ボックス1に「あいうえお」が入力され、
テキストボックス2に以下の4行あったとする

年齢
結婚相手

この場合、リンク文字列として入力ボックス1の内容を加えた以下が表示される。

あいうえお 年齢
あいうえお 結婚相手

この文字列各々は、
ラジオボタン4の選択と組み合わせ、ラジオボタン3に従ったリンクとする。

ラジオボタン3でグーグルが選択され、
ラジオボタン4で「付加する」が選択されている場合、
各々の文字列をクリックすると以下で検索できるようリンクする。

<a href="https://www.google.com/search?q=allintitle:あいうえお 年齢" target="_blank">あいうえお 年齢</a>
<a href="https://www.google.com/search?q=allintitle:あいうえお 結婚相手" target="_blank">あいうえお 結婚相手</a>

ラジオボタン4で「なし」が選択されている場合、
各々の文字列をクリックすると以下で検索できるようリンクする。

<a href="https://www.google.com/search?q=あいうえお 年齢" target="_blank">あいうえお 年齢</a>
<a href="https://www.google.com/search?q=あいうえお 結婚相手" target="_blank">あいうえお 結婚相手</a>


同様にラジオボタン3でヤフーが選択されて、
ラジオボタン4で「付加する」が選択されている場合、
各々の文字列をクリックすると以下で検索できるようリンクする。

<a href="https://search.yahoo.co.jp/search?p=allintitle:あいうえお 年齢" target="_blank">あいうえお 年齢</a>
<a href="https://search.yahoo.co.jp/search?p=allintitle:あいうえお 結婚相手" target="_blank">あいうえお 結婚相手</a>


■補足事項
生成するコードはセキュリティも考慮すること。

JavaScriptはワードプレスのカスタムHTMLに挿入するため、
生成されるコードは、<body>タグ内に貼る想定でOK。
(<html>タグや<body>は考えなくても良い)
Jin Simple Code Block

このプロンプトをChatGPTに与えると、
以下のような感じで、それはもう魔法のようにJavaScriptのコードを作ってくれますね。

このコードをChatGPTを使わずに調べながら作ったとすると、多分私の場合では数時間は普通にかかると思います。

でもプロンプトを作るのに30分もかかってませんし、プロンプトができれば、まさに一瞬でコードを作ってくれるので、大幅な時間短縮にもなりますね。

また私が良く分かってないセキュリティ面も考慮されたコードになっているようで大助かり。(プロンプトの最後に「セキュリティも考慮してね、と加えてる)

ちなみに、ChatGPTが生成したコードは、
全て指示したプロンプトの意図通りになってない場合があるので、実際動作させてみて、指示と異なる点がないかは確認してみましょう。

また、少し見やすくなるようにCSSでデザインもしてますが、CSSを使うにあたっては、ChatGPTが生成したコードに含まれる改行(<br>タグ)を削除したり、<div>タグを追加してclassの追加をしたりしてます。

【貼り付けてたJavascript】

Code
<div class="jin-quick-cheker-01"> 
<div id="keyword-link-tool">
  <div>
    <label for="mainKeyword">① メインキーワード</label><br>
    <input type="text" id="mainKeyword" maxlength="20">
  </div>

  <div style="margin-top:12px;">
    <label for="searchKeywords">② 検索キーワード</label><br>
    <textarea id="searchKeywords" maxlength="50" rows="6" style="width:100%;"></textarea>
  </div>

  <div style="margin-top:12px;">
    <label for="searchKeywords">③ 検索エンジン</label><br>
      <input type="radio" name="searchEngine" value="google" checked>
      グーグル
    </label>
    <label style="margin-left:16px;">
      <input type="radio" name="searchEngine" value="yahoo">
      ヤフー
    </label>
  </div>

  <div style="margin-top:12px;">
    <label for="searchKeywords">④ allintitle付加</label><br>
    allintitle
    <label style="margin-left:8px;">
      <input type="radio" name="allintitle" value="yes" checked>
      付加する
    </label>
    <label style="margin-left:16px;">
      <input type="radio" name="allintitle" value="no">
      なし
    </label>
  </div>

  <div id="linkResult" style="margin-top:16px;"></div>
</div>
</div><!– //main -><script>
(function () {
  'use strict';

  const mainKeywordInput = document.getElementById('mainKeyword');
  const searchKeywordsTextarea = document.getElementById('searchKeywords');
  const linkResult = document.getElementById('linkResult');

  const COOKIE_SEARCH_KEYWORDS = 'search_keywords_text';
  const COOKIE_SEARCH_ENGINE = 'search_engine';

  function setCookie(name, value, days) {
    const maxAge = days * 24 * 60 * 60;
    document.cookie =
      encodeURIComponent(name) + '=' + encodeURIComponent(value) +
      '; max-age=' + maxAge +
      '; path=/' +
      '; samesite=lax';
  }

  function getCookie(name) {
    const encodedName = encodeURIComponent(name) + '=';
    const cookies = document.cookie.split(';');

    for (let cookie of cookies) {
      cookie = cookie.trim();
      if (cookie.indexOf(encodedName) === 0) {
        return decodeURIComponent(cookie.substring(encodedName.length));
      }
    }

    return '';
  }

  function getSelectedRadioValue(name) {
    const selected = document.querySelector('input[name="' + name + '"]:checked');
    return selected ? selected.value : '';
  }

  function setSelectedRadioValue(name, value) {
    const target = document.querySelector(
      'input[name="' + name + '"][value="' + CSS.escape(value) + '"]'
    );

    if (target) {
      target.checked = true;
    }
  }

  function createSafeLink(text, url) {
    const a = document.createElement('a');

    a.textContent = text;
    a.href = url;
    a.target = '_blank';
    a.rel = 'noopener noreferrer';

    return a;
  }

  function updateLinks() {
    const mainKeyword = mainKeywordInput.value.trim();
    const searchKeywords = searchKeywordsTextarea.value
      .split(/\r?\n/)
      .map(line => line.trim())
      .filter(line => line !== '');

    const searchEngine = getSelectedRadioValue('searchEngine');
    const useAllintitle = getSelectedRadioValue('allintitle') === 'yes';

    linkResult.textContent = '';

    if (!mainKeyword) {
      return;
    }

    searchKeywords.forEach(function (keyword) {
      const displayText = mainKeyword + ' ' + keyword;
      const queryText = (useAllintitle ? 'allintitle:' : '') + mainKeyword + ' ' + keyword;

      let url = '';

      if (searchEngine === 'yahoo') {
        url = 'https://search.yahoo.co.jp/search?p=' + encodeURIComponent(queryText);
      } else {
        url = 'https://www.google.com/search?q=' + encodeURIComponent(queryText);
      }

      const p = document.createElement('p');
      p.appendChild(createSafeLink(displayText, url));
      linkResult.appendChild(p);
    });
  }

  function saveSettings() {
    setCookie(COOKIE_SEARCH_KEYWORDS, searchKeywordsTextarea.value, 365);
    setCookie(COOKIE_SEARCH_ENGINE, getSelectedRadioValue('searchEngine'), 365);
  }

  function init() {
    const savedKeywords = getCookie(COOKIE_SEARCH_KEYWORDS);
    const savedEngine = getCookie(COOKIE_SEARCH_ENGINE);

    if (savedKeywords) {
      searchKeywordsTextarea.value = savedKeywords;
    }

    if (savedEngine) {
      setSelectedRadioValue('searchEngine', savedEngine);
    }

    mainKeywordInput.addEventListener('input', updateLinks);

    searchKeywordsTextarea.addEventListener('input', function () {
      saveSettings();
      updateLinks();
    });

    document.querySelectorAll('input[name="searchEngine"]').forEach(function (radio) {
      radio.addEventListener('change', function () {
        saveSettings();
        updateLinks();
      });
    });

    document.querySelectorAll('input[name="allintitle"]').forEach(function (radio) {
      radio.addEventListener('change', updateLinks);
    });

    updateLinks();
  }

  init();
})();
</script>
Jin Simple Code Block

また、
デザインのために設定したCSSは以下。

Code
.jin-quick-cheker-01 {
    border: 2px solid #5c7e58;
    padding: 1em;
    background: #fffdf6;
}
.jin-quick-cheker-01 > div > div > label:first-child {
    font-weight: bold;
}
Jin Simple Code Block

プロンプトの作り方の実際

今回ChatGPTを使ってJavaScriptのコードを生成したわけですが、GeminiでもClaudeでも同じようにできると思います。

こうした生成AIに与えるプロンプトの作り方としては、最初から上で見たような長めのプロンプトを一気に作れるわけではありません。

今回の場合では、
まず以下のようなイメージ図を作ってプログラムの全体像を考えてみてます。

  • メインキーワードを入れる入力ボックスがある(①)
  • 検索キーワードを入力するエリアがあるよね(②)
  • 実際に表示される文字列があるよね(③)

...みたいな感じですね。

その後に、まず「本当にJavaScriptのコードを作ってくれるかな」と試しに出始めのお試しプロンプトを作ってみる。

例えば以下のようなシンプルなもの。

Code
以下のJavaScriptを作って。

・入力ボックス1がある
・テキストボックス2がある
・入力ボックス1,テキストボックス2の内容に従って、
テキストボックス2の内容を1行1行リンク文字列にする。

リンク文字列は、たとえば入力ボックス1に「あいうえお」が入力され、
テキストボックス2に以下の2行あったとする

年齢
結婚相手

この場合、リンク文字列として入力ボックス1の内容を加えた以下が表示される。

あいうえお 年齢
あいうえお 結婚相手

この各々の文字列をクリックすると以下で検索できるようリンクする。

<a href="https://www.google.com/search?q=allintitle:あいうえお 年齢" target="_blank">あいうえお 年齢</a>
<a href="https://www.google.com/search?q=allintitle:あいうえお 結婚相手" target="_blank">あいうえお 結婚相手</a>
Jin Simple Code Block

こうした感じで、
まず最初は簡単なものを生成AIへ送って試してます。

その後、検索エンジンもグーグルとヤフーで選択したいよね、とか、入力内容によってリアルタイムにリンクも変えたいよね、セキュリティも考えなくっちゃいけないのかな...などなど細かな仕様を順次プロンプトに追加して、その都度AIに投げて作成されたコードが想定通りの動作になるか試しながらプロンプトに手を加えて行ってみる。

そうしたことをチョコチョコしながら上の方で見た最終形のプロンプトができました。

また、最終形になる少し前のプロンプトでは、
それまで順次色々内容(動作仕様)を追加していったため入り組んだ形にもなっていて、人が読んでも結構分かりづらいもの(自分は分かるけどね、みたいなもの)になってました。

つまりは「これはAIも正しく解釈できないかもしれない」ということで、項目ごとに整理したりしたものが最終形のプロンプトになってます。

プロのエンジニアが要件定義をすれば、もっと上手に書くのでしょうけど、「プロンプトの書き方の基本!~」の記事で説明しているように、とにかく分かりやすく簡潔に書き、具体例も入れて、AIが正しく理解できるようにする、というのがポイントになりそうですね。

関連)
【AI】プロンプトの書き方の基本!初心者がまず覚えることと注意点を分かりやすく解説

またブログで稼ぎたい!ネットビジネスを始めてみたい、AI関連の知識を増やしたい、などありましたら、以下のメルマガにも登録してみてくださいね。

早期退職して海外で奮闘する JIN のメールマガジン

時間や場所に縛られず稼いだJINが教える

~ 最短で月収10万円稼げるようになる方法 ~

お名前/ニックネーム

隣のあの人にも、思わず教えたくなる秘密

配信停止は、いつでもできます

迷惑メールは一切配信されませんので、ご安心くださいね

自らの手で未来を変える力を手に入れる!

コメント