読者です 読者をやめる 読者になる 読者になる

API Gateway + Lambda で Marvel のキャラクター画像を自動返答する Slack Bot を作った

温泉ハッカソンの中で Marvelite Gem を使ったスクリプト を書いてみたんだけど,せっかくなら最近気になってた API Gateway + Lambda を試してみようと思って,Node から Marvel Comics API を叩く方向性に変えた.結果的に Marvel Comics API を使って Slack でキャラクター画像を自動返答する Bot を作った.

ParrotBot

まず,本実装に入る前に Slack + API Gateway + Lambda の疎通確認をしておきたかったので,Slack から飛んでくる Outgoing Webhooks のパラメータをパースして「オウム返し」するだけの Bot を作ってみた.ParrotBot と名付けた.

Slack の Incoming Webhooks でポストする部分は前回のエントリーに書いた通り.Outgoing Webhooks のところは後述する.

Slack で

parrotbot xxx

と書くとそのまま「オウム返し」をしてくれるようになった!

ただ Bot から o って謎のメッセージ飛んでくるのは原因不明で,温泉ハッカソンの時間も限られてたので未解決のまま.誰か教えて!

f:id:kakku22:20150831145301p:plain

コードは playground に置いてある.

MarvelBot

次に ParrotBot をベースに Marvel のキャラクター画像を自動返答する Bot を作った.MarvelBot と名付けた.

Node から Marvel Comics API を叩くところは既に優秀なラッパーライブラリがあったので,それを使った.

Slack で

marvelbot xxx

と書くとキャラクター画像を返してくれるようになった!カッコイイ!

f:id:kakku22:20150831145309p:plain

コードは playground に置いてある.

キャラクター画像は standard_amazing 固定だけど雑に生成した.

function(res) {
    image_path = res.data[0].thumbnail.path;
    image_extension = res.data[0].thumbnail.extension;
    image_size = 'standard_amazing'
    return image_path + '/' + image_size + '.' + image_extension;
}

学んだことなど

試行錯誤を繰り返しながら学んだことなどを簡単にまとめておこうと思う.

Lambda で出るエラー

Lambda を動かすとたまに以下のエラー出るけど,単純にシンタックスエラーが原因だったりするので,CloudWatch のログを見て直す.

{
  "errorMessage": "Process exited before completing request"
}

Lambda Blueprint

Lambda Blueprint (青写真って意味) っていうメニューが増えてて,汎用的に使える具体的なユースケースが知れて良いなぁと思った.前に Lambda を使ったときは無かったし最近の機能?

f:id:kakku22:20150831212810p:plain

Mapping Templatesの設定

Slack の Outgoing Webhooks をトリガーにする場合,API Gateway の Integration Request で Mapping Templates に Content-Type を指定しておく必要がある.

application/x-www-form-urlencoded に対して Template に以下のコードを入力する.

$input.json('$')

Outgoing Webhooks のパラメータ

Outgoing Webhooks を使う場合,以下のようなパラメータが飛んできて Lambda の event に設定される.なので自分でパースして text の部分を取得する必要がある.

token=XXXXXXXXXXXXXXXXXX
team_id=T0001
team_domain=example
channel_id=C2147483705
channel_name=test
timestamp=1355517523.000005
user_id=U2147483697
user_name=Steve
text=googlebot: What is the air-speed velocity of an unladen swallow?
trigger_word=googlebot:

ちなみに JSON ではなくシンプルなテキストとして飛んでくる点と,半角スペースが + になっているところをケアしておく.雑に書くとこういう感じでメッセージを取得できる.

event.split('&')[9].split('=')[1].replace(/\+/g,' ');

詳しくは Slack のドキュメントを読む.

Trigger Word を絶対に設定する

Outgoing WebHooks で Trigger Word を絶対に設定するようにする.

最初 Trigger Word を設定しないで動作確認をしたら Outgoing と Incoming の会話が無限ループになって,数分で Marvel Comics API の日次アクセス上限に達してしまってワロタw

本来やりたかったこと

今回は Slack Bot を作ったけど,本来は Elasticsearch の Head Plugin でノード名のところにキャラクター画像を表示して「ノードを管理しながら Marvel も詳しくなれて一石二鳥じゃん!」っていう謎な Chrome 拡張を作りたかった!!!

f:id:kakku22:20150831220658p:plain

まぁ今回 API まで作ったからすぐできそう.ちなみに以下のキャプチャに出てる Colleen Wing はこのキャラクターですwww

まとめ

良かったこと

  • 温泉最高!(ハッカソンは?w)
  • ずっと気になってた API Gateway + Lambda を試せて良かった
    • 本当に EC2 無く API が作れてしまう時代なんだなと感動した
    • API Gateway も Lambda も管理コンソール上でテストできて本当に助かる
  • API Gateway 経由で Lambda を呼び出してうまく動かないときなどは Lambda のログを CloudWatch で確認できてデバッグできる

困ったこと

  • Lambda から遷移する場合とメニューから遷移する場合で API Gateway の管理コンソールの導線が違くて「あの画面どのリンクから飛ぶの!」って何回も悩んだ
  • Slack Integrations の使い方を間違えてるかも
    • Bot から o って謎のメッセージ飛んでくるし...なんで?誰か教えて!
  • Node 未経験すぎる
    • 最低限勉強しとかないとって焦ってる

関連エントリー(参考にした)

Lambda 関連のエントリー

ちょっと前だけど GW に Lambda に入門したときのエントリーも載せておく.