HubotとTypeScriptで翻訳Slack botを作ってみた

わたしもSlack botとやらをつくってみます。
Slackにbotがいないとなんか寂しい。研究室Slackに何か作ろう。

# botの仕様

* 無料 ← 研究室に対して1円たりとも出費したくないため
* hubot ← slack botで調べると大量に出てきてウザいくらいなので使ってやんよ
* 静的型付け ← いつも型間違えてエラー出すから言語レベルで助けてほしい

で、何を作るか考えて、
「日本語投稿を英語に翻訳」
で決定。弊研には留学生がおり、日本語投稿は推奨されない。

以上の条件を満たすモノ:

* Heroku
* Microsoft Translator API
* TypeScript

Scala.jsも一瞬考えたけどScalaは書いたことあるのでボツ。
http://qiita.com/ara_ta3/items/5a222a44957ca6e29fff

# TypeScriptを入れる

https://www.typescriptlang.org/

> The command-line TypeScript compiler can be installed as a Node.js package.

```sh
npm install -g typescript
```

バージョン2.0.10が入った。

# Hubotを入れる

http://blog.seeds-std.co.jp/entry/2125.html
によれば、以下のものを入れるといいらしい。

```sh
npm install -g hubot hubot-slack yo generator-hubot
```

## 試しに生成してみる

```sh
yo hubot
```

とやるとbot名等々を聞かれるので、適当に設定。  
生成物は.jsonとbinとnode_modulesとscriptsといったところで、構造はかなり簡単。

# TypeScript --> JavaScript

目標は「.tsから.jsを生成」。問題点はJavaScript用に作られたものを使おうとする時に型定義ファイル(.d.ts)が必要なこと。

Hubot用の型定義ファイルは
http://qiita.com/itoshiki/items/65d24b197d830054f501
のお力を借りる。もしかしたら誰かががっつり書いてる？でもこの記事で足りたのでOK。

tsconfig.jsonとtypings.jsonの力を借りると便利。めっちゃ便利。
tsconfig.jsonは `tsc --init` で作ることができ、

```sh
tsc -p tsconfig.jsonがあるディレクトリ
```

でjs生成。

typings.jsonは必要な型定義を `typings search ライブラリ名` で探し、 `typings install` で拾う。有名どころのライブラリなら存在している、ハズ。

# 実際に作ってみる

## Herokuに乗せる

1. 作ったHubotをHerokuにポイ。 
1. Slackの適当なチャンネルをクリックして「+ Add an app or custom integration」を選ぶと、ブラウザが立ち上がって飛ばされる。
1. 入力欄にHubotと入れて検索するとHubotが出てくるので「install」。
1. 適当に名前をつける。他、適当に設定。
1. トークンが出るので、 `heroku config:set HUBOT_SLACK_TOKEN=トークン` をする。

これだけ。あとはinviteしておく。
生成時にできるexample.coffeeの `robot.hear /badger/i, (res)` を動かすと、

<img width="493" alt="slackbot.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/84589/0a364487-0dd0-91d0-9c46-e0bca762ba5d.jpeg">

こんな感じ。

最近の設定事情はこの辺を参考に。
http://qiita.com/KeitaMoromizato/items/0ee11d795d18a49538d8

## Microsoft Translator API

いつものDataMarketは今年度いっぱいで終わってしまうので、
https://azure.microsoft.com/ja-jp/services/cognitive-services/translator-text-api/
から。

流れは

1. 登録して得られたKeyをAuthentication Token API for Microsoft Cognitive Services Translator APIに投げてjwtゲット
2. jwtといっしょにText Translation APIを使う

という感じ。つまりいつも通り。
Tokenを発行してからTranslator APIを叩く流れは変わらない。

oauth:
http://docs.microsofttranslator.com/oauth-token.html

```ts
import https = require('https');
import querystring = require('querystring');

let httpsRequest = https.request({
  host: 'api.cognitive.microsoft.com',
  path: '/sts/v1.0/issueToken',
  method: 'POST',
  headers: {
    'Ocp-Apim-Subscription-Key': キー
  }
}, function (result) {
  // result.on('data'〜 でがんばる
});
httpsRequest.write(querystring.stringify({}));  // 多分必要
httpsRequest.end();
```

本命:
http://docs.microsofttranslator.com/text-translate.html

```ts
https.get({
  host: 'api.microsofttranslator.com',
  path: `/v2/http.svc/Translate?appid=Bearer%20${上で取ったとーくん}&text=${翻訳する文章}&to=${翻訳先の言語}`
}, function (result) {
  // result.on('data' 〜
});
```

<img width="244" alt="slack_trans.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/84589/4409cad4-e7d1-bf14-2c93-1c41e8042b29.jpeg">

できた！

## 日中起きていてもらう

深夜帯にSlackを送る奴はいないと信じて、深夜帯に寝て日中起きてもらう設定をする。

http://qiita.com/misopeso/items/8cde2ecbb82e7bfc01b4
http://sota1235.hatenablog.com/entry/2015/06/10/130000

# わかったこと

Azureのkeyとかreferenceを発掘するまで大変。
今までDataMarketに属していた諸々がAzureでまとまってくれたので、UIや仕様に慣れてしまえばすぐかも。

TypeScriptの仕様を理解するまで大変。
よくある静的型つきほど型がはっきりしないので(私には)まだ辛い。
あと、古い情報とか、ブラウザ用?の関数とか、Angular.jsとかが検索妨害してきてしんどかった。

「Slack botをHubotでつくってHerokuで運用する」のはめちゃくちゃ簡単。
これはマジ。

# 感想

Node.js初めて+新生翻訳API初めて+jsはコピペしかしたことない+ts初めて
だったので、割と無謀企画になった上に風邪引いて泣いた。

投稿が遅れて申し訳ありませんでした。