FF Logs API V2の実行方法について
概要
logs APIv2をnodeJs上で実行してみたので、備忘録をまとめます
準備物
- logsのアカウント
- NodeJS
- yarn
APIコールまでの手順
クライアントの作成まで
画像のように、クリックし、settingsの画面に入ります
一番下のWebAPIの欄のmanage your clients here
を選択する
Create Clientを選択し、ApplicationNameと Redirect URLsを入力します。
- ApplicationName: 適当に
- Redirect URLs: http://localhost:8080/callback
Redirect URLsでリダイレクトするべきURLはlocalhostにします。(ほかにリダイレクトURLに設定できるものがあればそちらを設定しても問題ありません)
ここまで記載すると、画面にクライアントIDとクライアントシークレットが表示されるのでどこかにメモしておきます。
ちなみに、忘れると再発行はできないので、別途クライアントを作成する必要があります
リダイレクトURLに設定したlocalhostを動かす
nodeJsのCLIのテンプレートをcloneしてください。
-> typescript + eslint + prettierなど必要なものをそろえたrepoなのでこちらを使えばとりあえずの開発を始められます。tsじゃなくてもよくね?という意見は聞きません。
ローカルにサーバー立てたいときにおなじみのexpressを使います
yarn add express
yarn add -D @types/express
でauthorizationCodeを受け取る処理を実装します。
srcに server.ts
を追加して下記の処理を記載します
import express from 'express';
const app = express();
const port = 8080;
app.get('/callback', (req, res) => {
const authorizationCode = req.query.code;
if (authorizationCode) {
console.log(`Authorization code: ${authorizationCode}`);
res.send('Authorization code received. You can close this window.');
} else {
res.send('No authorization code received.');
}
});
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
package.jsonに下記コマンドをscriptに追加してlocalhostができるようにします
"server": tsup src/server.ts --format esm --watch --clean --onSuccess \"node dist/server.js\
localhostしてサーバーを立ち上げておきます。
yarn server
APIを呼んでみる
今回実行するAPIはv2APIでREST APIではなく、GraphQLが使われています。
GraphQLに関して理解したい方は下記サイトを見てください。
今回のテストでGraphQLとRestAPIの違いについて具体例で示すことができればと思います
ドキュメントにはInsomniaというクライアント上で実行することを推奨されているので、それらを使って実行できるようにしてみます。
- Createでコレクションを作成します
Request Collectionを選択します。名前は適当に入れてください
- 中央のNew Http Requestを選択してRequestを作成します
- GetをPostに変更してurlを入力する欄にhttps://www.fflogs.com/api/v2/client を入力します
- 二個目のタブのBodyを選択し、▽をクリックしてQraphQLを選択します
- shcemaに下記のスクリプトを入力します
query ($reportId: String!) {
reportData {
report(code: $reportId) {
fights {
id
startTime
endTime
name
}
}
}
}
- 下側のQuery Variablesに下記のスクリプトを入力します
{
"reportId": "[ReportId]"
}
ここまで実装できているとこのタブはこんな内容になっているはずです
ReportIdはlogsの戦闘データのURLに含まれている文字列です。
https://ja.fflogs.com/reports/[ReportId]#fight=[num]
-
OAuth タブを選択した後に▽をクリアして、OAuth2を選択します
-
空欄を埋めていきます
- GRANT TYPE:Authorization Code
- AUTHORIZATION URL: https://www.fflogs.com/oauth/authorize
- AUTHORIZATION TOKEN URL: https://www.fflogs.com/oauth/token
- CLIENT ID: クライアント作成時に保存した文字列
- CLIENT SECRET: クライアント作成時に保存した文字列
- REDIRECT URL: http://localhost:8080/callback
-
Refresh Tokenを選択して、ACCESS TOKENが表示されることを確認します
ここまでうまくいっているとこんな感じになっているはずです
-
上側のSendを選択してAPIコールができることを確認します
レスポンスを確認して、HTTP Statusが200であればOKです。ついでにレスポンスも確認しておきましょう
APIコールをしてみる(nodeJS編)
下記コードを実行して実際にAPIコールができるか確認します
API_KEYは先ほどの9で取得したTokenを使います
// http requestを送るためにaxiosを使っているので、 yarn add axiosをしてください
import axios from 'axios';
const API_KEY =
'API_KEY';
const BASE_URL = 'https://www.fflogs.com/api/v2/client';
interface FightData {
id: number;
startTime: number;
endTime: number;
}
async function fetchGraphQL(query: string, variables: any): Promise<any> {
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${API_KEY}`,
};
try {
const response = await axios.post(
BASE_URL,
{
query,
variables,
},
{ headers },
);
return response.data.data;
} catch (error) {
console.error('Error fetching data from FFLogs API:', error);
return null;
}
}
async function getReportData(reportId: string) {
const query = `
query ($reportId: String!) {
reportData {
report(code: $reportId) {
fights {
id
startTime
endTime
name
}
}
}
}
`;
const variables = { reportId };
return fetchGraphQL(query, variables);
}
async function getFightData(
reportId: string,
fightId: number,
): Promise<FightData | null> {
const query = `
query ($reportId: String!, $fightId: Int!) {
reportData {
report(code: $reportId) {
fights(fightIDs: [$fightId]) {
id
startTime
endTime
}
}
}
}
`;
const variables = {
reportId,
fightId,
};
const data = await fetchGraphQL(query, variables);
if (data && data.reportData.report.fights.length > 0) {
return data.reportData.report.fights[0];
}
return null;
}
(async () => {
const reportId = 'ReportId'; // 戦闘レポートID
// 戦闘の詳細データを取得
const test = await getReportData(reportId);
//jsonとして保存してもよい
console.log(test);
})();
この結果で得られるレスポンスが先ほどのものと一致しているか確認してください。
これらの結果が正しければOKです。あとはschemaをいじって自分の欲しいデータを取得してみましょう。
まとめ
logs v2APIを実行するまでの流れについて記載しました。今後はこれらのデータを使って何かしらできればと考えています
雑記
FF14楽しんでいるでしょうか?私が絶オメガをクリアして満足していてほぼそれからやっていないです。次絶やるときは自動でlogを解析してうまくなったかどうか記録をつけたいので、このあたりについてもう少し深堀したいと思います
Chat GPT 4o
今回のAPI実行するためにChatGPT 4oに死ぬほど頼りました。ほぼほぼサンプルコード含めてChatGPT 4oさんに頼った形です。logs APIというマイナーなAPIに対してスキーマを定義できるなど、めちゃくちゃ優秀でした。こいつと対話しながら何か自分用のアプリを作ることができればと思います
Discussion