DashでChatOpsのコマンド入力の速度と正確性を上げる

この記事は [ChatOps Advent Calendar 2015](http://qiita.com/advent-calendar/2015/chatops) の18日目です。
前日は @hiconyan さんの **[Botkit + ImgurでプルリクにLGTMする](http://qiita.com/hiconyan/items/f850a901852f7d6b56df)** でした。

## <i class="fa fa-desktop" style="font-size:1em;"></i> 概要
DashでChatOpsのコマンド入力の速度と正確性を上げる方法をご紹介します。

## <i class="fa fa-frown-o" style="font-size:1em;"></i> ChatBotのコマンド入力
Slack, Hubotの登場によりChatOpsを導入する現場が増えてきたのではないでしょうか？
ところでみなさん、ChatBotのコマンド入力ってどうしてますか？
手入力でしょうか？
**手の温もりたっぷりでしょうか？**

ChatOpsを取り入れているみなさんはおそらく普段ゴリゴリとプログラムを書いている方が多いと思います。
プログラミング時のようにコード補完をしながらサクサクと書きたくありませんか？
怠惰・短気を発揮したくありませんか？

そこで OS X 限定ではありますが **API Document Browser** として有名な **Dash** [^1] の
**Snippet** 機能を活用してみたいと思います。

## <i class="fa fa-flask" style="font-size:1em;"></i> サンプルの前提
個人的に **Slack** と **Ruboty** [^2] を利用しているのでこのふたつを前提とします。
もちろん考え方は他のチャットツールやチャットボットでも流用できます。

## <i class="fa fa-calendar" style="font-size:1em;"></i> サンプル1: ruboty-cron
手入力による設定の面倒さの代表格 **ruboty-cron** を扱ってみます。
（設定頻度が多くないので手入力でも問題ないPluginですけどね。見た目に差が分かりやすいのでサンプルに選びました。）

例えば、通常 ruboty-cron [^3] に job を追加するには以下の様なコマンドを手入力するか 
既存コマンドを探してコピーして一部を変更する必要があります。

### <i class="fa fa-hand-o-up" style="font-size:1em;"></i> 手入力の例
平日朝9時半にボットに挨拶してもらう設定です。

```
@bot-name "30 9 * * 1-5" @bot-name echo おはよう
```

![manual_ruboty.gif](https://qiita-image-store.s3.amazonaws.com/0/43480/6ac9624e-c2e3-3b02-def4-88a106679921.gif)

### <i class="fa fa-gears" style="font-size:1em;"></i> Snippetを登録
![dash_snippet_ruboty_add_job.png](https://qiita-image-store.s3.amazonaws.com/0/43480/e3dcb07b-1208-e4a4-22a9-2a8fe7aa405c.png)

|項目|設定内容|意味|
|:--|:--|:--|
|Abbreviation|`bot_add_job;;`|スニペット呼び出しのキーとなる略語|
|Body|`@__bot-name__ add job "__minutes__ __hour__ __month__ __year__ __week__" __job__`|スニペット本体 `__placeholder__` でプレースホルダーになる|
|Syntax|`None`|文法。RubotyはSyntaxが用意されていないので `None` に設定|
|Tag|`Ruboty`|スニペットの分類を管理するためのTag|

### <i class="fa fa-rocket" style="font-size:1em;"></i> Snippetを利用して登録
* インクリメンタル検索で探すパターン

![snippet_ruboty.gif](https://qiita-image-store.s3.amazonaws.com/0/43480/d3a71908-2f79-8490-8a78-c95a7333d991.gif)

* 直接入力のパターン

※この場合、 Abbreviation を暗記しておく必要があります

![snippet_ruboty_direct.gif](https://qiita-image-store.s3.amazonaws.com/0/43480/5ffa8f5b-f58e-5c12-b926-82651e347d84.gif)

## <i class="fa fa-graduation-cap" style="font-size:1em;"></i> まとめ
ChatOpsを導入しているチームは、かなりの頻度でチャットを行い  
Botを利用していると思います。  

Snippetによるメリットと

* 正確さ
* すばやさ
* 人数が増えるほど資産の共有価値が上がる

Snippet導入によるデメリット

* DashによるSnippet活用の導入コスト
* Snippetの作成コスト
* Snippetの保守コスト

これらを対比して導入するかどうか？
後続レポートなどを期待してます。

## <i class="fa fa-plus-circle" style="font-size:1em;"></i> おまけ
### <i class="fa fa-wrench" style="font-size:1em;"></i> DashのSnippet管理
DashのSnippetはGUIの登録フォームしか用意されていません。一括Importなどもありません。  
ただ、DashのSnippetのデータはSQLiteで管理されているため以下のようにDBを直接操作することが可能です。

* <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="http://tbpgr.hatenablog.com/entry/2015/12/10/235443" target="_blank">DashでGUIを利用せずSnippetを管理する</a>

いちいちSQLを実行するのは面倒なのでSnippetをtomlファイルで管理して [^3]
一括で更新できるツールを作りました。

* <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="http://tbpgr.hatenablog.com/entry/2015/12/16/001304" target="_blank">DashのSnippetをTOMLファイルで管理してrakeのコマンドで一括更新できるツールを作った</a>
* <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="http://tbpgr.hatenablog.com/entry/2015/12/16/001958" target="_blank">DashのSnippetをTOMLファイルで管理してrakeのコマンドで一括更新できるツールにdump機能を追加した</a>

よろしければご利用ください。
（自分の開発効率の都合上Rubyで作ってます。利用にはRuby環境が必要です。）

### <i class="fa fa-file-code-o" style="font-size:1em;"></i> DashのSnippet活用
Snippetといえば、エディタやIDEに組み込まれているケースが多いと思います。
Dashの場合、エディタ・IDEの外部でSnippetを管理できるのでチームメンバーのエディタ・IDE
がバラバラでもSnippetを共有できます。
ただ、エディタ組み込みのSnippetを使うよりは若干使いにくさが残るかもしれません。
あなたはどちらをとりますか？

### <i class="fa fa-diamond" style="font-size:1em;"></i> RubotyのSnippet
以下に個人的に作成したSnippetを公開しています。

* <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="https://github.com/tbpgr/dash-snippets" target="_blank">tbpgr/dash-snippets - GitHub</a>

`./ruboty` 配下に Ruboty 関連の Snippet をおいてあります。

toml形式で提供しているのでインストールするには上記のSnippet管理ツールを利用する必要がありますが、
よろしければご利用ください。

## <i class="fa fa-warning" style="font-size:1em;"></i> リスク
![dash_ruboty_miss.png](https://qiita-image-store.s3.amazonaws.com/0/43480/1d434080-a23f-461d-8b82-4dc91bddad93.png)

コマンドをミスった時に発動する雑談APIの思いがけないレスポンスを楽しんでいた方は、
その体験が失われてしまうかも。

## <i class="fa fa-calendar" style="font-size:1em;"></i> 明日の担当
[ChatOps Advent Calendar 2015](http://qiita.com/advent-calendar/2015/chatops) の19日目の担当はpapixさんです!

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="https://github.com/tbpgr/dash-snippets" target="_blank">tbpgr/dash-snippets - GitHub</a>

## <i class="fa fa-book" style="font-size:1em;"></i> 引用
[^1]: <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="https://kapeli.com/dash" target="_blank">Dash Official</a>
[^2]: <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="http://qiita.com/tbpgr/items/39d93a0a33ec99e37da1" target="_blank">Ruboty って何？どうやって動かすの？ Hubot と何が違うの？どっちを使えばいいの？</a>
[^3]: <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="https://github.com/r7kamura/ruboty-cron" target="_blank">r7kamura/ruboty-cron - GitHub</a>
[^4]: <i class="fa fa-external-link" style="font-size:1em;"></i> <a href="https://github.com/toml-lang/toml" target="_blank">TOML</a>