全裸bot for LINE

BOT API Trial Account Overview - LINE Business Center が公開されて、LINEのbotが作れるようになった、ということで 遅ればせながら自分も 過去に作ったTwitter bot を移植してみた。

テキストを受け取ってちょっと改変してオウム返しする、というのは練習としては良い題材ですね。kagome を使えばPure Goで形態素解析できるし、ということでGoで書いてみた。

source code
https://github.com/sugyan/line-zenra-bot

Callback URLにSSLが必須、送信側はIP Whilelistに登録している必要がある、ということでちょっと制限があるけれど、これくらいのお遊び程度のものならherokuで受けて fixie addonを使えばIP固定させて使うことができる。もっと本格的に使おうと思ったらちゃんとした構成を考える必要があるでしょうけども。


実装の参考に、と幾つかの記事や公開コードを読んでみたのですが Signature validationを無視しているものが多くて気になりました。

お遊び程度のデモなら気にすることもないのかもしれないけど、Callback URLに対して誰でも出鱈目なJSONをPOSTできる状態で そのまま信頼してそのデータを使うなんてとんでもない。
そんなに難しいことでもないし、ちゃんとSignature validationはしておこう。

func (bot *Bot) handle(w http.ResponseWriter, req *http.Request) {
	defer req.Body.Close()
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		...
	}
	if !bot.checkSignature(req.Header.Get("X-Line-Channelsignature"), body) {
		return nil, errors.New("invalid signature")
	}
	...
}

func (bot *Bot) checkSignature(signature string, body []byte) bool {
	hash := hmac.New(sha256.New, []byte(bot.ChannelSecret))
	hash.Write(body)
	return signature == base64.StdEncoding.EncodeToString(hash.Sum(nil))
}

※追記しました