LoginSignup
8
3

More than 5 years have passed since last update.

某先輩botの開発 ~前編~

Last updated at Posted at 2018-07-15

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

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

8
3
0

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
8
3