GameFiメディアです。まだ公にリリースをしていません。
ゲームの情報と、ゲームのニュース情報、ゲームのTransaction、ゲーム内トークンの価格を確認することができます。
# チーム編成
Bizz(1人), エンジニア(2人), デザイナー(2人)
# 概要
2023年3月から、先輩から直接声をかけてもらい、GameFiメディアの立ち上げに参加しました。
主に先輩、そして内定者のインターンのデザイナーと協力して開発を進めています。
インフラと監督役でCTOに入ってもらっています。
# 技術選定
## 使用技術
### フロント
- Nuxt3.2
### API
- Nest
- Go
### DB
- Mysql
### インフラ
- AWS
- ECS
- Amazon RDS
- AWS Aurora
- AWS batch
- Lambda
- Amazon Managed Blockchain
### その他
- Python
- GO
## 技術選定理由
- Nuxt3.2
新規事業であり採用の観点からモダンな技術を採用しました。
VueとReactで迷いましたが、技術スタック的にVueを採用しました。
また、新規事業でありスピードが重視されコードが雑になることが予想されたので、TSを採用しました。
- Nest
web3系のフレームワークでJavaScriptが豊富だったため、Node.js系を採用しました。
その中で、開発工数を最小限に抑えるためにNest.jsを選択しました。
しかし、後にNest.jsを廃止しました。
理由としてnode固有のイベントループのブロックが不定期に発生し、安定稼働しなかったためです。
マルチスレッドにする方法や、レスポンスの容量を減らしてみましたが、改善されませんでした。
- Go(Gin+Gorm+CA)
Goを採用した理由として、早急にNestjsから移行をしたかったため、自分が一番得意であるGoを採用しました。
また、当事業部にはGoエンジニアが多いので増員しやすいと思ったからです。
フレームワークとしてGinとechoで悩み、最終的に知り合いの学生数人にどっちのプロダクトに参加をしたいか聞き新卒の採用の観点からGinにしました。
ORMは最も人気のあるGromにしました。
テストを必ず書きたく、精度の良いテストにしたかったのでCAを採用しmockを使用したテストを書いています。
- AWS
アプリケーションは全てイメージにしてECSに乗せてあります。
また、AWS batchにてトークンの価格とトランザクション情報を取得しています。
トークンの価格は、[CoinGecko APIにて取得](https://qiita.com/MoriKeigoYUZU/items/2db58fbea689dc84a80c)しています。
トランザクション情報はAmazon Managed Blockchainにてノードを立てて取得しています。
最初は[Etherscanにて取得](https://github.com/MoriKeigoYUZU/etherscan-rec)しようと思ったのですが、従量課金制で予算を出せば自分でノードを立てたほうが安くなるのでノードを立てています。
# グラフ機能
## 概要
トークンやトランザクション情報を一覧で表示するために、グラフ機能を導入しました。
以下はグラフ機能の要件です。
- トークン価格情報の表示(複数の場合は選択可能)
- トランザクション情報の表示
- 期間選択(7日、1ヶ月、1年、自由選択)
- グラフクリック時に縦線を表示し、クリックした日を強調する
- グラフクリック時には該当する日付のニューストピックに自動遷移する
- ニューストピックを選択した場合、該当するグラフを表示する(表示範囲外の日付がクリックされた場合は、クリックされた日を中心に表示範囲を調整する)
## 取り組み・苦労した点
### グラフクリック時の処理
- グラフのフレームワークとしてchartJSを使用しました。特定の日を強調する機能がなかったため、独自のプラグインを作成し、クリックした日付に色付けする機能を実装しました。
- ニューストピックに自動遷移させるために、クリックした日付に関連するニューストピックを表示する方法を開発しました。クリックされた日付に対応する情報がない場合は、その旨をユーザーに明示的に伝える仕組みを導入しました。
こちらは非常に苦労しました。
まず、グラフのフレームワークにchartJSを使用しており、特定の日を強調するライブラリがなかったので、自作のプライグランを作成し特定の日がクリックされたら色付けをする機能を実装しました。
以下一部抜粋
```javascript
const pinnedGraphDatePlugin = {
id: 'pinnedGraphDatePlugin',
afterDatasetsDraw: (chart: any, args: any, options: any) => {
const ctx = chart.ctx;
if (props.isTopicData == false) {
return
}
const svgImage = new Image();
svgImage.src = thumbtackSvg;
chart.data.labels.forEach((label: string, index: number) => {
if (options.days.includes(label)) {
ctx.save();
ctx.beginPath();
ctx.moveTo(x, textBoxY + textBoxHeight);
ctx.lineTo(x, chart.chartArea.bottom);
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(238, 66, 142, 0.45)';
ctx.stroke();
}
});
},
};
```
### ニューストピックを選択した場合の処理
- ニューストピックを選択した際には、APIにクリックした日付と現在の表示範囲を送信します。APIはこれらの情報を元にデータを取得します。ただし、取得したデータが現在の表示範囲よりも未来の日付を含む場合や、過去のデータが表示範囲外に及ぶ場合には、適切な調整を行いレスポンスを返します。
また、ニューストピックを選択したら該当するグラフを選択し表示させるでは、
ニューストピックをクリックしたときに、APIにクリックした日付と、現在の表示範囲に送っています。
そこで、APIは日付と表示範囲から情報を取得するのですが、範囲が現在よりも未来になってしまったり、過去のデータの取得以前に及んでしまう場合は、ずれるように調整をしてレスポンスを返しています。
# ニューストピック取得
## 概要
ニューストピックを半自動的に取得しています。
なぜ半自動化しているかというと、チームメンバーが少ないため手間をかけないように考えた結果決定しました。
## 取り組み
ニューストピックはかなり特殊な方法で取得しています。
GameFiは多くがDiscordにて情報を発信しています。
そのため、Discordをスクレイピングして自動化する方法にしようとしました。
しかし、Discordはスクレイピングが禁止されているので、別のアプローチを取る必要がありました。
そこで、Discord butを作成しbutを通して取得できるのはないかと思い採用しました。
仕組みとして、Gameのニュース・トピックが必ず公式のアナウンスチャンネルにて発信されます。
Discordサーバーに直接butを入れることは権限的にできないので、自分のチャンネルに転送させ、自分のチャンネルに常駐しているbutにて取得します。
取得したニュース情報は、OpenAIにて要約します。
その後、Slackにて要約した文と和訳した文を投稿しています。
投稿後、Bizz側が確認をし、OKであればスタンプにてアクションを、NGであればスレッドに新しいメッセージを書き込むことで編集ができるようにしました。
なぜSlackにて確認ができるようにしたかというと、管理者画面もあるのですが、ゲームタイトルの増加とともに大量のニュースが来ることが予想されたので、より気軽に使うことができるSlackにしました。
# ログイン機能
## 概要
独自のお気に入りゲームリストや、自分の保有しているトークンの価格をリアルタイムでみたり、収支を確認する機能を追加するためにログイン機能を作成します。
認証にはMetaMask認証を使用します。
リリースに向けて制作中です。