質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

3回答

12250閲覧

discord.jsでルーレットbotを作りたい

azi1208

総合スコア1

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/08/08 15:49

前提・実現したいこと

Discord.jsでのbot作成に挑戦中のプログラミング初心者です。
チャット上で「ルーレット」と入力されたら、指定人数分(今回は4人)の入力を受け付け、
その後、入力された値をランダムに出力するbotを作成したいと思っております。

想定している手順としては以下の通りです。
①ユーザが「ルーレット」と入力
②botが「何かやりたいことを入力してください」と出力
③ユーザ1が任意の値(1)を入力
④ユーザ2が任意の値(2)を入力
⑤ユーザ3が任意の値(3)を入力
⑥ユーザ4が任意の値(4)を入力
⑦botが入力された任意の値(1)~(4)までをランダムにどれか一つ出力

発生している問題・エラーメッセージ

・「何かやりたいことを入力してください」と出力した後、ユーザの入力を待たず、どんどん次の処理を実行してしまいます。

メッセージ送信: 何かやりたいことを入力してください{} メッセージ送信: undefined{} DiscordAPIError: Cannot send an empty message at /rbd/pnpm-volume/57782d40-a5d5-4f3c-ace6-91915818b576/node_modules/.registry.npmjs.org/discord.js/11.6.4/node_modules/discord.js/src/client/rest/RequestHandlers/Sequential.js:85:15 at /rbd/pnpm-volume/57782d40-a5d5-4f3c-ace6-91915818b576/node_modules/.registry.npmjs.org/snekfetch/3.6.4/node_modules/snekfetch/src/index.js:215:21 at processTicksAndRejections (internal/process/task_queues.js:88:5) { name: 'DiscordAPIError', message: 'Cannot send an empty message', path: '/api/v7/channels/842725590116204547/messages', code: 50006, method: 'POST' }

該当のソースコード

const http = require('http'); const querystring = require('querystring'); const discord = require('discord.js'); const client = new discord.Client(); http.createServer(function(req, res){ if (req.method == 'POST'){ var data = ""; req.on('data', function(chunk){ data += chunk; }); req.on('end', function(){ if(!data){ res.end("No post data"); return; } var dataObject = querystring.parse(data); console.log("post:" + dataObject.type); if(dataObject.type == "wake"){ console.log("Woke up in post"); res.end(); return; } res.end(); }); } else if (req.method == 'GET'){ res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Discord Bot is active now\n'); } }).listen(3000); client.on('ready', async message =>{ console.log('Bot準備完了~'); client.user.setPresence({ activity: { name: 'げーむ' } }); }); //ルーレット処理 client.on('message', async message =>{ if (message.author.id == client.user.id || message.author.bot){ return; } if (message.content.match(/ルーレット/)){ let text = "何かやりたいことを入力してください"; sendMsg(message.channel.id, text); let arr = []; client.on('message', async message =>{ arr.push(message); }); client.on('message', async message =>{ arr.push(message); }); client.on('message', async message =>{ arr.push(message); }); client.on('message', async message =>{ arr.push(message); }); let random = Math.floor(Math.random() * arr.length);  let result = arr[random];  message.reply(result) return; } }); if(process.env.DISCORD_BOT_TOKEN == undefined){ console.log('DISCORD_BOT_TOKENが設定されていません。'); process.exit(0); } client.login( process.env.DISCORD_BOT_TOKEN ); function sendReply(message, text){ message.reply(text) .then(console.log("リプライ送信: " + text)) .catch(console.error); } function sendMsg(channelId, text, option={}){ client.channels.get(channelId).send(text, option) .then(console.log("メッセージ送信: " + text + JSON.stringify(option))) .catch(console.error); }

補足情報(FW/ツールのバージョンなど)

開発環境;Glitch

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

randomかrandamかどっちか忘れたけど、
Jsのそういうモジュール使ったら簡単だよ

投稿2021/10/18 11:51

norinori7

総合スコア38

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Waki285

2021/10/18 13:01 編集

今回聞いているのは『「何かやりたいことを入力してください」と出力した後、ユーザの入力を待たず、どんどん次の処理を実行してしまいます。』だと思われるので、それは的外れだと思います。
guest

0

const http = require('http'); const querystring = require('querystring'); const discord = require('discord.js'); const client = new discord.Client(); http.createServer(function(req, res){ if (req.method == 'POST'){ var data = ""; req.on('data', function(chunk){ data += chunk; }); req.on('end', function(){ if(!data){ res.end("No post data"); return; } var dataObject = querystring.parse(data); console.log("post:" + dataObject.type); if(dataObject.type == "wake"){ console.log("Woke up in post"); res.end(); return; } res.end(); }); } else if (req.method == 'GET'){ res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Discord Bot is active now\n'); } }).listen(3000); client.on('ready', async message =>{ console.log('Bot準備完了~'); client.user.setPresence({ activity: { name: 'げーむ' } }); }); // //ルーレット処理 // client.on('message', async message =>{ // if (message.author.id == client.user.id || message.author.bot){ // return; // } // if (message.content.match(/ルーレット/)){ // let text = "何かやりたいことを入力してください"; // sendMsg(message.channel.id, text); // let arr = []; // client.on('message', async message =>{ // arr.push(message); // }); // client.on('message', async message =>{ // arr.push(message); // }); // client.on('message', async message =>{ // arr.push(message); // }); // client.on('message', async message =>{ // arr.push(message); // }); // let random = Math.floor(Math.random() * arr.length); //  let result = arr[random]; //  message.reply(result) // return; // } // }); client.on('message', async message => { if (message.content === 'ルーレット') { let arr = []; await message.channel.awaitMessages(() => true, { max: 1, time: 10 * 5000 })  .then(collected => { if (!collected.size) return console.log('メッセージが入力されませんでした(タイムアウト)'); console.log('メッセージ1: ' + collected.first().content) arr.push(collected.first().content) }) await message.channel.awaitMessages(() => true, { max: 1, time: 10 * 5000 })  .then(collected => { if (!collected.size) return console.log('メッセージが入力されませんでした(タイムアウト)'); console.log('メッセージ2: ' + collected.first().content) arr.push(collected.first().content) }) await message.channel.awaitMessages(() => true, { max: 1, time: 10 * 5000 })  .then(collected => { if (!collected.size) return console.log('メッセージが入力されませんでした(タイムアウト)'); console.log('メッセージ3: ' + collected.first().content) arr.push(collected.first().content) }) await message.channel.awaitMessages(() => true, { max: 1, time: 10 * 5000 })  .then(collected => { if (!collected.size) return console.log('メッセージが入力されませんでした(タイムアウト)'); console.log('メッセージ4: ' + collected.first().content) arr.push(collected.first().content) }) lottery(message.channel.id, arr); } }) if(process.env.DISCORD_BOT_TOKEN == undefined){ console.log('DISCORD_BOT_TOKENが設定されていません。'); process.exit(0); } client.login( process.env.DISCORD_BOT_TOKEN ); function sendReply(message, text){ message.reply(text) .then(console.log("リプライ送信: " + text)) .catch(console.error); } function sendMsg(channelId, text, option={}){ client.channels.get(channelId).send(text, option) .then(console.log("メッセージ送信: " + text + JSON.stringify(option))) .catch(console.error); } function lottery(channelId, arr){ let random = Math.floor( Math.random() * arr.length); sendMsg(channelId, arr[random] + 'に決定しました'); }

投稿2021/08/09 02:49

azi1208

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Waki285

2021/08/09 02:52

awaitを使ってしまうとthen処理は使えないはずですが,,,
Waki285

2021/08/09 02:54

また、条件としても最低限`m => !m.author.bot`はつけたらどうでしょうか。 それと、discord.jsのアップデートをしてくださいね。(package.jsonに行って、`discord.js`を ^12.5.3 にしてください。
guest

0

ベストアンサー

まず、discord.jsのバージョンをv12にアップデートしてください!
アップデートしたぜんていでかきます。

まず、client.onのなかにclient.onを書いても基本的に動きません。
ではどうすればいいかというとmessage.channel.awaitMessagesという関数があります

js

1const http = require('http'); 2const querystring = require('querystring'); 3const discord = require('discord.js'); 4const client = new discord.Client(); 5 6http.createServer(function(req, res){ 7 if (req.method == 'POST'){ 8 var data = ""; 9 req.on('data', function(chunk){ 10 data += chunk; 11 }); 12 req.on('end', function(){ 13 if(!data){ 14 res.end("No post data"); 15 return; 16 } 17 var dataObject = querystring.parse(data); 18 console.log("post:" + dataObject.type); 19 if(dataObject.type == "wake"){ 20 console.log("Woke up in post"); 21 res.end(); 22 return; 23 } 24 res.end(); 25 }); 26 } 27 else if (req.method == 'GET'){ 28 res.writeHead(200, {'Content-Type': 'text/plain'}); 29 res.end('Discord Bot is active now\n'); 30 } 31}).listen(3000); 32 33client.on('ready', async message =>{ 34 console.log('Bot準備完了~'); 35 client.user.setPresence({ activity: { name: 'げーむ' } }); 36}); 37 38 39//ルーレット処理 40client.on('message', async message =>{ 41 if (message.author.bot) return; 42 if (message.content.match(/ルーレット/)){ 43 await message.reply("なにかやりたいことを入力してください"); 44 const arr = []; 45 let user1 = await message.channel.awaitMessages(msg => msg.author.id === "ユーザー1のユーザーID", { max: 1, time: 6000/*1分*/}); 46 if (!user1.size) return message.reply("ユーザ1が応答しないため、タイムアウトしました"); 47 user1 = user1.first().content 48 arr.push(user1); 49 let user2 = await message.channel.awaitMessages(msg => msg.author.id === "ユーザー2のユーザーID", { max: 1, time: 6000/*1分*/}); 50 if (!user2.size) return message.reply("ユーザ2が応答しないため、タイムアウトしました"); 51 user2 = user2.first().content 52 arr.push(user2); 53 let user3 = await message.channel.awaitMessages(msg => msg.author.id === "ユーザー3のユーザーID", { max: 1, time: 6000/*1分*/}); 54 if (!user3.size) return message.reply("ユーザ3が応答しないため、タイムアウトしました"); 55 user3 = user3.first().content 56 arr.push(user3); 57 let user4 = await message.channel.awaitMessages(msg => msg.author.id === "ユーザー4のユーザーID", { max: 1, time: 6000/*1分*/}); 58 if (!user4.size) return message.reply("ユーザ4が応答しないため、タイムアウトしました"); 59 user1 = user4.first().content 60 arr.push(user4); 61 let random = Math.floor(Math.random() * arr.length); 62 let result = arr[random]; 63  message.reply(result) 64 return; 65 } 66 67}); 68 69if(process.env.DISCORD_BOT_TOKEN == undefined){ 70 console.log('DISCORD_BOT_TOKENが設定されていません。'); 71 process.exit(0); 72} 73 74client.login( process.env.DISCORD_BOT_TOKEN );

これでどうでしょうか。

投稿2021/08/09 02:34

Waki285

総合スコア2014

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

azi1208

2021/08/09 02:48

回答ありがとうございます。 あの後自分なりに改良して、message.channel.awaitMessagesと、awaitを使用して非同期処理の実装は完了しました。 ただまだユーザー操作的に不親切なので、 Waki285様からいただいた回答を組み込んで改良していきたいと思います。 この度は回答いただき誠にありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問