タグ: GAS

  • 日本語で魔法のようにGAS開発がはかどる「GASSISTANT」

    2024年10月7日、日本語で魔法のようにGASコーディングがはかどる「GASSISTANT」(ガシスタント)なるツールがリリースされました。

    https://gassistant.vercel.app

    開発したのは日本人の横田大伍さん(@daigo_3_8)。

    https://note.com/chaen_channel/n/n0be3b13a0e04

    これはよさそう、と思ったのですが、一方で「実際にお役に立ちそうなGASのユーザー、特にローコードと初心者の間を行ったりきたりするようなGASコーディングですら難しい人にはちょっととっつきづらそう…」、そして、逆に「ClaspのようなTypeScriptでGASを書いている人」にも「とっつきづらそう…」という印象もありました。これは試さねば。

    ★このあたりは開発者の横田さんよりメッセージを頂いております(文末)

    なおAICU media編集部やAIDX Labには しらいはかせをはじめとして10年来のGAS開発者がいます。普段からClaudeのArtifactsや、vercel「v0」のような対話型のコード支援環境も使っていますが、ストレスもあります。ブラウザのタブをいったりきたりする必要がありますし、時々「全文を出力して」といったお願いをしないと、コードの差分に悩まされることも多々ありました。CursorやCopilotのようなコード補完だけでなく、GitHubのdiffを見ながら、相談しながらテスト環境を動かしてデプロイからテストまで実行していきます。しかもこの方法ではコードが視界を通過しているだけで、頭の中で判断として残りません。AIがアシストしているわりに、危険なコードが大量に生成される可能性もあります。

    GASSISTANTはそんな悩みを解決してくれそうです。AIがコードの提案からデバッグまでを自動で行ってくれるので、コーディングが驚くほどスムーズになることを確認できました。

    実際に使ってみた!

    まず、個人のGmailアカウントを使って、テスト用にひとつGoogle Spreadsheetを作りましょう。実験用にGASSISTANTというスプレッドシートを作成して、拡張機能→Apps Scriptでエディタを開きました。

    画像

    GASエディタのURLを設定する準備をします。URLの赤い部分がスクリプトIDですが、URLそのものをコピーして貼り付けると、GASSISTANTのエディタ側でIDをリンクしてくれますので、これで準備OKということになります。

    画像

    GASSISTANTにGoogleアカウントでログインし、GASSISTANT のプライバシー ポリシー利用規約をご確認ください。

    なお、初回はチュートリアルが起動しますので、いったんスキップするか終わらせるかしてみてからでなければ設定に入れません。軽くチュートリアルの内容を紹介します。

    画像

    右下のチャット窓に相談をすると解説とともにGASのコードが生成されるようです。

    画像

    左側のエディタ画面に提案が表示されます。
    全て反映するか、断るかを個々のコードブロックで選べるようです。
    GitHubでのDiffよりも便利かもしれません!

    画像

    コードの提案を反映させたら「保存してデプロイ」を押します。数秒待つと保存が終わります。

    画像

    「実行して自動修正」を押すと、右のチャット履歴にテストデータが投げられ、実行されている様子が見えます。

    画像

    右のチャット履歴にはコードの「反映」や「コピー」、そして説明やテストパラメータのJSONが表示されます。

    画像

    ※チュートリアルとしては、ここで「反映」ボタンを押すと進みます。
    (チュートリアルから抜けられなくて慌てました)
    追記:このあたりは早速改善が入ったようです!

    画像

    さて、丁寧なチュートリアルは終わりです。
    用意した「GASSISTANT」スプレッドシートのエディタからURLを貼り付けましょう。

    画像

    ちなみにチュートリアルが終わった時点で300クレジットが279クレジットになっていました(汗)

    アップグレードすると月額2980円だそうです。クレジットが増えるのか、使い放題になるのかは、まだよくわかりません(問い合わせしました!文末に回答をまとめています)。

    画像

    Slack通知機能を追加してみた

    チュートリアルは「A列にメールアドレスの束があるのでメールを送信して」というお願いでコードが生成されていました。
    追加のリクエストとして、以下のようなリクエストを右下のチャット窓に打ち込んでみました。

    実行開始時と終了時にSlack通知。WebHookのエンドポイントはScriptPropertiyの SLACK_WEBHOOK_URL で指定します。

    GASSISTANTからの返答は以下の通りでした。

    • Slackに通知を送信するために、Google Apps ScriptにSlackのWebhookを使用するコードを追加しましょう。以下のコードでは、メール送信の開始時と終了時にSlack通知を送信するようにしています。
    • コードブロック
    • 説明: `sendSlackNotification`関数を追加し、SlackのWebhook URLを使ってメッセージを送信します。`PropertiesService.getScriptProperties().getProperty(‘SLACK_WEBHOOK_URL’)`でWebhook URLを取得します。事前にScript PropertiesにこのURLを設定しておく必要があります。メール送信の開始時と終了時にそれぞれSlackに通知を送信します。 このコードを使う前に、Script Propertiesに`SLACK_WEBHOOK_URL`を設定してください。これにより、指定されたSlackチャンネルに通知が送信されます。

    以下が生成されたコードです。

    function sendEmails() {
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const lastRow = sheet.getLastRow();
      const emailColumn = 1; // A列
    
      // メールの件名と本文を設定
      const subject = "件名をここに入力";
      const body = "本文をここに入力";
    
      // Slack通知: メール送信開始
      sendSlackNotification("メール送信を開始します。");
    
      for (let i = 1; i <= lastRow; i++) {
        const emailAddress = sheet.getRange(i, emailColumn).getValue();
        
        if (emailAddress) {
          try {
            MailApp.sendEmail(emailAddress, subject, body);
            logEmailStatus(emailAddress, "送信成功");
          } catch (error) {
            logEmailStatus(emailAddress, `送信失敗: ${error.message}`);
          }
        }
      }
    
      // Slack通知: メール送信終了
      sendSlackNotification("メール送信が完了しました。");
    }
    
    function logEmailStatus(email, status) {
      const logSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("AI Log");
      if (!logSheet) {
        // "AI Log"シートが存在しない場合は作成
        logSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("AI Log");
      }
      logSheet.appendRow([new Date(), email, status]);
    }
    
    function sendSlackNotification(message) {
      const webhookUrl = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK_URL');
      if (!webhookUrl) {
        Logger.log("Slack Webhook URLが設定されていません。");
        return;
      }
    
      const payload = JSON.stringify({text: message});
      const options = {
        method: 'post',
        contentType: 'application/json',
        payload: payload
      };
    
      UrlFetchApp.fetch(webhookUrl, options);
    }

    コードの差分に「Accept」「Reject」が表示されています。

    画像

    どれも大丈夫そうなコードですが、いちおう一つづつ確認して「Accept」してもいいですし、画面上にある「すべて適用」を押してもいいと思います。日本語UIは新鮮ですね!

    「保存してデプロイ」を押してみます。確認のために本家GASのコードエディタの方をリロードしてみると、反映されているようです。

    画像

    なお、従来通りのGASエディタでのコード修正も問題なくできそうです。修正して保存したあとはGASSISTANT側の「同期」で現在のコードを吸い上げることができます。
    ちょうど 「Google Apps Script GitHub アシスタント」に動作が近いと思いました。

    https://chromewebstore.google.com/detail/google-apps-script-github/lfjcgcmkmjjlieihflfhjopckgpelofo?hl=ja

    さて、スクリプトプロパティにSlackのWebHookのURLを指定する機能はなさそうなのでGASエディタ側で設定します。

    画像

    「プロジェクトの設定」から「スクリプトプロパティ」で自分が決めた「SLACK_WEBHOOK_URL」を設定します。このURLはSlack上でIncoming Webhookを設定することで取得できます。

    画像

    ここでは別のプロジェクトの開発で使ったボットのIncoming Webhookを再利用しています。

    GASSISTANTに戻って「実行して自動修正」を実行します。するとアラートが出て実行が止まりました。

    画像

    外部(Slack)にアクセスする処理を加えたので当然、新たな権限承認が必要になったようです。GASエディタに行って権限を確認してきます。
    デバッグ実行を行って、権限承認ダイアログから、

    画像

    左下の「無題のプロジェクト(安全ではないページ)に移動」を選んで権限の許可を実施します。

    画像

    これでA列にメールアドレスを書いておけば、メールも無事に送信できるようになります。誤爆に注意しましょうね。
    このへんで終わっておけばいいのですが、さらに「実行して自動修正」を押すと、なんだか更に改善したいようです。

    エラーメッセージから、`doGet`関数が見つからないことが原因でエラーが発生していることがわかります。このため、`doGet`関数を追加して、GETリクエストからパラメータを受け取り、`sendEmails`関数を呼び出すようにします。 以下は修正されたコードです。

    画像

    最終的にはdoGet(e)関数から sendEmails(subject, body)を呼ぶ形になりました。テストJSONを受け取るにはこのほうが良いかもしれませんね。

    デバッグ結果を見ると、GETリクエストを使用してメールが正常に送信され、スプレッドシートの「AI Log」シートに送信結果が記録されています。すべてのメールが「送信成功」となっており、特に問題は見られません。 現時点でコードに改善が必要な箇所はありません。メール送信機能が期待通りに動作していることが確認できました。このまま引き続きご利用いただけます。 もし追加で何か特定の改善点や機能追加のリクエストがあればお知らせください。

    function doGet(e) {
      const subject = e.parameter.subject || "件名をここに入力";
      const body = e.parameter.body || "本文をここに入力";
      
      sendEmails(subject, body);
      
      return ContentService.createTextOutput("メール送信が完了しました。");
    }
    
    function sendEmails(subject, body) {
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const lastRow = sheet.getLastRow();
      const emailColumn = 1; // A列
    
      // Slack通知: メール送信開始
      sendSlackNotification("メール送信を開始します。");
    
      for (let i = 1; i <= lastRow; i++) {
        const emailAddress = sheet.getRange(i, emailColumn).getValue();
        
        if (emailAddress) {
          try {
            MailApp.sendEmail(emailAddress, subject, body);
            logEmailStatus(emailAddress, "送信成功");
          } catch (error) {
            logEmailStatus(emailAddress, `送信失敗: ${error.message}`);
          }
        }
      }
    
      // Slack通知: メール送信終了
      sendSlackNotification("メール送信が完了しました。");
    }
    
    function logEmailStatus(email, status) {
      const logSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("AI Log");
      if (!logSheet) {
        // "AI Log"シートが存在しない場合は作成
        logSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet("AI Log");
      }
      logSheet.appendRow([new Date(), email, status]);
    }
    
    function sendSlackNotification(message) {
      const webhookUrl = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK_URL');
      if (!webhookUrl) {
        Logger.log("Slack Webhook URLが設定されていません。");
        return;
      }
    
      const payload = JSON.stringify({text: message});
      const options = {
        method: 'post',
        contentType: 'application/json',
        payload: payload
      };
    
      UrlFetchApp.fetch(webhookUrl, options);
    }

    さらに追加機能を実装していく…!

    この時点で「残りクレジット: 119」となりました。まだまだ無料で遊べそうです。さらなる改造をしてみましょう。

    ・B列には送信相手のフルネーム、C列には送りたいメッセージの本文が入ります。
    ・D列には送信日時を入れてください。
    ・Webhookには送信者名、メールアドレス、送信内容を1件毎通知してください。
    ・全体の処理の件数と所要時間を計測してレポートしてください。
    ・いちど送信した相手には2週間以上期間をあけてから送信してください。
    ・毎週火曜日朝9時に実行するトリガーを設定してください。

    こんな感じに実行できました!メールも届いています!

    【送信履歴が付いたスプレッドシート】

    画像

    【Slackでの通知】

    画像

    気になった点

    基本的にはよくできていると思いました!
    ・クレジットが何なのか、月額プランが何なのかよくわからなかった(わかれば課金したい気持ちも出てきます!)
    ・実行したい関数が何なのか、軽く指定できるといいのかもしれないです。この例でもdoGetに落ち着くのはいいことかなと思いますが、一方でトリガー設定は実行されていませんでした。実行しようとするとGASエディタからマニュアル操作になるし、権限承認ダイアログもあるのでこれでいいのかもしれません。

    画像

    ・改善が終わらない。
     「実行して自動修正」というボタンの都合上かもしれないのですが、方向感なく改善を続けてしまいがちです。コードを評価したり「これで完成です」といってGitPushしたりする機能があるといいのかも。

    ・一度許可したシートへのアクセスを解除する方法がわからない。
     このままだとコードが固定できないので本番運用には問題があるかもしれません。データを外部に漏らさないためにもシートへのアクセスを解除したいところです。もしくは生成したコードを本番用に移植するといった作業は必要かもしれませんね。

    おまけ「GASSISTANT Opener」

    同じ作者さんが開発したChrome拡張です。
    GASエディタを開くとGASSISTANTを開けと言われ続けるようになります。

    https://chromewebstore.google.com/detail/gassistant-opener/nhkidgdaohjomakblaafjblkphnlmije

    GASエディターを開いたらGASSISTANTを開く提案をします

    GASSISTANT(https://gassistant.ai-zen.co.jp/)は初期設定が最小限に抑えられていますが、スクリプトID設定は手動で行う必要があります。 この拡張機能では、GASエディタからGASSISTANTを開きスクリプトIDを設定するフローが自動化されているため、ワンクリックでGASSISTANTを使い始めることができます。

    便利もありますが、不便になる要素もあるかも!?
    今後のアップデートに期待です。

    追記:開発者さんに聞いてみた!

    早速ご返信いただきました。

    料金について

    アップグレードすると即時3000クレジットに増加し、以降毎月3000クレジット付与されます。
    なおクレジットは追加ではなく、毎月3000にリセットされる形です。
    また、アップグレードするとAIの処理を自分のDify上でホストすることが可能になります。
    この設定をした場合、クレジットは消費されません(Dify側でAPI利用料がかかります)。

    セキュリティについて

    秘匿情報の取り扱い・Webアプリとして公開するなどの自明なリスクについては開発者に任せる想定でしたが、より丁寧な運用ガイドも用意すべきだと感じています。

    想定ユースケースについて

    想定ユースケースはclaspを使うほどでもない規模の開発です。

    本番運用でGASSISTANTを使う際は、セキュリティ面で言うとアップグレードしてDifyをセルフホスト、後日実装する実行可能APIでのデプロイをお勧めしております。

    セキュリティについて

    セキュリティについても引き続き注視し、安心してお使いいただけるようリスク低減に努めてまいります。

    GASSISTATN開発者

    まとめ

    GASSISTANTは、GASコーディングを劇的に効率化する革新的なツールです。GASコーディング初心者から中上級者まで、幅広い人におすすめできる感じがあります。いわゆる「ひとり情シス」みたいな方には強い味方ですね!

    アップグレードすると自分のDify上で使えるのはいいですね。
    機密情報の取り扱いや開発のワークフローなども理解して使えば、かなり革新的なAI活用ができそうです!

    注意

    GASSISTANT のプライバシー ポリシー利用規約をご確認ください。
    ※AICU編集部注:Google Apps Script経由で外部ツールを使って個人情報や売上情報を扱うような用途になる場合は特に注意して読んで理解してから試用することをおすすめします。内部で使用されているLLMの動作やログの収集内容、組織のポリシーによっては利用に適さない可能性もあります。(本稿に限らず)AIの使用による事故や過失の責任は使用者にあります。また積極的に開発者にお問い合わせしましょう。

    GASSISTANT – AIネイティブなGASエディタ
    https://gassistant.vercel.app
    https://gassistant.ai-zen.co.jp/

    【予告】「GASSISTANT」についてはAICU Magazine「 #サクッと先取り !クリエイティブAIツール」のコーナーでも扱っていきたいと思います!

    #サクッと先取り !クリエイティブAIツール #AICUmagazine
    #GASSISTANT  #GAS #GoogleAppsScript

    https://j.aicu.ai/MagV5

    https://j.aicu.ai/MagV4

    https://j.aicu.ai/MagV3

    https://j.aicu.ai/MagV2

    https://j.aicu.ai/MagV1

    Originally published at https://note.com on Oct 7, 2024.