LoginSignup
132
130

More than 5 years have passed since last update.

Slackで現実世界も記録する

Last updated at Posted at 2015-01-05

はじめに

2014年12月頃、SlackのHubot Integrationの仕様が変わりまして、Slack上でhubotが動いているURLを設定する必要がなくなりました。このおかげで、RaspberryPi上のhubotも簡単にSlackと連携させることができます。

というわけで、世の中のIoTブームに乗っかってSlackを現実世界とつなげてみましょう。

作ったもの

今回実装したのは、Slackのあるコマンドに反応してRasPiが写真を撮影、自動アップロードするという機能です。

なぜこれを実装したかと言うと、これが欲しかったんです。画像データを自動で飛ばしてくれるホワイトボード。でもお高いですよね。普通はこんなお高いやつを何台も買えないので、ミーティングのときにはiPhoneで写真を撮って、Slackにアップロードして共有しています。

これ、自動化できればお高いホワイトボード買わなくていいんじゃね?ということで作ってみました。

IMG_20150105_120156.jpg

実演

こんな感じでセッティングして...

IMG_20150105_120139.jpg

slack上でcameraと入力すると...

5.png

10数秒後の画像がポストされます!Slack APIのtokenが自分のものなので自分が投稿しているように見えますが、完全に自動で画像がアップロードされています。

RasPi設定

若干覚えていないところがあるのですが覚えている範囲で...Raspbianのインストールまでは完了している前提で。

nvmインストール

curl https://raw.githubusercontent.com/creationix/nvm/v0.11.1/install.sh | bash
source ~/.profile
nvm install 0.10

npmインストール

追記:nvmインストールしたらnpm付いてきますね...不要です

git clone git://github.com/isaacs/npm.git
cd npm/scripts
chmod +x install.sh
sudo ./install.sh

Webカメラ設定

sudo apt-get install fswebcam

hubotスクリプト

コードはGithubに置いていますので、cloneしたら使えるはず。スクリプトはこんな感じ。今回は市販のWebカメラを使用しているのでfswebcamコマンドで撮影しています。RasPi用カメラモジュールを使う場合はここをraspistillに置き換えたら動くはず。

node.jsからmultipartのリクエストを投げるのがどうしても出来なかったので、しょうがなくcurlコマンドを叩いて画像をアップロードしています。どなたかいい感じの書き方をご存知の方、コメントなりPullRequestなりお願いします。

/scripts/camera.coffee
module.exports = (robot) ->
  exec = require('child_process').exec
  Slack = require 'slack-node'
  slack = new Slack process.env.SLACK_API_TOKEN
  DIR = '/tmp/'

  robot.hear /camera/i, (msg) ->
    channel = msg.message.room
    fileName = "#{getNow()}.jpg"

    console.log "rcv"
    exec "fswebcam -S 50 -r 1920x1080 --no-banner #{DIR}#{fileName}", (err, stdout, stderr) ->
      if err
        return msg.send "Failed " + err

      postSlack channel, fileName, (err, res) ->
        if err
          return msg.send "Failed " + err
        msg.send "OK"

  postSlack = (channel, fileName, callback) ->
    getChannelFromName channel, (err, id) ->
      if err
        return callback err
      exec "curl -F file=@#{DIR}#{fileName} -F channels=#{id} -F token=#{process.env.SLACK_API_TOKEN} https://slack.com/api/files.upload", (err, stdout, stderr) ->
        exec "rm -f #{DIR}#{fileName}", (err, stdout, stderr) ->
          if err
            console.log "failed to delete file"
        if err
          return callback err
        callback null, 'OK'

  getChannelFromName = (channelName, callback) ->
    slack.api "channels.list", exclude_archived: 1, (err, response) ->
      if err
        return callback err

      if !response.ok
        return callback response.error
      for val, i in response.channels
        if val.name == channelName
          return callback null, val.id

      return callback err 

  getNow = () ->
    date = new Date
    y = date.getFullYear()
    m = date.getMonth() + 1
    d = date.getDate()
    h = date.getHours()
    M = date.getMinutes()
    s = date.getSeconds()

    return "#{y}#{m}#{d}#{h}#{M}#{s}" 

おわりに

IoT連携まで来るといよいよSlackはただのチャットツールじゃないなと。チャットであり、コマンドラインであり、すべてのインタフェースに成り得る。自分の想像力でプロジェクトをもっと面白いものにしていきましょう!

132
130
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
132
130