そこに仁義はあるのか(仮)

略してそこ仁!

slack botで開発や運用をちょっと楽にする

弊社がDialogPlayを開発・リリースしました!すごい!!かっこいい!!使いたい!!ですが、その話は一旦おいておいて…
私たちのチームでも、DialogPlayほどいろんなことができるわけではないのですが、チームでの開発・運営のなかでbotを使っています。
現在、私の所属しているチームではslackを使っているのですが、いくつかbotが入っていて、それぞれ開発・運用にちょっと役立つサムシンをしています。

f:id:syobochim:20170428110815p:plain

🤖 botが何をやっているか

現在動いているbotたちです。現在3匹稼働しています。
愛着がある名前をbotにつけています。

  • rascalくん (Created by @ さん)
    • コミュニケーションを生み出す
  • 224くん(Created by @ さん)
    • システムが死んで(死活監視NG)いたら教えてくれる
  • syobochirnちゃん(Created by @ ※私です)
    • JenkinsでJOBがこけたら通知する
    • 224くんやJenkins JOBの通知から、やらなきゃいけないことを教える
    • ランダムもしくは曜日決めで 担当者をアサインする

🤖 rascalくん

rascalくんについては、↓の記事に詳細が書いてあります。
チーム力向上のためのエトセトラ - Qiita

メンバーがslackで話した会話を覚えて、形態素解析をして、で、言葉を組み合わせて発言をしてくれます。
ちょっと仕事に飽きてきて、一息いれたい、となったとき(だいたい14時~15時とかくらい)は、rascalくんとチームメンバーが会話していたりします。

f:id:syobochim:20170427165410p:plain

チームの雰囲気をほっこりさせてくれる効果があるのですが、誰に似たのか、乱暴な言葉を使うようになってしまいました。


🤖 224くん

いちばん真面目に働いているbotです。
死活監視をしていて、システムに問題があったら教えてくれます。

f:id:syobochim:20170427165648p:plain

AWSでの、死活監視の構成はこんな感じになっています。

f:id:syobochim:20170501110839p:plain

🤖 syobochirnちゃん

  • JenkinsでJOBがこけたら通知します。
  • 224くんやJenkins JOBの通知から、やらなきゃいけないことを教えます。
  • ランダムもしくは曜日決めで 担当者をアサインします。

f:id:syobochim:20170428113507p:plain

f:id:syobochim:20170427170652p:plain

👀 Jenkinsからの通知

Slack Plugin - Jenkins - Jenkins Wikiを使っています。
導入がとても簡単で、30分くらいでslack通知をすることができるようになりました。٩( ´ω` )و

Jenkinsからの通知がslackに飛んで来ると、問題があったときの検知が早くなり、結構便利です。
ただ、通知が多すぎるとノイジーになり、通知を無視するようになってしまうので、何を通知して何を通知しないかは見直したりしています。

👀 アサインする

レビュー依頼や障害対応をするときに、ランダムに担当者をアサインをしています。(一人に負荷がかからないようにするため。)
あとは、当番制のもの(夕会の司会とか…)に対して、担当者をリマインドしています。(当番制のものって、担当を忘れてたときに「忘れないで!」っていう側も「忘れてた!」ってなる側も心が消耗する気がするので、botでリマインドすることで運営をストレスレスにする。)

🔧 どうやって作ったか

最初はslackbotを使っていたのですが、↓の理由から、slackclientを使うよう変更しました。(※slackbotでも同じことできるよ!であればごめんなさい。)

  • Jenkins通知のデータ構成に対応したかった
  • Thread形式でリプを返したかった

slackclientの説明はHow To Write A Slack Bot — End to End – Julian Martinez – Mediumがわかりやすかったです。

🔧 ハマったこと

↑のslackclientを使った理由の一つめにも書きましたが、Jenkinsからの通知は、メッセージの構成が普通のメッセージとは違っていたので、ちょっとだけ苦労しました…!。゚(゚´ω`゚)゚。

通常のメッセージはこんな構成になっているので、 "text" の値を見ればある程度の処理ができます。
slackbotは "text" のメッセージを取得する場合に、とても便利です。

{
  'type': 'message',
  'user': 'xxxxxxx',
  'text': 'やっほー!',
  'team': 'yyyyyyy',
  'channel': 'zzzzzz',
  'event_ts': 'aaaaaa',
  'ts': 'bbbbbb'
}


でも、Jenkinsからの通知は↓のようにちょっとオシャレ(?)になっていて、普通のメッセージとは構成が違いました。
f:id:syobochim:20170501111902p:plain

{
  'type': 'message',
  'user': 'xxxxxxx',
  'text': '',
  'team': 'yyyyyyy',
  'attachments': [
    {
      'fallback': 'ここにメッセージが入る - #25 Still Failing after 23 sec (<http://xxxxxx/jenkins/job/xxxxxx/25/|Open>)\n aaaaaa.',
      'id': 1,
      'color': 'D0D0D0',
      'fields': [
        {
          'title': '',
          'value': 'ここにメッセージが入る - #25 Still Failing after 23 sec (<http://xxxxxx/jenkins/job/xxxxxx/25/|Open>)\n aaaaaa.',
          'short': False
        }
      ],
      'mrkdwn_in': [
        'pretext',
        'text',
        'fields'
      ],
      'from_url': 'https://cccc.slack.com/archives/~~~~~',
      'is_share': True
    }
  ],
  'channel': 'zzzzzz',
  'event_ts': 'aaaaaa',
  'ts': 'bbbbbb'
}


slackclientはメッセージを割とそのまま操作することができるので、こんな感じ↓でデータをとっていろんな情報を取得し、処理することができました。
Threadの位置も取得できるので、スレッド形式で返信する、という処理も簡単でした。

listdata = sc.rtm_read()
attachments = listdata[0]["attachments"][0]
message = attachments["fallback"]
channel = listdata[0]["channel"]
ts = listdata[0]["ts"]

🤖 さいごに

初めはbotを軽い気持ちで導入したのですが、意外と便利でどんどんアレもしたい、コレもしたい、となっていきました!
何かが起こった時に通知がリアルタイムなことや、プチ運用手順書として使えるのはやっぱり便利です。

「あれを言ったらこれを返す」という単純なbotを作る場合は、slackbotがサラッと作れていいんじゃないかなーと思います。
また、「この曜日のこの時間にこう言って欲しい!」(当番のリマインド)は、botでなくリマインダで簡単に設定できちゃうので、そこから始めてもいいのではと思います。(参考:slack の /remind 機能まとめ - Qiita