【19日目】discord.jsでモーダルウィンドウを使ってメールを送信する

# はじめに
こんにちは、なりかくんです。
今回は、discord.jsを使ってDiscord上でモーダルウィンドウを使ってメールを送信するプログラムを作ってみようと思います。

モーダルウィンドウについては、16日目の記事に書いていますので是非そちらをお読みください。

https://qiita.com/narikakun/items/868efb6640a66334a146

# 今回使うメール送信ライブラリ
今回は、nodemailerというライブラリを使ってみようと思います。
このライブラリのいいところは、非常に簡単に使うことが出来るという点と現在もメンテナンスがされているという点です。

以下のコマンドで簡単にインストールできます。
```
npm install nodemailer
```

以下のようにしてメールを送信することが出来ます。
```js
const nodemailer = require('nodemailer');

const transport = nodemailer.createTransport({
    host: 'メールサーバーアドレス',
    port: 465,
    secure: true,
    requireTLS: false,
    tls: {
        rejectUnauthorized: false,
    },
    auth: {
        user: 'ユーザー名',
        pass: 'パスワード'
    },
});
await transport.sendMail({
    from: "差出人",
    to: "宛先",
    subject: "件名",
    text: "内容",
});
```

# モーダルウィンドウでメール送信画面を作る
今回は、モーダルウィンドウを使ってメールの送信画面を作ります。モーダルウィンドウを使うと以下のような画面を簡単に作ることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/19aede36-1568-ea69-298d-aa9b32473d82.png)

この画面を作るコードは以下のようになっています。
```js
const { ModalBuilder, TextInputBuilder, ActionRowBuilder, TextInputStyle } = require('discord.js');

const modal = new ModalBuilder()
    .setCustomId('mailSend')
    .setTitle('メール送信');

const fromInput = new TextInputBuilder()
    .setCustomId('fromInput')
    .setLabel("送信元")
    .setStyle(TextInputStyle.Short);

const toInput = new TextInputBuilder()
    .setCustomId('toInput')
    .setLabel("送信先")
    .setStyle(TextInputStyle.Short);

const subjectInput = new TextInputBuilder()
    .setCustomId('subjectInput')
    .setLabel("件名")
    .setStyle(TextInputStyle.Short);

const htmlInput = new TextInputBuilder()
    .setCustomId('htmlInput')
    .setLabel("内容")
    .setStyle(TextInputStyle.Paragraph);

modal.addComponents(new ActionRowBuilder().addComponents(fromInput), new ActionRowBuilder().addComponents(toInput), new ActionRowBuilder().addComponents(subjectInput), new ActionRowBuilder().addComponents(htmlInput));

await interaction.showModal(modal);
```

# 組み合わせる
では、送信するコードとモーダルウィンドウのコードを組み合わせてみます。
以下のようなコードになりました。
```js:mailsend.js
const { SlashCommandBuilder, ModalBuilder, TextInputBuilder, ActionRowBuilder, TextInputStyle } = require('discord.js');
const nodemailer = require('nodemailer');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('mailsend')
		.setDescription('メール送信'),
	async execute(interaction) {
		const modal = new ModalBuilder()
			.setCustomId('mailSend')
			.setTitle('メール送信');

		const fromInput = new TextInputBuilder()
			.setCustomId('fromInput')
			.setLabel("送信元")
			.setStyle(TextInputStyle.Short);

		const toInput = new TextInputBuilder()
			.setCustomId('toInput')
			.setLabel("送信先")
			.setStyle(TextInputStyle.Short);

		const subjectInput = new TextInputBuilder()
			.setCustomId('subjectInput')
			.setLabel("件名")
			.setStyle(TextInputStyle.Short);

		const htmlInput = new TextInputBuilder()
			.setCustomId('htmlInput')
			.setLabel("内容")
			.setStyle(TextInputStyle.Paragraph);

		modal.addComponents(new ActionRowBuilder().addComponents(fromInput), new ActionRowBuilder().addComponents(toInput), new ActionRowBuilder().addComponents(subjectInput), new ActionRowBuilder().addComponents(htmlInput));

		await interaction.showModal(modal);
		const filter = (mInteraction) => mInteraction.customId === 'mailSend';
		interaction.awaitModalSubmit({ filter, time: 360000 })
			.then(async mInteraction => {
				const from = mInteraction.fields.getTextInputValue('fromInput');
				const to = mInteraction.fields.getTextInputValue('toInput');
				const subject = mInteraction.fields.getTextInputValue('subjectInput');
				const html = mInteraction.fields.getTextInputValue('htmlInput');
				await mInteraction.deferReply();
				const transport = nodemailer.createTransport({
                    host: 'メールサーバーアドレス',
                    port: 465,
                    secure: true,
                    requireTLS: false,
                    tls: {
                        rejectUnauthorized: false,
                    },
                    auth: {
                        user: 'ユーザー名',
                        pass: 'パスワード'
                    },
				});
				await transport.sendMail({
					from: from,
					to: to,
					subject: subject,
					text: html,
				});
				mInteraction.editReply(`送信しました！`);
			})
			.catch(console.error);
	},
};
```
実際に動かしてみると、以下のようになります。まず、モーダルウィンドウに入力して送信ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/1973a1ab-d42b-7a6c-8c25-9bb8a1bd5f23.png)
そして、宛先のメールボックスを確認するとしっかりと届いていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/99e2a3ed-dade-90d8-75b0-def435f9f70e.png)

これを活用するといい感じに何かが作れそうな予感がします（笑）
以上です、最後までお読みいただきありがとうございました。