Serverless を使って 簡単なLine Bot を作った話 


勉強会の話すネタ作りに、ちょっと試してみました。

完全に動かしてみた、的な感じなので動作保障は無いですが、誰かの参考になればと思います。

## 準備

### serverless のインストール

````
$ npm install -g serverless
````

### AWS ユーザの作成

`~/.aws/credential` がない場合、ユーザを作成してほげほげする。

````
$ aws iam create-user --user serverless-bot
$ aws iam create-access-key --user-name serverless-bot
$ aws iam attach-user-policy --user-name serverless-bot --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
````

キーなどを `~/.aws/credential` に貼っつけて完了

### Line Bot 作成の準備

Line Notify を利用して簡単なHTTP通信でメッセージ送信が可能。

開発者ドキュメントは[こちら](https://notify-bot.line.me/static/pdf/line-notify-api_ja.pdf?v=1.0)から確認できる。

Oauth 実装はテスト利用するには面倒なので今回は下記のマイページから発行できる、自分用トークンを利用して実装。

https://notify-bot.line.me/my/

なおAPIはBearer認証でトークンさえ手に入れれば後は楽ちん。

## コードの作成

まずは以下のコマンドでスケルトンを作成

````
$ mkdir serverless-bot
$ cd serverless-bot
$ serverless create --template aws-nodejs --name serverless-bot
````

スケルトンとして 以下 3つのファイルが出来る。

- event.json : 関数のテスト実行で利用するパラメータファイル
- handler.js : 関数を記述するJSファイル
- serverless.yml : いろいろ設定とか記述するファイル

とりあえず Line にメッセージを送信してみる。

今回、HTTP通信にはsuperagent を使用するので、npmでインストールしておく。

````
$ npm init
$ npm i superagent -S
````

メッセージを送信するための関数を `handler.js`に追加

````
const request = require("superagent")

module.exports.line = (event, context, callback) => {
  request
      .post('https://notify-api.line.me/api/notify')
      .send({ message: 'ねえねぇ' })
      .set('Content-Type', 'application/x-www-form-urlencoded')
      .set('Authorization', 'Bearer xxxxxxxxxxx')
      .end(function(err, res){
        const response = {
          statusCode: 200,
          body: JSON.stringify({
            message: 'Go Serverless v1.0! Your function executed successfully!',
          })
        };
        callback(null, response);
      })
};
````

関数をサービスとして登録するので、serverless.yml を編集

````
functions:
  line:
    handler: handler.line
    events:
      - schedule: rate(10 minutes)
      - http:
          path: serverless/line
          method: get
````

今回はスケジュールとHTTPの２つをイベントとして登録し、動作をテストしてみる。

## deploy / debug / logging 

以下のコマンドでデプロイを実行する。

````
$ serverless deploy -v 
....中略.....
Service Information
service: serverless-bot
stage: dev
region: us-east-1
api keys:
  None
endpoints:
  GET - https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/serverless/line
functions:
  serverless-bot-dev-hello: arn:aws:lambda:us-east-1:xxxxxxxx:function:serverless-bot-dev-hello
  serverless-bot-dev-line: arn:aws:lambda:us-east-1:xxxxxxxx:function:serverless-bot-dev-line
````

HTTP イベントを設定している場合、デプロイログ画面で URLが表示される。

````
$ curl -X GET  https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/serverless/line
````

みたいにすると無事Lineに通知が届き実行可能。

AWSのダッシュボードからスケジューラも適切に設定されていることが確認出来る。

10minに１回、ねぇねぇとつぶやいてくれるメンヘラbotがお手軽に完成する。



デプロイしたら、コマンド経由でテスト実行する事も可能。以下のコマンドで関数を実行する。

````
$ serverless invoke --function line --log 
````

あくまでココではテスト実行するだけなので、ここでエラーを吐かなくてもHTTP経由ではエラー、ということもある。

デプロイしていないコードは実行できないっぽいので、本格的に開発するならmochaなりでテスト書くのが無難そう。

## 各種イベントを設定する 

### schedule イベント

````
line:
    handler: handler.line
    events:
      - schedule: rate(10 minutes)
````

構文については、 https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html を参照

1分のときは `10 minutes`ではなく`1 minute`なので注意

### http イベント

````
line:
    handler: handler.line
    events:
      - http:
          path: serverless/bot
          method: get
````

path でエントリー、methodで メソッドを指定する。

こちらのイベントを設定すると自動でAPI Gateway が起動し、ほげほげしてくれるみたい。

## 感想・気になったところとか

本来の目的としてはHerokuで動いていたBacklog用のBotを Serverless で置き換えられたらなぁ…というところだったので、
上で試した機能を利用して概ね実装することは可能っぽい。

Lineの通知はおもったよりも簡単。SlackじゃなくてLineの方が良い類の通知、プライベート周りでめっちゃありそうなので重宝しそう。

nodeもモジュールなど不通に使える様なので、通常のnode開発のフローでシンプルな関数を記述していけば、そのままLambdaとしてデプロイ出来るっぽくって、すごいお手軽感はある。

- line の[開発者ドキュメント](https://notify-bot.line.me/static/pdf/line-notify-api_ja.pdf?v=1.0)、URLとかコピペすると文字がバグる時ある。
- 料金とかどうなるのかとかが気になる。
- CloudFormationって何!?掛かるの？　- 無料です[参考](https://aws.amazon.com/jp/cloudformation/pricing/) 
- API Gateway って何!?いくらかかるの？ - ちょっとだけお金かかる。[参考](https://aws.amazon.com/jp/api-gateway/pricing/)
- nodeのversionは4.3らしい。素敵。
- ソースをGithubで管理したいと思うので、セキュリティキーの埋め込みとかそういうのなんとかマスターしたい。
- Lineの通知は以外とめちゃくちゃ簡単だった。ほんとに簡単。

##　参考

Serverless Framework v1.0の使い方まとめ
http://qiita.com/horike37/items/b295a91908fcfd4033a2

Serverless 1.0 の参考プロジェクト
https://github.com/serverless/serverless#example-projects-v10