discord用のbotを作る
JavaScriptの勉強も兼ねてdiscord用のbotを作ったので、その備忘録。
といっても、説明の殆どは他のサイトに依存していますが。。。
まずは、Node.jsをダウンロードします。JavaScriptを実行してくれるやつです。
windowsだと、
winget install OpenJS.NodeJSというコマンドでダウンロードできるみたいです。
次に、以下の記事をもとにbotのアカウントとか登録とかやっていきます。
↑の途中でよくわからないバグに遭遇したんですが、あれはなんだったんでしょうね。
https://scrapbox.io/files/63b62a5080fba8001d46c9bf.png
web版のdiscordをログインし直してみたり、パスワード変えてみたり、設定から開発者モードをオンにしたり、設定の開発者モードの青文字部分からapiのサイトにサクセスしてみたり、、、、
結局、なにが間違っていて何が正しかったのか…。
めでたく環境が整ったら、後はコードを書くだけです。
JavaScriptの情報はあちこちに出回っているので、ところどころ調べながらコードを書いていきます。
バグがあってもしっかりとコマンドラインにエラー情報が載るので安心ですね。
最後に僕が作ったbotのコードを載せときます。
残念ながら、大した機能はありませんが…。
code:JavaScript
//実行コマンド:node index.js
//モジュールの読み込み??
const { Client, GatewayIntentBits } = require("discord.js");
const client = new Client({
intents: Object.values(GatewayIntentBits).reduce((a, b) => a | b)
});
const fs = require('fs');//ファイル操作用
//グローバル変数
let ary = [];//コマンドを保存するための配列
let ch_log_write = 0;
//コンソールに表示
client.on("ready", () => {
console.log(${client.user.tag} でログインしています。);
let text = String(fs.readFileSync("command_data.txt", {flag: 'a+'}));
if (text.length === 0) return;
if (text.startsWith("command_data_for_discord_bot")) {
let s = 0;
let f = 0;
while (text.charAt(s) !== "=") { s++; }
s++;
while (text.charAt(s) === " ") { s++; }//numの値の最初の位置まで進める
f = s;
while (text.charAt(f) !== ";") { f++; }//numの値の最後の位置まで進めル
f--;
while (text.charAt(f) === " ") { f--; }//数値と;の間の空間を埋める
let num = Number(text.substring(s, f + 1));//ファイルにあるコマンドの総数が判明
for (let i = 0; i < num * 2; i++) {//コマンドを読み込んでaryに書き込んでいく
s = f + 1;
while (text.charAt(s) !== "\"") { s++; }//""に囲まれた文字列を読み込んでいく
s++;
f = s;
while (text.charAt(f) !== "\"") { f++; }
ary.push(text.substring(s, f));//追加
}
}
});
client.on( 'disconnect', () => {
console.log('disconnect');
});
//メッセージが流れたときのイベント処理
client.on("messageCreate", async msg => {
/*botのメッセージだった場合に除外*/
if(msg.author.bot) {
return;
}
//メッセージがなんであれ、とりあえずlogに書き込む
if (ch_log_write === 1) {
let string_data = "`name = " + msg.member.displayName + "\n" +
"channel = " + msg.channel.name + "\n" +
"file = ";
const file = msg.attachments.first()
if (file) {
let url_ary = msg.attachments.map(attachment => attachment.url);
let string_url_num = String(url_ary.length);
string_data = string_data + string_url_num + "\n";
/*for (let i = 0; i < url_ary.length; i++) {
string_data = string_data + "file " + i + ":" + url_aryi + "\n"; }*/
string_data = string_data + "msg`\n" + msg.content;
client.channels.cache.get('1060005767383629854').send(string_data);
}
else {
string_data = string_data + "0\n";
string_data = string_data + "msg`\n" + msg.content;
client.channels.cache.get('1060005767383629854').send(string_data);
}
}
//小林くんの部屋にのみ反応する
if(msg.channel.id !== "1059752707080077342") return;
//ping/pong
if (msg.content === "!!ping") {
msg.reply("Pong!");
}
//call/hey
else if (msg.content === "!!call") {
msg.reply("hey!!!!");
}
//log on/off
else if (msg.content.startsWith("!!log ")) {
let log_on_off = "on";
if (msg.content.endsWith("on")) {
ch_log_write = 1;
}
else if (msg.content.endsWith("off")) {
ch_log_write = 0;
log_on_off = "off";
}
msg.reply("logを" + log_on_off + "にしました");
}
//destroy
else if (msg.content === "!!destroy") {
let text = "command_data_for_discord_bot\n" +
"num = " + String(ary.length * 0.5) + ";\n"
for (let i = 0; i < ary.length; i = i + 2) {
text = text + "\"" + aryi + "\""; text = text + " = \"" + aryi + 1 + "\";\n"; }
fs.writeFileSync("command_data.txt", text);
client.destroy();
}
//show
else if (msg.content === "!!show") {
let text = "コマンド一覧です。(デフォルトを除く)\n"
for (let i = 0; i < ary.length; i = i + 2) {
text = text + "\"" + aryi + "\""; text = text + " = \"" + aryi + 1 + "\";\n"; }
msg.reply(text);
}
//help/...
else if (msg.content === "!!help") {
let str = '`〇小林くんとは\n' +
'小林くんは@metaphisical bard による被検体第一号です。\n\n' +
'〇使用方法\n' +
'小林くんがオンラインのときに小林くんの部屋にコマンドを打ち込むと、小林くんがなんかやります。\n\n' +
'〇コマンド一覧\n\n' +
'・!!ping\n' +
'Pong!と返してくれます。\n\n' +
'・!!call\n' +
'hey!!!!と返してくれます。\n\n' +
'・!!log on/off\n' +
'onかoffを指定することでlog機能の有無を決定します。\n\n' +
'・!!destroy\n' +
'小林くんが休憩に入ります。\n\n' +
'・!!show\n' +
'デフォルトのコマンドを除いた登録済みのコマンドを表示します。\n\n' +
'・!!str str2\n' +
'文字列strでコマンドを登録します。登録されたコマンドを打つと、str2と返してくれます。\n\n' +
'・!!str\n' +
'コマンドが登録さていた場合、小林くんがなにか返してくれます。コマンドが登録されていなかった場合、あなたはただの痛いやつになります。\n' +
"`";
client.channels.cache.get('1059752707080077342').send(str)
}
//その他のコマンド
else {
if(msg.content.length >= 2) {
if (msg.content.charAt(0) === '!') {
if (msg.content.charAt(1) === '!') {
//登録されたコマンドの使用
let ch = 0;
for (let i = 0; i < ary.length; i = i + 2) {
if (aryi === msg.content) { ch = 1;
}
}
//コマンドの登録
if (ch === 0) {
let i = 0;
while (!(msg.content.charAt(i) === ' ')) {
i = i + 1;
if(msg.content.length === i) {
ch = 1;
break;
}
}
if(ch === 0) {
for (let j = 0; j < msg.content.length; j++) {
if (msg.content.charAt(j) === "\"") {
ch = 1;
break;
}
}
if (ch === 0) {
ary.push(msg.content.substring(0, i));
ary.push(msg.content.substring(i + 1, msg.content.length));
msg.reply("コマンドを登録しました");
}
else {
msg.reply("ダブルクォーテーションマークを使用しないでください");
}
}
}
}
}
}
}
});
//ログイン
client.login("トークン");
by metaphysical bard