require()はできるだけファイル冒頭でする
細かいことですが、そのファイルがどんな外部モジュールに依存しているかをファイル冒頭にまとめておくと見やすいので、require()はできるだけファイルの冒頭に書きましょう。
varもconstにしています。
js
1const cron = require('node-cron')
2
3/* ... なんやかんやあって ... */
4
5client.on('ready', () => {
6 /* ... いろいろする ... */
7})
client.guilds.fetch(guildID)ではなくclient.guilds.cache.get(guildID)
client.guilds.fetch()は引数にサーバID(Snowflake)ではなくサーバオブジェクト(GuildResolvable)を渡さなくてはならないので、代わりにclient.guilds.cache.get(guildID)を使います。
js
1cron.schedule('00 17 * * *', async () => {
2 const guildID = 'ギルドID'
3
4 const guild = client.guilds.cache.get(guildID);
5 /* ...guildを使ってなにかする... */
guild.channels.cache.filter()はCollectionを返す
Array.prototype.filter()と同じような関数で、返値はChannelではなくCollectionです。
そのため、各チャンネルのmembersプロパティを取得するにはCollection.each()しましょう。
js
1const vchannels = guild.channels.cache.filter(channel => channel.type === 'voice')
2
3vchannels.each(vchannel =>
4 vchannel.members.each(/* ... */)
5)
ユーザをVoiceChannelから退出させる方法
いくつか方法があり、その中でもバージョンによって動くものと動かないものがあるようです。
member.voice.setChannel(null)やmember.setVoiceChannel(null)はメンバーのチャンネル情報をnullに設定することにより、ボイスチャンネルから退出させるというものです。
一方、member.voice.disconnect()やmember.voice.kick()は文字通りメンバーをボイスチャンネルから退出させるために用意された関数です。
バージョンによってdisconnect()が使える・使えない分かれるようですが、どのバージョンから使えるのかは残念ながらわかりません。kick()は公式ドキュメントから見つけることすらできませんでしたが、ユーザ発の情報では割とありましたので、昔からある方法なのかもしれません(この辺は伝聞になってしまいますが申し訳ない)。
【追記】
hinanonさんによると「await member.voice.kick().catch(console.error)にしたら動きました」とのことです。
以下のコードもその情報に合わせて修正しました。
member.voice.disconnect('理由')やmember.voice.kick()はPromiseを返す 非同期関数 なので、awaitで処理が終わるまで以降のコードの実行を中断します。
awaitを使うにはそのコードが含まれる関数をasyncにしなければいけないので、そこも修正します。
また、細かいことですが、if文周りでバグが入りそうなコードになっている(おそらくmember == nullのときでもconsole.log(member.id)が実行される)ので{...}で範囲を明確にしました。
ifやwhileなどは例え1行だとしてもif (...) {...}にしておくと意図しない動作を防げます。
vchannel.membersもCollectionなので、forEach()ではなくeach()を使っています。
js
1vchannel.members.each(async member => {
2 if (member) {
3 // disconnect()を使う方法
4 await member.voice.disconnect(`2時になったのでボイスチャットからキックしました(*'▽')`).catch(console.error)
5
6 // kick()を使う方法
7 await member.voice.kick().catch(console.error)
8
9 console.log(member.id)
10 }
11})
channel.send()はPromiseを返す
Promiseを返す関数は基本的にawaitして.catch()でエラー処理するようにしましょう。
なお、await member.voice.disconnect()するとdisconnect()の処理が終わるまでそれ以降のコードの実行を中断するので、その後にメッセージを送る場合もsetTimeout()でdisconnect()の処理が終わるまで待つ必要はありません。
js
1await member.voice.disconnect(`2時になったのでボイスチャットからキックしました(*'▽')`).catch(console.error)
2
3/* 処理待ちは必要ない */
4await channel.send(`2時になったのでボイスチャットからキックしました(*'▽')`).catch(console.error)
こんな感じでしょうか。
一応、guild, vchannels, channelがnullやundefined, []だった場合のエラー処理をしていませんのでご注意ください。
ご参考まで。
2021/10/28 07:11
2021/10/28 07:56 編集
2021/10/28 08:35
2021/10/28 08:36
2021/10/28 08:37