Quantcast
Channel: Slack Advent Calendarの記事 - Qiita
Viewing all articles
Browse latest Browse all 24

某先輩botの開発 ~前編~

$
0
0

Merry Christmas!!

この記事は何?

円滑なコミュニケーションのため, 多機能なSlack botを作ったので雑に紹介します
スクリーンショット 2018-07-15 18.33.54.png

先輩には画像検索やYahoo!ニュースの表示, 電車の遅延情報の表示, 語録を喋る, サイコロを振る, arxivURLを展開する等の機能が搭載されています.

コード

ソースコードはこ↑こ↓
https://github.com/motacapla/hubot-slack-docker

Slack上で登録したスタンプもbotから投稿できます, その他のdemoは記事の最後にあります:
parrot-party.mov.gif

動作環境

git cloneされているものとしてお話を進めます.
あとポータビリティを高くするためdockerを使います(ローカル→AWSインスタンス上へスムーズに移行出来ました)

  • docker
  • docker-compose

ローカルで検証したい場合は, node.jsとnpmはnodebrewを導入すると楽です:
https://qiita.com/taketakekaho/items/dd08cf01b4fe86b2e218

Slack側でhubotを追加する必要があります:
https://qiita.com/mochidamochiko/items/29c2d77715d8a1ff062a

また, arxivのURL展開機能を使うためにはWeb 着信 フックのAPIも追加する必要があります:
https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008

画像検索の機能を持たせるためには, 以下の導入が必要です(in English):
https://github.com/hubot-scripts/hubot-google-images
(検索にはGoogle Custom Search APIを使います)

dockerのインストールからslack上でのhubot動作確認までは以下の記事が参考になりました:
https://qiita.com/miyamiya/items/91d1bac25764a24e820e
https://qiita.com/tubone/items/11a7ceb3e7013139abab

Dockerを使う

色々インストールするのですが, いちいち覚えておくのも面倒くさいので, dockerを使っています. あと, docker-composeが便利なのでコチラを使うこととします.
https://qiita.com/youtanagai/items/ff67ceff5497a0e0b1af

Dockerfile

nodeのイメージからhubot用のimageを作ります.
usernameなどは適宜変更してね
後で知ったけど, このADDを使っているところはCOPYのほうが望ましい?らしい

Dockerfile
FROM node
MAINTAINER tikeda

ENV TZ JST-9

RUN npm install -g yo generator-hubot
RUN npm list -g yo generator-hubot
RUN useradd bot
RUN mkdir /home/bot && chown bot.bot /home/bot

USER bot
WORKDIR /home/bot
RUN  yo hubot --owner "tikeda" --name "yaju-bot" --description "ikisugiii" --adapter slack

CMD cd /home/bot/hubot
RUN npm install cheerio-httpcli --save
RUN npm install cron --save
RUN npm install hubot-google-images --save
RUN npm install hubot-slack-attachment --save

ADD ./scripts/* ./scripts/
ADD package.json package.json

CMD ["bin/hubot", "--adapter", "slack", "-n", "yaju"]

docker-compose

arxivのURLを展開する機能を使うため, 着信WebフックのWebhook URLを使っています.(マークダウンでかっこよくPOSTする必要がない場合は不要です.)
あと環境によってはversionを3にしろとかポートが使われてるとか怒られますので, 適宜変更してやります.
ローカル↔コンテナにおけるファイルのやり取りを実現するため, ./mnt以下をマウントしてやります.こうすると例えばTODOリストであったり, 勤怠管理の機能なども作ったりできる(作るとは言ってない)

docker-compose.yml
version: '2.2'
services:
  yaju-bot:
    container_name: hubot
    build: . 
    image: yaju-bot
    volumes:
      - ./mnt:/mnt  
    ports:
      - "8888:8888"
    environment:
      - HUBOT_SLACK_TOKEN=Slackに追加したhubotAPIのトークン(xoxb-*のやつ)
      - HUBOT_GOOGLE_CSE_ID=Google Custom Search APIのID
      - HUBOT_GOOGLE_CSE_KEY=Google Custom Search APIのKEY
      - HUBOT_SLACK_INCOMING_WEBHOOK=Slackに追加した着信 Web フック
のWebhook URL

動作確認

適切にdocker-composeの環境変数を埋めてあげれば, 動作すると思います.
基本的に, 以下のコマンドだけ使えば良いです.

ビルドからコンテナとbot起動まで
$ docker-compose up -d --build

起動したら, slackのbotを招待してpingしてみましょう.
PONGが帰ってくれば疎通確認okです.

コンテナとイメージ削除
$ docker-compose down --rmi all

イメージごと消すときはオプション--rmi allをつけます. 基本的に毎回付けていいと思います.

機能の追加

自作した関数は./scripts/配下のyaju-bot.coffeeに追加してあげれば良いです. 僕はcoffee-scriptで書いてます(というか人のをパクっていい感じに改良してます)が, node.jsなども動きます.

yaju-bot.coffee
cron = require('cron').CronJob
path = require('path')
cheerio = require('cheerio-httpcli')
exec = require('child_process').exec
msgs = require('../mnt/meigen.json')
arxiv = require('arxiv')
module.exports = (robot) ->
        #淫夢語録を返す機能. respondの場合, メンション付きのmeigen*に反応する. *はワイルドカード.
        robot.respond /meigen(.*)/i, (msg) ->     
                #もしmeigen-allであったら, 名言リストのファイルの中身を全て吐き出す
                if msg.match[1] == '-all'
                        msg.send "@#{msg.message.user.name} *全名言リスト* \n #{msgs}"
                #違うのであればランダムにsend
                else                                
                        message = msgs[Math.floor(Math.random() * msgs.length)]
                        msg.send "#{message}"

        #サイコロを振る機能. hearの場合, メンションなし roll という文字に反応する.
        robot.hear /roll/i, (msg) ->
                max = 100
                min = 1
                range = Math.floor(Math.random() * (max - min) + min)
                msg.send "[#{min}-#{max}]: #{range}"

関数を作りたい場合はここに追加して, どうぞ
あとTab文字にはくれぐれも気をつけてください!インデント云々で怒られ続けてハマりました

demo

例えばYahoo!ニュースは @botの名前 newsで取得できます:
news.mov.gif

arxivのURLはポストされたら勝手に展開してくれます(ただし着信Webフックを使う場合は, 特定のチャンネルでしかsend出来ない?)
arxiv-url.mov.gif

Google Custom Search APIを使うと, animateとimageが使えます. それぞれgifとjpg(or png)を適当に拾ってくるようです:
animate.mov.gif
imageme.mov.gif

疲れたのでプルリクお願いします!何でもしますから!


Viewing all articles
Browse latest Browse all 24

Trending Articles