初Qiita記事
概要
実現したいこと
botに送られたメッセージをGASでいろいろ処理して返信できるbotを作りたい。無料で。
とりあえず今回はGAS経由でオウム返しをするbotを作る。
利用するサービス
すべて無料で利用可能。すばらしい!
処理の流れ
無料版Glitch はアクセスがないと5分で落ちます。24時間稼働のために、GASの時限トリガーで5分ごとにアクセスし続けます。Discord.jsはバージョン13を使います。
多分こんな感じ。
実践
botの作成
自分のDiscordサーバーにbot用のチャンネルを用意します。Discord Portal からbotを作成し、TokenとclientIdを控えます。botを自分のDiscordサーバーに追加します。scopeはbotとapplication.commandsを選べばOK.
GASのコード
GAS自体の説明は省略。新しくプロジェクトを作成し、code.gs
を書きます。
//GASのプロパティを使いやすいように
//プロパティを使うことで機密情報のべた書きを避けられます
const P = {
prop: PropertiesService.getScriptProperties(),
get(key) {
return this.prop.getProperty(key);
}
set(key, value) {
this.prop.setProperty(key, value);
}
}
//5分おきにこの関数を実行するように時限トリガーを設定
const retainGlitch = () => {
//あらかじめ設定しておいたプロパティを呼び出す
const glitchURL = P.get('glitchURL')
const data = {}
const headers = { 'Content-Type': 'application/json; charset=UTF-8' }
const params = {
method: 'post',
payload: JSON.stringify(data),
headers: headers,
muteHttpExceptions: true
}
//特に中身のないデータをGlitchへPOST
response = UrlFetchApp.fetch(glitchURL, params);
console.log(response);
}
//Glitchからのメッセージが入ったPOSTを受け取る
const doPost = e => {
const message = JSON.parse(e.postData.contents);
//返信データを作成
const messageObj = {
'messageType': 'send',
'content': 'via GAS: ' + message.content
}
const payload = JSON.stringify(messageObj);
//json形式データを返す
const output = ContentService.createTextOutput().setMimeType(ContentService.MimeType.JSON);
return output.setContent(payload);
};
これをエディタから、だれでもアクセスできるWEBアプリとして公開し、URLを控えます。
Glitchのコード
Glitchのアカウントを作成します。New Projectからglitch-hello-node
のapp starterを選びます。package.json
内の"engines: { "node": "12.x" }
を"engines: { "node": "16.x" }
に書き換えます。画面下のTERMINALを開き、$ npm i discord.js
と$ npm i axios
を実行します。エラーが出てうまくいかなければ、$ rm package-lock.json
、$ npm init
などを実行してみてください。
# このファイル内に機密情報を書く
# = の前後には空白を開けない
# ''や""で値を囲まない
DISCORD_BOT_TOKEN={botのToken}
GAS_URL={GASのURL}
//モジュールのインポート
const http = require("http");
const axios = require('axios');
const discord = require("discord.js");
let client;
const connectDiscord = () => {
client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES, Intents.FLAGS.GUILD_MESSAGE_REACTIONS] });
client.login(process.env.DISCORD_BOT_TOKEN);
client.on("ready", () => console.log("bot is ready!"));
//送信者がbot自身でないとき、GASへPOSTする関数を実行
client.on("messageCreate", (message) => !message.author.bot ? sendGAS(message) : "");
if (process.env.DISCORD_BOT_TOKEN == undefined) {
console.log("please set ENV: DISCORD_BOT_TOKEN");
process.exit(0);
}
};
// GASにデータをPOSTする関数
const sendGAS = (message) => {
const jsonData = {
author: message.author,
content: message.content,
channel: message.channel,
};
const post = async () => {
try {
await axios({
method: "post",
url: process.env.GAS_URL,
data: jsonData,
responseType: "json",
}).then((response) => {
const msg = response.data;
//送信方法を振り分け
switch (msg.messagetype) {
case "nothing": //何もしない
break;
case "reply": //返信
message.reply(msg.content);
break;
case "send": //ただ送る
default:
message.channel.send(msg.content);
break;
}
});
} catch (error) {
message.reply("an error occurred: " + error);
}
};
post();
};
//実行
connectDiscord();
//GASからのPOSTリクエストを受け取る用
http
.createServer( (request, response) => {
console.log('post from gas')
response.end("Discord bot is active now.");
})
.listen(3000);
package.json
のAdd Packageからaxiosを検索して追加します。WEBエディタ上のShareボタンを押すと表示されるLive siteのリンクを、GASのglitchURL
に設定します。
一旦以下の関数を書いて実行すれば設定完了です。
const setURL = () => P.set('glitchURL', 'your_project_url');
結果と振り返り
-
ローカル環境を使わないのは非常にお手軽。
-
GASだけで作れるLINE botのほうが楽だった。
-
requestやrequest-promiseモジュールが非推奨とのことで、axiosというのを使ってみた。
-
GASをAPIのようにつかうのは初めてだった。
ContentService
かHtmlService
でないと値を返せないみたい。
参考にしたサイト
- Discord Botの作り方、まとめ(Node)- Qiita
- Glitchを使ってNode.js製Discord Botを動かしてみる - Qiita
- 自動応答のDiscord Botを完全無料で構築する[gas][glitch] - Qiita
追記
- Discord.js v13用に書き替えました。
- console.log()とかでやたらめったらアロー関数を使ってるのはなんでだっけ...? (←コメントを残さないバカ)
axiosではなくで標準のhttpsモジュールを使うほうがいいかも- 逆に受け取り側はhttpモジュールではなくexpressを使ったほうがいいかな
- セミコロンの有無統一しようぜ