ChatGPT を使って JSON レスポンスから ObjectScript クラスを生成する
REST レスポンスから IRIS データーベースに情報を保存する新しいプロジェクトがあります。 少なくとも 20 以上の個別の REST エンドポイントの情報を同期する必要があるため、それらのエンドポイントの結果を保存するために、ほぼ同じ数の ObjectScript クラスを作成しなければなりません。
ChatGPT を使って、それらのクラスを作成することはできますか? 答えは「できます」です。生成 AI を使って便利なものを作るのは初めてなので、素晴らしい機会だと思います。 スープを飲むキリンの写真を生成するのには飽きてきました…。
以下のようにして実現しました。
- エンドポイントをクエリするために、「curl」を使ってサンプルの JSON REST の呼び出し出力を取得する。
- ChatGPT にアクセスする(InterSystems は社員に会社全体で使用できるライセンスを提供しています)。
- ChatGPT と以下のように会話する。
以下のリクエストを「Message ChatGPT」プロンプトに入力しました。
私: 次の JSON のデータを格納する ObjectScript クラスを生成してください。
JSON を入力する前に Return キーを押すと、ChatGPT から次のように指示されました。
ChatGPT: ObjectScript クラスの生成が必要な JSON 構造を提供してください。 サンプルの JSON オブジェクトがある場合は、それを貼り付けてください。それに対応する InterSystems ObjectScript クラスを作成します。
プロンプトに以下の内容を入力しました。
{
"id": 335818632,
"appId": 113,
"appName": "Batch",
"contentId": 182455380233,
"subject": "Test Subject",
"name": "Test email campaign name",
"counters": {
"processed": 3910,
"deferred": 86,
"unsubscribed": 17,
"statuschange": 17,
"bounce": 153,
"mta_dropped": 8,
"dropped": 299,
"delivered": 3749,
"sent": 3903,
"click": 16,
"open": 323
},
"lastProcessingFinishedAt": 1733232499000,
"lastProcessingStartedAt": 1733232303000,
"lastProcessingStateChangeAt": 1733232499000,
"numIncluded": 4201,
"processingState": "DONE",
"scheduledAt": 1733232300000,
"type": "BATCH_EMAIL"
}
ChatGPT の返答:
提供された JSON 構造にマッピングする InterSystems ObjectScript クラスです。
Class MyNamespace.MyJSONData Extends (%Persistent, %JSON.Adaptor)
{
Property id As%Integer;Property appId As%Integer;Property appName As%String;Property contentId As%Integer;Property subject As%String;Property name As%String;Property counters As MyNamespace.Counters;Property lastProcessingFinishedAt As%BigInt;Property lastProcessingStartedAt As%BigInt;Property lastProcessingStateChangeAt As%BigInt;Property numIncluded As%Integer;Property processingState As%String;Property scheduledAt As%BigInt;Property type As%String;ClassMethod%OnJSONImport(jsonObject As%Object, instance As MyNamespace.MyJSONData) As%Status
{
Quit ..%JSONImport(jsonObject, .instance)
}
}
Class MyNamespace.Counters Extends (%SerialObject, %JSON.Adaptor)
{
Property processed As%Integer;Property deferred As%Integer;Property unsubscribed As%Integer;Property statuschange As%Integer;Property bounce As%Integer;Property mta_dropped As%Integer;Property dropped As%Integer;Property delivered As%Integer;Property sent As%Integer;Property click As%Integer;PropertyopenAs%Integer;
}
説明も提示されました。
.png)
このコードは基礎として最適ですが、自分の「MyPkg」というパッケージに対応するようにし、クラスに「EmaiCampaign」という名前を付けたいと思います。 また、NI を少々使用すると、「%BigInt」プロパティを生成した値が実は Linux 時間であり、プロパティは「%Library.PosixTime」である必要があることが分かります。
以下のようにリクエストしました(「~ください」と機会になぜ言ってしまうのかわかりませんが、親にそう育てられたからでしょう)
私: パッケージ名を「MyPkg」、クラスを「EmailCampaign」に変えて、もう一度クラスを作成し直してください。 また、プロパティの型を %BigInt から %Library.PosixTime に変更してください。
ChatGPT の返答:
指定されたパッケージ名とクラス名で ObjectScript クラスを更新しました。また、タイムスタンププロパティを %Library.PosixTime に更新しました。
Class MyPkg.EmailCampaign Extends (%Persistent, %JSON.Adaptor)
{
Property id As%Integer;Property appId As%Integer;Property appName As%String;Property contentId As%Integer;Property subject As%String;Property name As%String;Property counters As MyPkg.Counters;Property lastProcessingFinishedAt As%Library.PosixTime;Property lastProcessingStartedAt As%Library.PosixTime;Property lastProcessingStateChangeAt As%Library.PosixTime;Property numIncluded As%Integer;Property processingState As%String;Property scheduledAt As%Library.PosixTime;Property type As%String;ClassMethod%OnJSONImport(jsonObject As%Object, instance As MyPkg.EmailCampaign) As%Status
{
Quit ..%JSONImport(jsonObject, .instance)
}
}
Class MyPkg.Counters Extends (%SerialObject, %JSON.Adaptor)
{
Property processed As%Integer;Property deferred As%Integer;Property unsubscribed As%Integer;Property statuschange As%Integer;Property bounce As%Integer;Property mta_dropped As%Integer;Property dropped As%Integer;Property delivered As%Integer;Property sent As%Integer;Property click As%Integer;PropertyopenAs%Integer;
}
説明も提示されました。
.png)
コードをそのまま VSCode にコピーすると、波括弧に関する構文の問題がハイライトされました。 ObjectScript クラスでは内部クラス定義を使用できません。
.png)
ChatGPT に、MyPkg.Counters 内部クラスを別のクラスにして「波括弧」の問題を修正するように頼んでも「no-op」になるため、人の手でそのクラスを別のファイルに移動する必要があります。 ChatGPT は次のリクエストの後にそのクラスの名前を変更しました。
私: 記述されたとおりのクラスはコンパイルしません。 MyPkg.Counters 内部クラスをメインクラスから独自のクラスに移動して、MyPkg.CampaignCounters に名前を変更できますか?
ChatGPT の返答:
MyPkg.CampaignCounters クラスを独自のクラスに移動して、ObjectScript コードを更新しました。
Class MyPkg.EmailCampaign Extends (%Persistent, %JSON.Adaptor)
{
Property id As%Integer;Property appId As%Integer;Property appName As%String;Property contentId As%Integer;Property subject As%String;Property name As%String;Property counters As MyPkg.CampaignCounters;Property lastProcessingFinishedAt As%Library.PosixTime;Property lastProcessingStartedAt As%Library.PosixTime;Property lastProcessingStateChangeAt As%Library.PosixTime;Property numIncluded As%Integer;Property processingState As%String;Property scheduledAt As%Library.PosixTime;Property type As%String;ClassMethod%OnJSONImport(jsonObject As%Object, instance As MyPkg.EmailCampaign) As%Status
{
Quit ..%JSONImport(jsonObject, .instance)
}
}
Class MyPkg.CampaignCounters Extends (%SerialObject, %JSON.Adaptor)
{
Property processed As%Integer;Property deferred As%Integer;Property unsubscribed As%Integer;Property statuschange As%Integer;Property bounce As%Integer;Property mta_dropped As%Integer;Property dropped As%Integer;Property delivered As%Integer;Property sent As%Integer;Property click As%Integer;PropertyopenAs%Integer;
}
上記のコードを VSCode に貼り付けてコンパイルすると、コンパイラーは「%Object」という名前の型が ObjectScript に存在しないと通知しました。 IRIS ドキュメントによると、%JSON.Adaptor の %JSONImport() メソッドの最初のパラメーターは柔軟に設定できるようです。
「入力引数は、文字列またはストリームとしての JSON か、%DynamicAbstractObject のサブクラスのいずれかです。」
最初のクラスで %OnJSONImport() の最初のパラメーターの「As %Object」プロパティを取り除き、2 つのクラスを個別のファイルに分けると、MyPkg.EmailCampaign クラスが正しくコンパイルされました。 ただし、MyPkg.CampaignCounters はコンパイルしませんでした。ChatGPT は(まだ)アンダースコアが ObjectScript で特殊文字(文字列連結演算子)であることを知りません。
では、そのことを教えましょう。
私: ObjectScript では、アンダースコア文字「_」は特殊文字です。 名前にアンダースコアが使用されているプロパティをキャメルケース表記に変更してアンダースコアを削除してください。
ChatGPT の返答:
アンダースコアが使用された名前をキャメルケース表記に変換したプロパティでコードを更新しました。
Class MyPkg.EmailCampaign Extends (%Persistent, %JSON.Adaptor)
{
Property id As%Integer;Property appId As%Integer;Property appName As%String;Property contentId As%Integer;Property subject As%String;Property name As%String;Property counters As MyPkg.CampaignCounters;Property lastProcessingFinishedAt As%Library.PosixTime;Property lastProcessingStartedAt As%Library.PosixTime;Property lastProcessingStateChangeAt As%Library.PosixTime;Property numIncluded As%Integer;Property processingState As%String;Property scheduledAt As%Library.PosixTime;Property type As%String;ClassMethod%OnJSONImport(jsonObject As%Object, instance As MyPkg.EmailCampaign) As%Status
{
Quit ..%JSONImport(jsonObject, .instance)
}
}
Class MyPkg.CampaignCounters Extends (%SerialObject, %JSON.Adaptor)
{
Property processed As%Integer;Property deferred As%Integer;Property unsubscribed As%Integer;Property statusChange As%Integer;Property bounce As%Integer;Property mtaDropped As%Integer;Property dropped As%Integer;Property delivered As%Integer;Property sent As%Integer;Property click As%Integer;PropertyopenAs%Integer;
}
説明も提示されました。
.png)
ChatGPT は、依頼されたことだけでなく、2 語で構成されたプロパティ名もキャメルケース表記に変更してくれました(statuschange)。同じように命名されているメインクラスの他のプロパティもすべてキャメルケース表記なので、この変更を維持します。
最後に生成されたコードでは 2 つの個別のファイルに分けられ(また %OnJSONImport() メソッドの定義から「As %Object」定義を削除して)、すべてのコードが正しくコンパイルされるようになりました。
これらの生成されたクラスは、求めているものの基礎として最適なコードです。このプロジェクトの他の REST データソースでもこのプロセスを繰り返して、大量の不要な入力作業を省きたいと思います。