ファイルをアップロードするSlack Botを作る

先日書いたSlack Bot を作るでは、単純なオウム返しする Slack bot を作りました。
今回はそれを拡張してファイルアップロードする Slack bot を作成します。


目次

参考

権限設定

ファイルをアップロードするにあたって、bot に対して権限を追加する必要があります。
Slack Bot を作るにて chat bot としての設定を行った後に、
以下の通り設定を追加します。

「OAuth & Permissions」を開く

「Add an OAuth Scope」を押し、権限を選択する。

「files:write:user」を追加する。

権限を変更すると、アプリの再インストールが要求されるので、再度インストールします。
「あなたに代わりファイルをアップロード、編集、削除する」となっているのを確認します。

権限変更に関する処理はここまでです。

準備

今回ファイルのアップロードを行うにあたって、アップロード用のファイル upload.txt を用意します。

upload.txt
1
アップロードするファイル

こちらを用意した、ディレクトリは以下の通りになります。

1
2
3
4
5
6
7
8
.
+---files
| +---upload.txt #アップロード用のファイル
+---node_modules
\---src
+---use_direct_api.js
\---use_slackbots.js

実装

slackbots にはファイルアップロードの機能が用意されていないようだったので今回は断念。
@slack/web-api と”@slack/rtm-api を使うパターンのみ紹介します。

実装

use_direct_api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const { createReadStream } = require("fs");
const { WebClient } = require("@slack/web-api");
const { RTMClient } = require("@slack/rtm-api");

const token = "[控えておいた Bot User OAuth Access Token]";

const web = new WebClient(token);
const rtm = new RTMClient(token);

const uploadfilename = "upload.txt";

rtm.on("connected", () => {
web.chat.postMessage({
text: "Hello world!",
channel: "general",
});
});

rtm.on("message", async (event) => {
console.log(event);
if (
event.type != "message" ||
event.subtype == "bot_message" ||
event.files != undefined
)
return;

if (event.text === "upload") {
await web.files.upload({
title: uploadfilename,
channels: event.channel,
initial_comment: `${event.text} on ${uploadfilename}`,
file: createReadStream(`./files/${uploadfilename}`),
});
} else {
web.chat.postMessage({
channel: event.channel,
text: event.text,
});
}
});

rtm.start();

確認

以下のコマンドで bot のプログラムを起動する。

1
node use_direct_api.js

uploadと送ると、slack bot がファイルをアップロードしてくるようになります。

画像を見るとわかるのですが、ただのメッセージを送ってくる testapp とファイルを送ってくる testapp は異なります。
詳細を調べるとわかることですが、ただのメッセージでは、subtype: ‘bot_message’という値を持っています。しかし、ファイルをアップロードするメッセージでは、subtype: ‘bot_message’を持ちません。
bot からのメッセージなのか判断ができません。
subtype: ‘bot_message’を持たない結果、ファイルを送信したメッセージに、自分でオウム返ししてしまうので以下のように処理します。

1
2
3
4
5
if (
event.type != "message" ||
event.subtype == "bot_message" ||
event.files != undefined
)

event.files != undefinedに合致する。すなわち、ファイルを持っている場合は、反応しないようしました。

この点については、アプリケーションのインストールで、
「あなたに代わりファイルをアップロード、編集、削除する」となっているのが理由と推察しました。


今回は、slack bot にファイルのアップロードをさせました。
事前に保管したファイルをアップロードしましたが、例えば「カメラを接続した Raspberry Pi を用意して、メッセージを送ると写真を返す。」ということができそうです。

ではでは。