見出し画像

[kintone] プロンプト1発で仕事おしまい! をGPTsで試したらあと一歩およびませんでした

こんにちは、キン担ラボの本橋です。

相棒のJSメンタ郎と本橋です

先日は5往復の会話でJSカスタマイズを作りました。今回はこれを『1回のプロンプト』でJSメンタ郎くんに書かせられないか挑戦してみました。

結論から言うと散々モガいてみましたがほんのあと一歩だけ!及びませんでした。

ひとまず出来上がったプロンプトをご覧ください。もはや出力されたコードよりも長い。

JSメンタ郎と客の会話

本橋: 「kintoneのアプリケーションで、編集画面が表示された時に特定のフィールド(例えば「テンプレート」と「リザルト」)に対するカスタマイズを行うJavaScriptコードを作成してください。このコードは、他のフィールドの内容が変更された際に「テンプレート」フィールドのテキストに含まれる下記のプレースホルダを、その他のフィールドの値で置換して「リザルト」フィールドに反映させる機能を持っている必要があります。

%%フィールドコード%%

また、APIを使用してフィールドの一覧を取得し、特定のフィールドを除外する処理も含めてください。」

この指示に基づいて、以下のポイントに注意しながらコードを作成します:

kintoneのイベントハンドラ(kintone.events.on)を使用して、編集画面の表示時のイベントをキャッチする。
kintone REST APIの '/k/v1/app/form/fields' を使用して、アプリケーションのフィールド一覧を取得する。
特定のフィールド(この例では「テンプレート」と「リザルト」)を処理から除外する。
各フィールドの変更イベント 'app.record.edit.change.フィールドコード' をkintone.events.on を使ってハンドラを定義して、テンプレートテキストの置換とリザルトフィールドの更新を行う処理を設定する。

JSメンタ郎:このタスクのために、JavaScriptコードを作成する際には、以下のステップに従います:

  1. 編集画面表示時のイベントハンドリング: kintoneのイベントハンドラを使用して編集画面が表示された時にイベントをキャッチします。

  2. APIを使用してフィールド一覧の取得: kintone REST APIを使用して、アプリケーションのフィールド一覧を取得します。

  3. 特定のフィールドの処理除外: 「テンプレート」と「リザルト」フィールドは処理から除外します。

  4. 各フィールドの変更イベントのハンドリング: 各フィールドの変更イベントに対してリスナーを設定し、テンプレートテキストの置換とリザルトフィールドの更新を行います。

以下は、これらの要件を満たすための基本的なコードの例です:

(function () {
    "use strict";

    // 編集画面表示時のイベントハンドラ
    kintone.events.on("app.record.edit.show", function (event) {
        // APIを使用してフィールド一覧を取得
        var appFieldsUrl =
            "/k/v1/app/form/fields.json?app=" + kintone.app.getId();
        kintone.api(
            kintone.api.url(appFieldsUrl, true),
            "GET",
            {},
            function (response) {
                // 除外するフィールド
                var excludeFields = ["テンプレート", "リザルト"];

                // 除外するフィールド以外のフィールドコードを取得
                var fieldCodes = Object.keys(response.properties).filter(
                    function (code) {
                        return !excludeFields.includes(code);
                    }
                );

                // 各フィールドの変更イベントに対するハンドラを設定
                fieldCodes.forEach(function (code) {
                    var changeEvent = "app.record.edit.change." + code;
                    kintone.events.on(changeEvent, function (e) {
                        // テンプレートテキストの置換
                        var templateText = e.record["テンプレート"].value;
                        var newValue = e.record[code].value;
                        var newResult = templateText.replace(
                            new RegExp("%%" + code + "%%", "g"),
                            newValue
                        );

                        // リザルトフィールドの更新
                        e.record["リザルト"].value = newResult;
                        return e;
                    });
                });
            }
        );
    });
})();

このコードは、編集画面が表示された際に、フィールド一覧を取得し、特定のフィールド以外で変更があった場合に、テンプレートテキストのプレースホルダをそのフィールドの値で置換し、リザルトフィールドに反映させます。また、例外処理はこのコードには含まれていませんが、実際のプロジェクトではAPI呼び出しやイベントハンドラ内での処理に対して適切なエラーハンドリングを行うことが重要です。

本橋:動かないんだなぁ

一箇所だけ修正したら動いた

実に惜しい、kintone APIの呼び出し方だけうまくいきませんでした。fields.jsonの呼び出しで、GETパラメータの与え方を間違えてしまっています。それだけ直せば動きました!

// ✕ この呼び出し方だと間違ったURLで呼び出してしまう
var appFieldsUrl = "/k/v1/app/form/fields.json?app=" + kintone.app.getId();
kintone.api( kintone.api.url(appFieldsUrl, true), "GET", {}, function (response) {...} )

// ◯ アプリ番号はパラメータとして与える
var appFieldsUrl = "/k/v1/app/form/fields.json";
kintone.api( kintone.api.url(appFieldsUrl, true), "GET", { app: kintone.app.getId() }, function (response) {...} )

この1点を修正したら動作しました。以下のコードをJSファイルとしてkintoneに登録すれば動作します。

(function () {
    "use strict";

    // 編集画面表示時のイベントハンドラ
    kintone.events.on("app.record.edit.show", function (event) {
        // APIを使用してフィールド一覧を取得
        var appFieldsUrl = "/k/v1/app/form/fields.json";
        kintone.api(
            kintone.api.url(appFieldsUrl, true),
            "GET",
            { app: kintone.app.getId() },
            function (response) {
                // 除外するフィールド
                var excludeFields = ["テンプレート", "リザルト"];

                // 除外するフィールド以外のフィールドコードを取得
                var fieldCodes = Object.keys(response.properties).filter(
                    function (code) {
                        return !excludeFields.includes(code);
                    }
                );

                // 各フィールドの変更イベントに対するハンドラを設定
                fieldCodes.forEach(function (code) {
                    var changeEvent = "app.record.edit.change." + code;
                    kintone.events.on(changeEvent, function (e) {
                        // テンプレートテキストの置換
                        var templateText = e.record["テンプレート"].value;
                        var newValue = e.record[code].value;
                        var newResult = templateText.replace(
                            new RegExp("%%" + code + "%%", "g"),
                            newValue
                        );

                        // リザルトフィールドの更新
                        e.record["リザルト"].value = newResult;
                        return e;
                    });
                });
            }
        );
    });
})();

コード自体はとても読みやすくまとまっていると思います。改善するのであれば、テンプレートとリザルトのフィールドコードを定数化して外に出しておく、くらいかな。(varではなくconstに、とかもあると思います)

挑戦してみてわかったこと

API呼び出しのパラメータ指定方法という詳細な部分で失敗していました。これはGPT側の理解が進んでいけば解消する部分かと思います。

あるいは現時点であれば、API呼び出し部分は関数として呼び出せる前提で切り出しておいて、その関数を呼び出してね、とプロンプトしてあげるというのも一つの回答になりそうです。

結論として、ある程度複雑なものを期待するのは止めにしておきましょう。一発で完成させようとするのはチャレンジとしては楽しいですが、会話形式で少しずつ改善したほうが遥かに楽です。

しかも今回は無理やり一発で書かせようと試みたせいでChatGPTの利用制限に引っかかりまくり、「2時間待ってから再開してね」と何度も言われてしまいました。

会話しながら進めれば前回の記事の通り「5往復」の会話で仕上げることができています。

そんなJSメンタ郎とのペアプロミングをみなさんもぜひ楽しんでみてください!

ChatGPT - JSメンタ郎 (openai.com)

いいなと思ったら応援しよう!