【6日目】discord.jsで送られたURLをすべて短縮URLにする

# はじめに
こんにちは、なりかくんと申します。
今回は、discord.jsで受け取ったメッセージにURLが含まれていたら勝手に短縮URLに変換するBotを作ってみようと思います。

# 短縮URLに使うAPI
今回は、なりかくんが開発・運営をしている[UR0.cc](https://ur0.cc/)のAPIを活用して短縮URLを作成したいと思います。
このAPIは、API Keyなどの登録が不要なので非常に簡単に使うことが出来るようになっています。

https://ur0.cc/

短縮URLを作成するプログラムは以下のようになります。
requestモジュールを使ってリクエストを作成します。また、Promiseを使うことで関数化出来ます。
```js
function createShortLink(url) {
    return new Promise((resolve, reject) => {
        request({
            url: "https://ur0.cc/api.php?create=true&url="+encodeURIComponent(url),
            json: true
        }, function (error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body);
            }
        });
    });
}
```

# メッセージインテントを有効にする必要がある
Discord内で送られたメッセージを受け取るには、Discord Developer Portalからメッセージインテントを有効にする必要があります。また、Botを起動時にインテントを指定する必要もあります。
といってもClientインスタンスを作成する際に、`IntentsBitField.Flags.GuildMessages`と`IntentsBitField.Flags.MessageContent`を指定するだけです。
```js
new Client({
    intents: [
        GatewayIntentBits.Guilds,
        IntentsBitField.Flags.GuildMessages,
        IntentsBitField.Flags.MessageContent
    ]
});
```

# メッセージからURLのみを抜き出す
受け取ったメッセージからURLを正規表現で抜き出します。以下のコードで抜き出すことが出来ます。
```js
string.match(/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g);
```
これを使ってメッセージからコードを抜き出して一つずつ処理するコードを書くとこのようになります。
```js
let urls = String(message.content).match(/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g);
if (urls) {
    for (const url of urls) {
        console.log(url);
    }
}
```

# メッセージを受け取って作成して送る
messageCreateイベントでメッセージを受け取って、先ほどのプログラムと送るプログラムをまとめるとこのようになります。
```js
client.on('messageCreate', async message => {
	try {
        if (message.author.bot) return;
        let urls = String(message.content).match(/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g);
        if (urls) {
            let shortUrls = [];
            for (const url of urls) {
                let createResult = await createShortLink(url);
                if (createResult.code == 200) {
                    shortUrls.push(createResult.shorturl);
                }
            }
            if (shortUrls.length != 0) {
                message.reply(shortUrls.join(" , "));
            }
        }
	} catch (error) {
		console.error(error);
	}
});
```

実際に動かしてみると、このように動きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/4fde69a3-9970-85a5-ab85-52416989f550.png)

今回のコードの全体はこのようになります。
```js:index.js
const request = require("request");
const { Client, GatewayIntentBits, IntentsBitField } = require('discord.js');
const { token } = require('./config.json');

const client = new Client({ intents: [GatewayIntentBits.Guilds, IntentsBitField.Flags.GuildMessages, IntentsBitField.Flags.MessageContent] });

client.on('ready', () => {
	console.log(`${client.user.tag}でログインしました。`);
});

client.login(token);

client.on('messageCreate', async message => {
	try {
        if (message.author.bot) return;
        let urls = String(message.content).match(/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g);
        if (urls) {
            let shortUrls = [];
            for (const url of urls) {
                let createResult = await createShortLink(url);
                if (createResult.code == 200) {
                    shortUrls.push(createResult.shorturl);
                }
            }
            if (shortUrls.length != 0) {
                message.reply(shortUrls.join(" , "));
            }
        }
	} catch (error) {
		console.error(error);
	}
});

function createShortLink(url) {
    return new Promise((resolve, reject) => {
        request({
            url: "https://ur0.cc/api.php?create=true&url="+encodeURIComponent(url),
            json: true
        }, function (error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body);
            }
        });
    });
}
```

# 最後に
このままでは、導入されているサーバーすべてで勝手に短縮してしまうのでアレンジしてみると実用的になるのかと思います。皆さんもぜひ試してみてください。

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