【4日目】discord.jsで地震情報を出すコマンドを作ろう

# はじめに
こんにちは、なりかくんと申します。
今回は、discord.jsで地震情報を出すコマンドを作ろうと思います。

# 地震情報の取得元
今回使う地震情報の取得元は私（なりかくん）が公開している地震情報APIを利用します。
地震情報APIの仕様は以下に記載されていますので省略します。

https://ntool.online/apidoc/earthquakeapi

# 今回使うモジュール: request
今回は、以前紹介したdiscord.jsと情報を取得する際に利用するrequestモジュールを利用します。
requestモジュールのインストールは、以下のコマンドでインストールできます。
```shell
npm install request
```

普通にrequestを書くとネストが深くなってしまうのでPromiseを使ってシンプルにします。
以下が地震情報APIからJSONデータを取得するコードです。
```js
function getEarthquake() {
    return new Promise((resolve, reject) => {
        request({
            url: "https://dev.narikakun.net/webapi/earthquake/post_data.json",
            json: true
        }, function (error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body);
            }
        });
    });
}
```

# データを表示する
では、データを表示するプログラムを作ってみましょう。APIのドキュメントをよく読み、コードを作っていきます。
今回私は、以下のようなコードになりました。
```js
let getData = await getEarthquake();
let lines = [`> **${getData.Control.Title}**`];
if (getData.Control.Title == "震源・震度に関する情報" || getData.Control.Title == "震源に関する情報") {
    lines.push(`**発生時間**: ${getData.Body.Earthquake.OriginTime}`);
    lines.push(`**震源地名**: ${getData.Body.Earthquake.Hypocenter.Name}`);
    lines.push(`**深さ**: ${getData.Body.Earthquake.Hypocenter.Depth}km`);
    lines.push(`**規模**: M${getData.Body.Earthquake.Magnitude}`);			
}
if (getData.Control.Title == "震源・震度に関する情報" || getData.Control.Title == "震度速報") {
    lines.push(`**最大深度**: ${getData.Body.Intensity.Observation.MaxInt}`);
    let intensity = [];
    for (const prefObj of getData.Body.Intensity.Observation.Pref) {
        for (const areaObj of prefObj.Area) {
            intensity.push(`${areaObj.Name} [${areaObj.MaxInt}]`);
        }
    }
    lines.push(`\`\`\`\n${intensity}\n\`\`\``);
}
await interaction.reply(lines.join("\n"));
```
実行してみるとこのようになります。タイトルと地震の情報等をシンプルにマークダウン形式で表示する形になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/359177e0-3cbd-2358-e992-b858b330b212.png)

# コマンドファイルの全体
では、今回作成したコードのコマンドファイルの全体を公開します。
```js:earthquake.js
const { SlashCommandBuilder } = require('discord.js');
const request = require("request");

module.exports = {
	data: new SlashCommandBuilder()
		.setName('earthquake')
		.setDescription('地震情報を取得'),
	async execute(interaction) {
		let getData = await getEarthquake();
		let lines = [`> **${getData.Control.Title}**`];
		if (getData.Control.Title == "震源・震度に関する情報" || getData.Control.Title == "震源に関する情報") {
			lines.push(`**発生時間**: ${getData.Body.Earthquake.OriginTime}`);
			lines.push(`**震源地名**: ${getData.Body.Earthquake.Hypocenter.Name}`);
			lines.push(`**深さ**: ${getData.Body.Earthquake.Hypocenter.Depth}km`);
			lines.push(`**規模**: M${getData.Body.Earthquake.Magnitude}`);			
		}
		if (getData.Control.Title == "震源・震度に関する情報" || getData.Control.Title == "震度速報") {
			lines.push(`**最大深度**: ${getData.Body.Intensity.Observation.MaxInt}`);
			let intensity = [];
			for (const prefObj of getData.Body.Intensity.Observation.Pref) {
				for (const areaObj of prefObj.Area) {
					intensity.push(`${areaObj.Name} [${areaObj.MaxInt}]`);
				}
			}
			lines.push(`\`\`\`\n${intensity}\n\`\`\``);
		}
		lines.push(getData.Head.Headline);
		await interaction.reply(lines.join("\n"));
		function getEarthquake() {
			return new Promise((resolve, reject) => {
				request({
					url: "https://dev.narikakun.net/webapi/earthquake/post_data.json",
					json: true
				}, function (error, response, body) {
					if (error) {
						reject(error);
					} else {
						resolve(body);
					}
				});
			});
		}
	},
};
```

以上です、最後までお読みいただきありがとうございました。