モックはChatGPTにサクッと作ってもらいましょう

## はじめに
こんにちわ。オルトプラスでサーバーサイドエンジニアやってます勝城です。

普段は社内プロジェクトでテックリードをしつつ、サーバーサイドエンジニアの採用担当をしております。

みなさん、ChatGPTを使っていますか？オルトプラスではaiラボというSlackチャンネルがあり、AI関する情報の共有等を積極的に行っています。

さて「モックはChatGPTにサクッと作ってもらいましょう」というタイトルにしましたが、ChatGPTでできることは自分でやる必要はなく、どんどん活用しませんかという布教記事です。

私はエンジニアですが、非エンジニアの方でもChatGPTを活用することでモックレベルなら簡単に作れてしまうでしょう。

この記事でやること

<b>・ChatGPTを使ってローカル環境で動くモックを作る</b>

この記事はこんな人におすすめ

<b>・ChatGPTを活用したい方
・ChatGPTでできる一例を知りたい方
・非エンジニアで簡易なモックを作りたい方</b>

本記事は <a href="https://qiita.com/advent-calendar/2023/altplus2023">オルトプラス Advent Calendar 2023</a> の12/19の記事です。

:::note info
今年はCEDEC2023で登壇する機会があり、社内の活動やNFTゲーム開発のおける実装と運用のノウハウを紹介することができました。

講演資料は<a href="https://cedil.cesa.or.jp/cedil_sessions/view/2715">CEDEC Digital Library</a>にアップロードされていますので、ご興味のある方はどうぞ。
:::

## 結論
ローカルや開発環境で動かすモックレベルであれば、ChatGPTを使うことでわずかな時間で作ることができます。

ChatGPTを使うことで自分のやりたいこと、欲しい情報に最短でアクセスし実行可能です。

情報の取り扱いや精度には注意が必要ですが、ChatGPTでできてしまうことはとことん任せてしまって、貴重な時間を他にやるべきことに有効活用したいと思います。

## 概要
![スクリーンショット 2023-12-12 10.37.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661678/960f74cb-640d-c4c9-13ed-423571172469.png)
ChatGPTを使ってFintech界隈でよく使用されるGo言語とbitFlyerが提供する公開APIを用いて、ビットコインのチャートをローカル環境のブラウザで表示する簡単なモックを作ってみました。

使用するもの

・ChatGPT4
・GoLand
・Go言語
・bitFlyerの[HTTP Public API](https://lightning.bitflyer.com/docs?lang=ja&_gl=1*1x0mock*_ga*ODAxMDA3NzI3LjE3MDIzNDIxNjE.*_ga_3VYMQNCVSM*MTcwMjM0NzQ4Ny4yLjEuMTcwMjM0NzUyMS4yNi4wLjA.)

## 手順1：ChatGPTにお願いする
![スクリーンショット 2023-12-12 9.56.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661678/2270ce08-5bff-a04a-35f9-1e12593d067c.png)

まずはシンプルにGo言語でbitFlyerのAPIを使ってビットコインの価格を取得したいとお願いしてみました。

するとChatGPTから次のような回答に。

![スクリーンショット 2023-12-12 9.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661678/a1881d63-01bd-8df1-c898-4c332a4b6f50.png)

提示されたソースコード

```golang:main.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

// TickerResponse はbitFlyerのAPIレスポンスを表します。
type TickerResponse struct {
	Last float64 `json:"ltp"`
}

func main() {
	url := "https://api.bitflyer.com/v1/getticker"
	resp, err := http.Get(url)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var ticker TickerResponse
	if err := json.NewDecoder(resp.Body).Decode(&ticker); err != nil {
		panic(err)
	}

	fmt.Printf("現在のビットコイン価格: %f\n", ticker.Last)
}
```

## 手順2：ChatGPTが生成したソースコードを実行する

1. GoLandを開いてchatgpt_bitflyerというプロジェクトを作成
2. main.goを作って、ソースコードをコピペ
3. go run main.go

```bash
$ touch main.go
$ go run main.go
現在のビットコイン価格: 6103838.000000
```
<b>ここまでわずか5分程度でビットコインの価格を取得できました。</b>

単純な処理ですが、もし自分でやるとなると最低でも15分以上は必要だと思います。

## 手順3:もう少し複雑なことをお願いする
![スクリーンショット 2023-12-12 11.35.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661678/0d10c4f0-6e22-33ee-c694-9357e15ffc0d.png)
次のビットコイン以外の価格も取得したいので、お願いしてみました。

するとChatGPTから次のような回答に。
![スクリーンショット 2023-12-12 11.36.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661678/427d2bea-d8b8-7117-c2e6-64e2a57488eb.png)


```golang:main.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

// TickerResponse はbitFlyerのAPIレスポンスを表します。
type TickerResponse struct {
	Last float64 `json:"ltp"`
}

func getTicker(url string) (TickerResponse, error) {
	resp, err := http.Get(url)
	if err != nil {
		return TickerResponse{}, err
	}
	defer resp.Body.Close()

	var ticker TickerResponse
	err = json.NewDecoder(resp.Body).Decode(&ticker)
	return ticker, err
}

func main() {
	bitcoinURL := "https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY"
	ethereumURL := "https://api.bitflyer.com/v1/getticker?product_code=ETH_JPY"

	bitcoinTicker, err := getTicker(bitcoinURL)
	if err != nil {
		panic(err)
	}

	ethereumTicker, err := getTicker(ethereumURL)
	if err != nil {
		panic(err)
	}

	fmt.Printf("ビットコイン価格: %f\n", bitcoinTicker.Last)
	fmt.Printf("イーサリアム価格: %f\n", ethereumTicker.Last)
}

```
実行結果
```bash
$ go run main.go
ビットコイン価格: 6097662.000000
イーサリアム価格: 325782.000000
```
処理が汎用的ではなかったので複数のproduct_codeを含むスライスを定義し、それぞれの通貨ペアの価格情報を取得するためにループを使用するようにお願いしてみました。

※本来は`GET /v1/getmarkets`エンドポイントを使用して、利用可能なproduct_codeを取得して各通貨ペアの価格情報を取得するコードを作成することができます。

```golang:main.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

// TickerResponse はbitFlyerのAPIレスポンスを表します。
type TickerResponse struct {
	Last float64 `json:"ltp"`
}

func getTicker(productCode string) (TickerResponse, error) {
	url := fmt.Sprintf("https://api.bitflyer.com/v1/getticker?product_code=%s", productCode)
	resp, err := http.Get(url)
	if err != nil {
		return TickerResponse{}, err
	}
	defer resp.Body.Close()

	var ticker TickerResponse
	err = json.NewDecoder(resp.Body).Decode(&ticker)
	return ticker, err
}

func main() {
	productCodes := []string{"BTC_JPY", "ETH_JPY", "XRP_JPY"} // ここに必要な通貨ペアを追加

	for _, code := range productCodes {
		ticker, err := getTicker(code)
		if err != nil {
			fmt.Printf("%s の価格取得中にエラー: %s\n", code, err)
			continue
		}
		fmt.Printf("%s 価格: %f\n", code, ticker.Last)
	}
}
```
このように指摘や改善策を提示することでペアプログラミングのように実装することもできます。

## 手順4：ビットコインのチャートをブラウザで見れるようにお願いする
![スクリーンショット 2023-12-12 10.37.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2661678/d41be6c1-abcb-2cda-6dfe-09e79839d0f1.png)
この後も同様にChatGPTにお願いしてみると無事ビットコインのチャートを表示できました。

<b>ここまで約15分程度です。</b>

途中CORS errorになりその解決策を提示してくれたり、質問に対して意図した回答でなければ、詳細に質問してあげると正確な回答をもらえます。

これは人間同士と同じでこちらが欲しい情報に対して相手に伝わる適切な質問をすることを心がけると良いでしょう。

```html:html/chart.html
<!DOCTYPE html>
<html>
<head>
    <title>ビットコイン価格チャート</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <!-- Chart.jsライブラリ -->
</head>
<body>

<canvas id="myChart" width="400" height="400"></canvas>
<script>
    // ビットコイン価格データを取得する関数
    function fetchBitcoinData() {
        fetch('/api/bitflyer')
            .then(response => response.json())
            .then(data => {
                const price = data.ltp; // 最終取引価格
                const timestamp = new Date(data.timestamp); // タイムスタンプ

                updateChart(timestamp, price);
            })
            .catch(error => console.error('Error:', error));
    }

    // チャートを更新する関数
    function updateChart(timestamp, price) {
        if (chart.data.labels.length > 20) { // 保持するデータポイントの数を制限
            chart.data.labels.shift();
            chart.data.datasets[0].data.shift();
        }

        chart.data.labels.push(timestamp.toLocaleTimeString());
        chart.data.datasets[0].data.push(price);
        chart.update();
    }

    // チャートの初期化
    var ctx = document.getElementById('myChart').getContext('2d');
    var chart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: 'ビットコイン価格 (JPY)',
                backgroundColor: 'rgba(255, 99, 132, 0.2)',
                borderColor: 'rgb(255, 99, 132)',
                data: []
            }]
        },
        options: {}
    });

    // 定期的にデータの取得とチャートの更新
    setInterval(fetchBitcoinData, 5000); // 5秒ごとに更新
</script>

</body>
</html>

```
chart.html は、ビットコインの価格チャートを表示するためのフロントエンドのページです。

このページでは、Chart.jsというJavaScriptライブラリを使用して、グラフの表示を行っています。

ページに含まれるJavaScriptコードは定期的に main.go のサーバー経由で /api/bitflyer エンドポイントにアクセスし、bitFlyerから取得したビットコインの価格情報を取得しています。

その後、このデータをチャートに反映させて現在のビットコインの価格動向を表示します。

```golang:main.go
package main

import (
	"io"
	"net/http"
)

func main() {
	// bitFlyer APIへのリクエストを処理するエンドポイント
	http.HandleFunc("/api/bitflyer", func(w http.ResponseWriter, r *http.Request) {
		// bitFlyer APIへのリクエスト
		resp, err := http.Get("https://api.bitflyer.com/v1/getticker?product_code=BTC_JPY")
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
		defer resp.Body.Close()

		// レスポンスをクライアントに転送
		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("Access-Control-Allow-Origin", "*")
		io.Copy(w, resp.Body)
	})

	// chart.html を配信するエンドポイント
	http.HandleFunc("/chart", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, "html/chart.html")
	})

	// サーバーを起動
	http.ListenAndServe(":5000", nil)
}

```
main.goには2つの主要な機能があります。

1つ目は、bitFlyer APIへのプロキシエンドポイントとして機能する /api/bitflyer です。このエンドポイントは、内部でbitFlyerのgetticker APIを呼び出してビットコインの最新の取引価格情報を取得し、フロントエンドに返します。

2つ目は、/chart エンドポイントを通じて chart.htmlファイルをクライアントに配信する機能です。これによりブラウザでビットコインの価格チャートを表示するページにアクセスできます。

```bash
$ go run main.go
# http://localhost:5000/chartにアクセス
```

## まとめ
この記事では、ChatGPTにビットコインのチャートを表示するモックを作ってもらました。

<b>初めのビットコイン価格の取得はわずか5分、ビットコインのチャート表示は15分程度です。</b>

今回は比較的作りやすいモックをお願いしているので短時間でしたが、それでも人間がやるよりは圧倒的に効率的だということが分かります。

エンジニアであればペアプログラミングのように精度の高いモックを効率的に作成できたり、非エンジニアでも対話形式で質問するだけで簡単なモックであれば作れてしまいます。

ChatGPTを使用に関するルールや制限に関して様々な議論があるものの、この先AIは切っても切れない関係になることは必然的です。

use AIからwith AIになる時代。ChatGPTでできることは自分でやる必要はなく、どんどん活用し貴重な時間を有効活用できればと思います。

## 参考
・<a href="https://lightning.bitflyer.com/docs?lang=ja&_gl=1*1x0mock*_ga*ODAxMDA3NzI3LjE3MDIzNDIxNjE.*_ga_3VYMQNCVSM*MTcwMjM0NzQ4Ny4yLjEuMTcwMjM0NzUyMS4yNi4wLjA.">bitFlyer API</a>