ChatGPTとJavaScriptカスタマイズを書くコツと読むコツ

こんにちは、[キン担ラボ](https://www.monosus.co.jp/service/kintanlab/)の本橋です。

この記事は、[kintoneアドベントカレンダー10日目](https://qiita.com/advent-calendar/2023/kintone)の記事です。

OpenAIのGPTsでJSメンタ郎というAIを公開しています。JSメンタ郎はkintone用のJavaScriptカスタマイズに特化したGPTsです。

<a href="https://chat.openai.com/g/g-aUbXfCMqn-jsmentalang">
<img width="240px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/5310752a-7934-b58a-c6a9-223adf32577e.png"/>
<br/>JSメンタ郎
</a>

そのままのChatGPTに『kintoneのJSカスタマイズをペアプロしましょう』と話しかけてスタートすることもできます。でも回数を重ねていくと毎回発生する定型句みたいなやり取りが若干面倒になってきてしまいました。

GPTs化しておくことで、kintoneのJSカスタマイズをする、という前提が共有済みのスタート地点からペアプロを始めることができます。


# JSメンタ郎との対話の始め方

ChatGPT plusをご契約の方はアクセスして、こんにちは！と話しかけてみて下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/81ef6ce4-fcbb-e64b-8ae1-1ca8d4bf043d.png)

文字数をカウントするカスタマイズを作りたい、と問いかけてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/386184ea-449a-05a7-47db-fa7f10c22178.png)

コードを書いて下さい、とお願いしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/c8a86342-3d47-23b0-48fa-a9e58476fba1.png)

```javascript
// ※このコードは動きません
(function() {
    "use strict";

    kintone.events.on('app.record.create.show', function(event) {
        var record = event.record;

        // テキスト入力フィールドのフィールドコード
        var inputFieldCode = '入力フィールドのフィールドコード';

        // 文字数を表示するフィールドのフィールドコード
        var countFieldCode = 'カウントフィールドのフィールドコード';

        var inputField = kintone.app.record.getFieldElement(inputFieldCode);

        // 入力フィールドの変更を監視
        inputField.addEventListener('input', function(e) {
            var textLength = e.target.value.length;
            record[countFieldCode].value = textLength;
            kintone.app.record.setFieldShown(countFieldCode, true);
            kintone.app.record.set(record);
        });

        return event;
    });
})();

```

このコードはこのままでは動きません。addEventListenerではなく、kintone.events.onで、app.record.create.changeイベントをハンドルするように書き換えてやれば動きそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/33d3df0f-8962-7414-4d6a-2e849424c224.png)

JSメンタ郎が修正したバージョンが以下のものです。

```javascript
// ※動きます！

(function () {
    "use strict";

    // テキスト入力フィールドのフィールドコード
    var inputFieldCode = "入力フィールドのフィールドコード";

    // 文字数を表示するフィールドのフィールドコード
    var countFieldCode = "カウントフィールドのフィールドコード";

    kintone.events.on(
        "app.record.create.change." + inputFieldCode,
        function (event) {
            var record = event.record;
            var inputValue = record[inputFieldCode].value;

            // 入力されたテキストの文字数をカウント
            var textLength = inputValue.length;
            record[countFieldCode].value = textLength;

            return event;
        }
    );
})();

```

やった！　動いた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/a6b69842-39ee-19f9-44ff-d9f17cf85642.png)

以上がJSカスタマイズでAIコーディングする一連の流れです。

ついつい直接コードを書き換えたくなりますが、プロンプトで対話しながら修正していくプログラミングもまた一味違った面白味があります。

## AIコーディングを始めるトレーニングとしてのJSメンタ郎

『AIといったって、どうせそんなには書いてくれないでしょ？』

当初はそんな意識がどうしても先に立ってしまっていました。ちょっとしたJSのコードスニペットやテンプレートを書くために呼び出して、コピペして、おしまい。そんな使い方をしていた程度でした。

そんな僕もJSメンタ郎と対話を繰り返していると理解が深まるもの。

なるほどこうやってAIに依頼すればいいのね。じゃあこれは？　こっちはどう？　と試しているうちに気づいたらエディタもVSCodeからCursorに乗り換え、最近はあたりまえにAIコーディングをするようになりました。

AIを導入することでコーディングの効率は段違いに良くなります。もしまだお使いでない方はJSメンタ郎との対話からどうぞ入ってみて下さい。飛ぶぞ。

## 前置きが長くなりました

この記事ではそんな短い経験の中で拾い集めたAIコーディングのコツをまとめてみたいと思います。JSメンタ郎にkintone用のJSカスタマイズを書かせる、という視点です。「こんなコツもあるよ！」と反応していただけると嬉しいです。

JSメンタ郎と対話していても、ChatGPT自体が日々少しずつ変化をしている事がわかります。ここにまとめたコツが現時点のものであり、将来的な変化によってどう転んでいくかは僕にはわかりません。

いつまで使えるノウハウか分からない、というあたりを心にピン留めいただきつつ、どうぞお付き合い下さい。

# AIにコードを書かせるコツ

やっと本題です。

kintoneのJSカスタマイズに特有の実装課題について列挙してみました。

## 実行画面の指定

僕の場合、kintone JavaScript APIのイベントはレコード一覧、レコード詳細、レコード追加、レコード編集という4つの画面を使うことが多いです。

他にもポータル画面や印刷画面、スペース画面などでJSカスタマイズを実行するためのイベントが用意されています。

https://cybozu.dev/ja/kintone/docs/js-api/

まずはどの画面で実行するJSカスタマイズか、とAIに伝えましょう。適切なハンドラから実行できるようになります。

> 例: 一覧画面の上部にボタンを配置するカスタマイズを作りたいです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/48a5a6de-3252-41fa-08dd-0b289100f2f2.png)

省略しますが、その一言だけでテンプレートのコードを書いてくれました。


## 入力フィールドと出力フィールドを指定

フィールドの編集を伴う場合、レコード追加画面とレコード編集画面のどちらかを使うことになります。その際に、入出力フィールドのフィールドコードを指定してください。

> 例: フィールドコード「input」を入力として、フィールドコード「result」を出力としてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/7fc327cb-9a66-594c-cad0-14e57aa4a66d.png)

フィールドコードを無指定で進めると先ほどの例のように『入力フィールドのフィールドコード』『カウントフィールドのフィールドコード』みたいなコメントになってしまい、毎回書き換える手間が増えます。

一度プロンプトしてしまえば済むので最初の方で指定してあげましょう。


## メイン処理を実行するイベント

どんなときにメイン処理を実行したいのか伝えてあげましょう。例えば入力フィールドを編集したタイミングなのか、あるいはその他の特定のフィールドなのか、保存しようとしたときなのか、保存したあとなのか。

こちらもJavaScript APIのイベント処理を使うことになります。適切なイベントを伝えることで見通しの良いコードを書いてくれるかと思います。

> 例: ボタンを押したタイミングで、入力フィールドの値をダイアログ表示させてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/1a8924ea-5018-bc2f-7681-02b24dea4a13.png)


## メイン処理のロジック

上のイベントを受けてどんな処理を実行したいか明確にします。例えば「入力フィールドが閏年だったときに出力フィールドにチェックを入れる」みたいな具合です。

> 例: ダイアログには、入力フィールドを日付として処理して、1月1日からの経過した週数を表示して下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/d5de13ad-ed2f-8714-47eb-74de976b78b7.png)

## ボタンの装飾とラベル

必須ではないのですが、何も言わないとそっけない標準スタイルで"submit"ボタンとかを配置されがちです。いい感じにデザインして下さい、とかでも良いので一言添えてあげて下さい。割といい感じにしてくれます。

> 例: ボタンはいい感じにデザインして下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13915/a4eede1f-eb9f-08cc-54a8-e44d2df91a43.png)

## その他のコツであなたの相棒を育てよう！

他にもAIコーディングをしていくと『なんだか毎回同じプロンプトしているなぁ』みたいな体験が出てきます。

その際はぜひ、あなた専用のGPTsを作ってそのコツを教えてあげてください。きっと良い相棒に育ってくれることでしょう。


# AIコードを読むコツ

正しく動作するコードが出てくることは稀です。だいたいは何度か「こんなエラーが出て動かないんだけど...」と会話を繰り返してブラッシュアップすることになります。

そんなとき、間違えられやすいポイントをあらかじめ抑えておけると素早い問題解決に繋がります。

## 正しいイベントに割り当てられているか

さきほどもありましたね。

kintoneのAPIの話ですが、編集画面を対象としたいときは、編集画面と新規作成画面の両方のイベントに割り当てる必要があります。どちらか片方だけ指定のケースが多いです。

そんなときはeditとcreateの両方のイベントを割当ててくれているか確認しましょう。

- app.record.edit.show
- app.record.create.show

プロンプトで『編集と新規作成の両方で』と指定しておいても、イベントについてはどっちか片方になりがちです。なんででしょうね。

## REST APIをでっち上げていないか

一見動きそうなのになんだか動きがおかしいな、と思っていたらREST APIのエンドポイントが見慣れぬパスになっていたことがありました。

> /k/v1/app/form/getAllFields.json

/fields.json を使ってください、と指定していてもこんなことをする場合もあります。ご注意ください。

## 呼び出しパラメータは適切か

REST APIをGETで呼び出す際にパラメータをエンドポイントに繋げてくることがありました。

> /k/v1/app/form/fields.json?app=999

これも一見動きそうな気がするんですが、以下のような書き方をされたのでしばらく考え込んでいました。

```javascript
const url = kintone.api.url('/k/v1/app/form/fields.json?app=999', false)
kintone.api(url, 'GET', body, (resp)=>{
    ...
})
```

このまま実行するとJavaScript APIの挙動によって、エンドポイントが/k/v1/app/form/fields.json?app=999.json みたいなパスになります。そのため正しく動作しません。

```javascript
const params = {
  app: 4,
  fields: ['recordId']
};
const url = kintone.api.urlForGet('/k/v1/app/form/fields.json', params, false)
kintone.api(url, 'GET', body, (resp)=>{
    ...
})
```

と、パラメータはパラメータで指定してあげて下さい。


# まとめ

以上、JSメンタ郎にコードを書かせるコツと、書いたコードを読む時のポイントでした。些細なことですが、今のところのAIコーディングのデバッグで頻出するところを集めてみました。

大きくまとめると、一般的とは言えないkintoneに特有のAPIを呼び出す部分なんかはChatGPTも間違いやすいです。他のAPIと確率的にごっちゃになるのでしょう。

JavaScript全般に共通した処理であればとてもきれいなコードで書いてくれます。そういった部分で頼りにしましょう。


# おまけ: Live Server使うと楽です。

JSカスタマイズを書くときはこちらの記事を参考にlocalhostから直接カスタマイズを読み込めるようにしておくと便利です。


Visual Studio Code Live Server Extensionを使ってkintoneカスタマイズ開発効率をあげよう！ – cybozu developer network

https://cybozudev.zendesk.com/hc/ja/articles/360026502091-Visual-Studio-Code-Live-Server-Extension%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6kintone%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E9%96%8B%E7%99%BA%E5%8A%B9%E7%8E%87%E3%82%92%E3%81%82%E3%81%92%E3%82%88%E3%81%86-

# JSメンタ郎と一緒に良きJSカスタマイズライフを！

最後までお付き合いいただきありがとうございました。

https://www.monosus.co.jp/service/kintanlab/

キン担ラボではChatGPTやGPTsを活用したプログラミングのメンタリングも提供しています。（AIも使いますが、人間のプログラマーですよ）

ご興味をお持ちいただけましたらぜひお声がけ下さい❗