【discordjs】DMにメッセージを送りたい!

1 min読了の目安(約1500字TECH技術記事

初書:2021/2/2
discordjs:11.6.4

前書き

discord.jsを使用してdiscordボットを作成していたのだが、リマインダーとしてDMにも送信してくれるようにしたいなと思ったので実装してみる

このサイトは以下のサイトを参考にしています。そのため、使用しているdiscordjsのバージョンが低めです。最新のdiscordjsを使用している場合は仕様が異なる可能性があります。
誰でも作れるdiscordbot初級編

その前に

対話形式のbotとして、ユーザー側からコメントがきて、それを返信するというシステムを作成する場合は、サーバーのチャンネルに返信する形と同じコードを使用できる。
上記の参考サイトの以下の箇所

function sendMsg(channelId, text, option={}){
    client.channels.get(channelId).send(text, option)
        .then(console.log("メッセージ送信: " + text + JSON.stringify(option)))
        .catch(console.error);
}

やってることはチャンネルを探してそこに送信しているのだが、DMから一度でも送られてくると、channnels.getでDMも取得できるのでそのまま送信ができる。

ただ、この方法には欠点があり、再起動するとchannnels.getで取得出来なくなるのだ。

一々再起動するたびにアクションしてもらうのはリマインダーとしてなんの役にも立たないので、送る方法を考える

実装する

調べてみると以下のページが。
javascript-ユーザーへのプライベートメッセージの送信-スタックオーバーフロー

どうやらclient.fetchUserからユーザー情報を取得し、送信できるらしい。
ということで、sendMsgを真似て作成してみる

function sendDM(userId, text, option = {}) {
    client.fetchUser(userId)
        .then(e => {
            e.send(text, option)
                .then(console.log("メッセージ送信: " + text + JSON.stringify(option)))
                .catch(console.error); // 1
        })
        .catch(console.error); // 2
}

簡単に説明すると、fetchUserでユーザー検索し、見つかればe.sendでメッセージを送信、見つからなければ2つ目のcatchでエラーを出力するというPromiseの2重構造。
ちなみにuserIdに入れる変数はチャンネルIdではなくユーザーId。

終わりに

検索→送信としているので正直タイムラグが大きくなると思うが、今回は送信できたらいいやと思ったので考えていない。