見出し画像

【Mac限定】ショートカットキー1発でGASを生成する方法

freeeからはちょっと離れますが、バックオフィスの仕事全般において切っても切れない関係となってきている生成AIの使い方をご紹介。

生成AIの使い方…と言っても、昨今流行りのチャットAIの使い方ではありません。個人的な意見ですが、AI活用はチャット形式以外の方法で活用が始まった時にそのポテンシャルを発揮できると思っています。

※2024年9月現在、本記事でAIと呼んでいるものはLLM(大規模言語モデル)の生成AIのことを指します。


ショートカットキーを押すだけで、使えるコードが出力される

先日Xでもちょこっと紹介しましたが、比較的、実装がシンプルなGoogle Apps Script(以降GAS)のスクリプトを書く時に、最近はショートカットキー1発で生成しています。

もちろん修正が必要な場合もありますが、使い捨て程度のスクリプトであれば、1回目からなかなか精度の高いコードが出力されます。

使っているのはBetterTouchToolというアプリです。

全MacユーザーにオススメのBetterTouchTool

BetterTouchToolは、トラックパッドやマウス、キーボードの操作をカスタマイズできる便利なアプリです。

Macユーザーで効率化好きの方であれば、全員このアプリは入れたほうが良いと思っているほどです。

BetterTouchToolについて語り始めると長くなるので、今回はスキップしますが、このBetterTouchToolの機能(アクション)で、選択範囲をChatGPTに変換して置き換えというアクションがあります。

要するに選択範囲を読み込んで、事前に指定したプロンプトでChatGPT(相当のAPI)にテキストを生成させることができる機能です。

例:音声入力した文章を整形してもらうアクション

今回は、このアクションにGASのスクリプトの生成を依頼します。

BetterTouchToolでGASを生成する設定

GASを出力させるアクションの設定は以下の通りです。

利用するモデル

私の場合は、より高い精度の返答を期待してOpenAIのAPIキーを設定して、got-4oモデルを利用しています。

APIキーの取得は以下の記事参考。

ちょっとマニアックな補足情報ですが、URL To Callという設定欄も用意されているので、OpenAI API互換のgroqなどの他のAPIを利用してllama3.1などのモデルで稼働することもできそうです。

※OpenAI API互換とは、OpenAIのAPIと同じエンドポイントやパラメータを使用して、他のサービスやモデルのAPIを利用できる互換性を指します。言い換えれば、OpenAI APIの使用方法を理解していれば、互換性のある他のAPIを簡単に導入できます。

システムプロンプト及びユーザープロンプト

AIの役割を指定するシステムプロンプトは、デフォルトのまま利用しています。

You are a helpful assistant who interprets every input as raw text unless instructed otherwise. Your answers do not include a description unless prompted to do so.

あなたは、特別な指示がない限り、すべての入力を生のテキストとして解釈する役立つアシスタントです。説明を求められない限り、あなたの回答には説明を含みません。

BetterTouchToolのデフォルトのシステムプロンプト

ユーザープロンプトは以下を設定しています。

コーディングガイドラインに従って、ユーザーの目的を達成することができるGoogle Apps Script のコードを出力してください。ただし、コードはバッククォートや他の記号で囲まずに、プレーンテキストとして出力してください。
# Google Apps Script コーディングガイド:
(後略)

freeelover

コーディングガイドラインを指定しなくてもコードは出力してくれますが、自分なりのガイドを用意しておくと、出力されるコードの精度がアップします。

チェックボックスの設定

□ 実行するたびに毎回何をするか尋ねる。
□ 選択したテキストの後にGPTの応答を貼り付け

はそれぞれOFFにしています。

今回は固定のショートカットキーに固定のプロンプトでの処理(GASのスクリプトの出力)を割り当てているためです。単純に選択したテキストに対して、毎回プロンプトを指定したい場合には、実行するたびに毎回何をするか尋ねるのチェックをONにします。

選択したテキストの後にGPTの応答を貼り付けは、元のテキストを残すか、上書きするかの設定です。これはお好みで設定してよいと思います。

コードを途中まで書いておく

Xで紹介した動画で出力しているGASのお題は、「毎朝7時に、その日の天気予報をLINE経由で送信するBotを作成したい。」でした。

毎朝7時はトリガーで実装するとして、「その日の天気予報をLINE経由で送信する」部分を関数化しようとしました。

もちろん「毎朝7時に、その日の天気予報をLINE経由で送信するBotを作成したい。」とお題をそのままテキストでベタ打ちして変換しても、それなりのコードが返ってきます。

↓↓↓試しに出力させてみました↓↓↓

/**
 * 毎朝7時に、その日の天気予報をLINE経由で送信するBotを作成する
 * LINE Messaging APIとOpenWeatherMap APIを使用する
 * @return {void}
 */
function sendDailyWeatherForecast() {
  // OpenWeatherMap APIキー
  const weatherApiKey = 'YOUR_OPENWEATHERMAP_API_KEY';
  
  // LINE Messaging APIのトークン
  const lineToken = 'YOUR_LINE_TOKEN';

  // 天気予報を取得する都市ID(例:東京)
  const cityId = '1850147'; // 東京の都市ID

  // OpenWeatherMap APIのエンドポイント
  const apiEndpoint = `https://api.openweathermap.org/data/2.5/weather?id=${cityId}&appid=${weatherApiKey}&units=metric&lang=ja`;

  // 天気APIへのリクエストを送信
  const response = UrlFetchApp.fetch(apiEndpoint);
  const weatherData = JSON.parse(response.getContentText());

  // 天気情報を整形
  const weatherDescription = weatherData.weather[0].description;
  const temperature = weatherData.main.temp;
  const weatherMessage = `今日の天気: ${weatherDescription}\n気温: ${temperature}°C`;

  // LINE APIのエンドポイント
  const lineEndpoint = 'https://api.line.me/v2/bot/message/broadcast';

  // LINEメッセージのペイロード
  const payload = {
    messages: [
      {
        type: 'text',
        text: weatherMessage
      }
    ]
  };

  // LINE APIリクエスト用のオプション
  const options = {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${lineToken}`
    },
    payload: JSON.stringify(payload)
  };

  // LINE APIへのリクエストを送信
  UrlFetchApp.fetch(lineEndpoint, options);

  console.log('天気予報がLINEに送信されました');
}

/**
 * 時間ベースのトリガーを設定する関数
 * @return {void}
 */
function createTimeTrigger() {
  // 既存のトリガーを削除
  const triggers = ScriptApp.getProjectTriggers();
  triggers.forEach(trigger => {
    if (trigger.getHandlerFunction() === 'sendDailyWeatherForecast') {
      ScriptApp.deleteTrigger(trigger);
    }
  });

  // 毎朝7時に実行されるトリガーを作成
  ScriptApp.newTrigger('sendDailyWeatherForecast')
    .timeBased()
    .atHour(7)
    .everyDays(1)
    .create();

  console.log('時間ベースのトリガーが作成されました');
}

ただ、上記のスクリプトだとLINE Messaging APIOpenWeatherMap APIといったちょっと設定が面倒なAPIを使わないといけません。

今回は、もっとシンプルな実装で良かったので、GASのエディタに以下のようにコードを途中まで記載しました。

/**
 * 天気予報をLINEで通知する関数
 */

function weatherForecastsLINEnotify() {
  // 大阪エリアのコード
  const areaCode = '270000';
  // 気象庁の天気予報データのURL
  const urlWeather = `https://www.jma.go.jp/bosai/forecast/data/forecast/${areaCode}.json`;
}

ここで抑えるべきポイントは以下の3つです。

  1. ドキュメンテーションコメントでどんな処理をする関数かを書いておく

  2. 関数名でどんな機能を持っているかわかるようにする

  3. 処理で利用したい定数・変数の一部を宣言しておく

  1. は天気予報をLINEで通知する関数

  2. はweatherForecastsLINEnotify

  3. は大阪エリアのコードや気象庁の天気予報データのURLの指定

です。

こうすることでAIにコンテクストを与えて、ある程度出力されるスクリプトを誘導します。

今回は、天気予報関連のAPIは使わずにUrl Fetchサービスで取得できる気象庁の天気予報データを活用するように誘導しました。

また関数名にLINEnotifyと記載することで、LINE Messaging APIではなく通知のみで手軽なLINE Notify APIに誘導しています。

LINE Notifyに関しては以下の記事参照。

意外とちゃんと動くコードが出てきた

そして、件のXに投稿した動画です。

出力させたコードをテストしたところ、意外とちゃんと動きました。

/**
 * 天気予報をLINEで通知する関数
 * @return {void}
 */
function weatherForecastsLINEnotify() {
  // 大阪エリアのコード
  const areaCode = '270000';
  // 気象庁の天気予報データのURL
  const urlWeather = `https://www.jma.go.jp/bosai/forecast/data/forecast/${areaCode}.json`;

  // HTTPリクエストを送信し、レスポンスを取得
  const response = UrlFetchApp.fetch(urlWeather);
  // レスポンスのJSONテキストをパース
  const objJson = JSON.parse(response.getContentText());

  // 必要なデータを取り出す
  const aryForecasts = objJson[0].timeSeries[0].areas[0].weathers;
  const dateForecast = objJson[0].reportDatetime;

  // LINE Notifyのアクセストークン
  const accessToken = 'YOUR_LINE_NOTIFY_ACCESS_TOKEN_HERE';
  // LINEへの通知メッセージ
  const message = `【天気予報】
  発表日時: ${dateForecast}
  今日: ${aryForecasts[0]}
  明日: ${aryForecasts[1]}`;

  // LINE Notify APIへのリクエスト設定
  const options = {
    method: 'post',
    headers: {
      'Authorization': `Bearer ${accessToken}`
    },
    payload: {
      message: message
    }
  };

  // LINE Notify APIへリクエストを送信
  UrlFetchApp.fetch('https://notify-api.line.me/api/notify', options);
  console.log('天気予報をLINEに通知しました');
}

レスポンスで返ってくるJSONの解析もやってくれているので、とりあえず天気予報を通知するbotの形にはなっています。

BetterTouchToolとChatGPTの連携は、可能性無限大

ショートカットキー1発でChatGPTに処理をさせることができるBetterTouchToolってすごくないですか?

個人的に最大のメリットだと感じるのは、チャット形式のUI画面に入力したり、出力されたものをコピペする手間が無くなることです。

現時点(2024年9月)では、GASの標準エディタにはAIによる支援機能は装備されていませんが、BetterTouchToolを使うことで、標準エディタ上で直接、AI支援を受けつつコードを書くことができます。

AI支援を受けつつGASを書く方法としては、CursorやVisual Studio Code(+ GitHub Copilot)とclaspを使ってローカルでコーディングして…という手順もありますが、BetterTouchToolを使ったほうが初期設定が簡単かなと思います。

実は、今回の活用方法のアイデアは、Cursorでの他言語のコーディングをしていてインスピレーションを得たものです。

プロンプトをもう少し工夫して、使い分けてあげれば、よりCursorライクにGASの標準エディタ上でAI支援コーディングを得られると思います。

GASコーディングガイドライン - BetterTouchTool版

ここからはコミュニティメンバー向けのおまけです。

出力されるGASの精度を上げるためにコーディングガイドラインが有効と書きましたが、具体的にどんなガイドをプロンプトに含めれば良いのでしょうか?

ここから先は

852字
この記事のみ ¥ 100
期間限定!Amazon Payで支払うと抽選で
Amazonギフトカード5,000円分が当たる

この記事が気に入ったらチップで応援してみませんか?