Slackに匿名で画像を投稿できるようにした


はじめに

Slackで匿名チャンネルを作りました。
直接聞きにくい相談やちょっとした雑談で使えるので便利です。

「画像も投稿できたらコミュニケーションの幅が広がるのでは?」と思ったのがきっかけで、
画像も匿名で投稿できるようにしました。

処理の流れとしては、
1. BotにDMで画像を送信する
2. Botが画像を受け取ったら、ローカルに保存する
3. 指定したチャンネルに保存した画像をBotが代わりに投稿する
4. ローカルに保存した画像を削除する
5. 終わり
となってます。

JavaScript初心者なので至らない点もあると思いますが、ご了承ください。

準備

この記事を参考に、

  • ワークスペース内で使うSlack Botの作成
  • API Tokenの取得
  • Botkitのインストール

を行ってください。

説明のために、今回作成したBotの名前は"anonymous_bot"とします。

BotとChannelのIDを取得

先ほど取得したAPI Tokenを使って、Botと匿名で投稿したいチャンネルのIDを取得してください。

  • BotのIDを取得
    https://slack.com/api/users.list?token=さっき取得したAPI_Token
  • ChannelのIDを取得
    https://slack.com/api/channels.list?token=さっき取得したAPI_Token

取得できるIDは、大文字のアルファベットと数字の組み合わせになっているはずです。
例:ABC0ED123

プログラムの作成

以下のプログラムをコピペしてください。

slack_bot.js
const Botkit = require('/path/to/Botkit.js');
const os = require('os');
const fs = require('fs');
const download = require('download');
const https = require('https');
const del = require('delete');

const slackBot_id = 'BotのID';
const channel_id = '投稿したいChannelのID';
const token = '取得したAPI Token';

var controller = Botkit.slackbot({
    debug: false,
});

var bot = controller.spawn({
    token: token
}).startRTM();

controller.on('file_shared', function(bot, message){

    if(message.user_id != slackBot_id){ //Bot自身の投稿には反応しない
        const messageObj = {
            token: token,
            file: message.file_id
        };

        bot.api.files.info(messageObj, function(err, res){
            if(err){
                console.log(err)
            }

            else{
                console.log('[file_shared] on');
                var now = new Date();
                var file_name = now.getFullYear()+':'+(now.getMonth()+1)+':'+now.getDate()+':'+now.getHours()+':'+now.getMinutes()+':'+now.getSeconds()+'.jpg';
                var file_dir = '/path/to/image_dir/';
                var file_path = file_dir + file_name; //ローカルに保存する際のディレクトリとファイル名
                var file_url = res.file.url_private_download;//送信された画像のURL

                var options = {
                    'method': 'GET',
                    'hostname': 'files.slack.com',
                    'path': file_url,
                    'rejectUnauthorized': 'false',
                    'headers': {
                    'Authorization': 'Bearer ' + token
                    }
                };

                var file = fs.createWriteStream(file_path);
                var responseSent = false;

                //URL先の画像をローカルに保存
                https.get(options, response => {
                    response.pipe(file);
                    file.on('finish', () => {
                        file.close(() => {
                            if(responseSent) return;
                            responseSent = false;
                        });//file.close
                    });//file.on
                });//https.get
                console.log('file download');

                //時間差で画像の送信→画像の削除を行う
                setTimeout(() => {
                    const messageObj = {
                            file: fs.createReadStream(file_path),
                            filename: file_name,
                            title: file_name,
                            channels: channel_id
                    };
                    bot.api.files.upload(messageObj, function(err, res){
                        if(err){
                            console.log(err);
                        }

                        else{
                            console.log('file upload');
                        }
                    });//bot.api.files

                    setTimeout(() => {
                        del([file_path], function(err, res){
                            if(err){
                                console.log(err);
                            }

                            else{
                                console.log('file delete');
                            }
                        });//del
                    }, 1000);//setTimeout
                },1000);//setTimeout

            }//else
        });//bot.api.files
    }//if

    console.log("finish");
});//controller.on

実行方法

# Botの起動
$ forever start slack_bot.js 

# Botの停止
$ forever stop slack_bot.js

BotにDMで画像を送ると、

Botが指定したチャンネルに代わりに投稿してくれます。