Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9138

Discord.jsでボタン式認証を作ろう

$
0
0
Discord.jsでボタン式認証を作ろう 今回はフレンドに頼まれてボタン式の認証BOTを作っていました 2時間もかかってしまった、、、 必要なもの Discord.jsv13 Node.jsv16以上 keyv@sqliteまたはaurora-mongo npm i discord.js @keyv/sqlite コード const { Client, Intents } = require('discord.js'); //discord.jsを読み込みClientとIntentを省略 const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); //Discordのインスタンスをインテンツを指定して作る const newbutton = buttondata => { //独自の関数を作る(ボタン作成の関数) return { components: buttondata.map(data => { return { custom_id: data.id, label: data.label, style: data.style || 1, type: 2 } }), type: 1 } //JSON型で返す }; const Keyv = require('keyv'); //keyvを読み込む const db = new Keyv(`sqlite://role.sqlite`, { table: "role" });//@keyv/sqlite //keyvのインスタンスを作る let us = []; //usにからの配列を代入する let checkus = []; //checkusにからの配列を代入する client.on("messageCreate", async message => { //messageCreateイベントを発火させてmessageにclassを代入して渡す if (message.content == "!認証画面") { //messageのcontentのプロパティが!画面表示だったらカッコ内の処理をする if (!await db.get(message.guild.id)) return message.reply("ロールをsetしてください"); //dbにメッセージが打たれたギルドIDが保存されているか判定してなかったら注意のメッセージを送信する message.reply({ //メッセージ送信 embeds: [{ description: "認証します\n認ボタンでスタート\n出てきた数字順に数字のボタンを押してください\n完了したらもう一度認証ボタンを押してください\nやり直したい場合は消ボタンを押してください" }], //embedを指定する components: [ newbutton([{ id: "id1", label: "1" }, { id: "id2", label: "2" }, { id: "id3", label: "3" }]), newbutton([{ id: "id4", label: "4" }, { id: "id5", label: "5" }, { id: "id6", label: "6" }]), newbutton([{ id: "id7", label: "7" }, { id: "id8", label: "8" }, { id: "id9", label: "9" }]), newbutton([{ id: "check", label: "認", style: 3 }, { id: "id0", label: "0" }, { id: "delete", label: "消", style: 4 }]) //idがカスタムIDラベルが表示されるラベル ] //ボタンを指定するこの時初めに作ったnewbutton関数を呼び出す }); }; if (message.content.startsWith("!setrole")) { //messageのcontentのプロパティが!setroleだったらカッコ内の処理をする const args = message.content.split(" ")[1].replace(/[^0-9]/g, ''); //打たれたメッセージの空白から1番目の値を数値のみにする const role = message.guild.roles.cache.get(args); //メッセージが打たれたギルドでそのロールがあるか判定する if (!role) return message.reply(`ロールが見つかりませんでした\n${args}`); //なかったら注意のメッセージを送信する const check = await message.guild.me.roles.add(role).catch(e => message.reply(`エラーが発生しました\nerror:${e}`)); //取得したロールを自分につけて権限が問題ないかチェックする if (check.content) return; //問題があったら処理しない await db.set(message.guild.id, args); //DBにメッセージギルドをkeyにして値をロールIDにする message.reply("完了しました"); //処理が終わったら完了のメッセージを送る }; }); client.on("interactionCreate", async interaction => { //interactionのイベントを発火させてinteraction classをinteractionに代入する if (interaction.customId.startsWith("id")) { //customIDの初めの値がidだったら実行する if (!us[interaction.userId]) return interaction.reply({ content: "認証ボタンを押してください", ephemeral: true }); //usのinteraction.userIdに何も保存されていなかったら注意のメッセージを送信する await interaction.deferUpdate(); //interactionをアップデートする try { //エラーが出ないか試す checkus[interaction.userId].push(interaction.customId.slice(2)) //checkusのinteraction.userIdに押された番号の数値を追加する } catch (e) { //エラーが起きた場合 interaction.followUp({ content: "Time outしました", ephemeral: true }) //エラーが起きるのは大体checkusのinteraction.userIdが存在しない時なのでその旨を表示する }; }; if (interaction.customId == "check") { //カスタムIDがcheckだったら処理 if (!us[interaction.userId]) { //usにユーザーIDのプロパティがなかったら処理する let num = []; //numにからの配列を代入する for (i = 0; i < 4; i++)num.push(Math.floor(Math.random() * 9)) //4桁の数値を一個一個配列にしてnumに保存 us[interaction.userId] = num; //usのユーザーIDのプロパティに作成したnumを代入 checkus[interaction.userId] = []; //checkusのユーザーIDのプロパティにからの配列を代入 interaction.reply({ //メッセージ送信 embeds: [{ description: `あなたの認証コードは\n${num.join(",")}\n600秒以内に完了させてください` }], //embedを設定する ephemeral: true //その人にしか見えないようにする }); setTimeout(() => { //600*1000ms(600s)たったら処理をする try { //試す delete us[interaction.userId]; delete checkus[interaction.userId]; //メモリーを開けるために古いデータを消す } catch (e) { //古いデータがなかったときにエラーが出るのでerrorハンドリングする } }, 600 * 1000); } else { //usにユーザーIDのプロパティがあったら処理する if (us[interaction.userId]?.join("") !== checkus[interaction.userId]?.join("")) return interaction.reply({ embeds: [{ description: `認証番号が違います\n認証番号${us[interaction.userId].join(",")}\nあなたが打ったコード${checkus[interaction.userId].join(",")}` }], ephemeral: true }); //認証番号とその人が今まで打った番号を比較してあっていなかったらその旨を表示する try { //試す delete us[interaction.userId]; delete checkus[interaction.userId]; //古いデータを消す } catch (e) { //古いデータがなかったらエラーが出るのでエラーハンドリングをする }; const role = await db.get(interaction.guildId); //dbからボタンが押されたギルドIDを使ってロールIDを取得する const check = await interaction.member.roles.add(role).catch(e => interaction.reply(`エラーが発生しました、サーバー管理者に問い合わせてください\nerror:${e}`)); //ボタンを押した人にロールをつけるロールをつけるのに失敗したらその旨を表示する if (check.content) return; //ロールをつけられなかったらこの先処理しない interaction.reply({ //メッセージを送信する embeds: [{ description: "認証成功" }], //embedを設定する ephemeral: true //その人にしか見えないようにする }); } }; if (interaction.customId == "delete") { //customIDがdeleteだったら処理をする if (!us[interaction.userId]) return interaction.reply({ content: "認証ボタンを押してください", ephemeral: true }); //usのユーザーIDプロパティがなかったらその旨を表示する try { //試す checkus[interaction.userId] = []; //今まで打たれてきたデータをからの配列にする } catch (e) { //今まで打たれてきたデータがなかった場合にエラーが出るのでエラーハンドリングする }; interaction.reply({ embeds: [{ description: "消しました" }], ephemeral: true }); //完了したらその旨を表示する }; }); client.login("Mytoken"); //websocket通信を開始する 実行の様子 PC iPhone 最後に バグがあったらBURI#9515まで連絡ください

Viewing all articles
Browse latest Browse all 9138

Trending Articles