LINE Messaging API の replyToken は何秒で無効になるのか検証

モチベーション

LINE Messaging API の公式ドキュメントでは
replyTokenの失効期限は一定期間と記載されており明確な数値がなく
正確に検証したいと思ったため.

応答できるイベントには応答トークンが発行されます。 応答トークンは一定の期間が経過すると無効になるため、メッセージを受信したらすぐに応答を返す必要があります。

developers.line.biz

結論

30秒

検証方法

検証用のシンプルな LINE ボットを開発.
express + line-bot-sdk-nodejs を使って heroku にデプロイ.
ソースコードは以下リポジトリ.

github.com

ボットの仕様

  • 数字(n)を送信数すると n 秒後に replyMessage を送信
  • replyMessage が送信できなかった場合は pushMessage でエラー内容を送信
  • 数字以外は数字を送信するように促す

検証内容

f:id:morugu:20190714152702p:plain
検証内容

まとめ

  • Messaging API の仕様を検証するためのボットを作った!
  • 30秒以下であれば replyMessage で返信が可能
  • 思っていたより期限が長かった!

Lambda から最新の AWS SDK を使って Aurora のデータベースクラスタの停止、開始を実行できるようにする

Lambda から Aurora のデータベースクラスタを止めるためにRDS.stopDBCluster を呼んだのですが stopDBCluster is not defined になったので Lambda Layers を使って解決してみました。

Amazon Aurora がデータベースクラスタの停止、開始へのサポートを開始

Lambda の実行環境調査

Lambda の実行環境(ランタイム: Node.js 8.10)では AWS SDK for JavaScript – 2.290.0 がデフォルトで含まれており
2.290.0までに対応している API であれば何も考えずに const AWS = require('aws-sdk'); で使うことができます。

docs.aws.amazon.com

2.290.0 は 2018/08/10 にリリースされたバージョンなので、それ以降にリリースされた API に関しては何かしら対策が必要となります。

Release Release v2.290.0 · aws/aws-sdk-js · GitHub

今回欲しいのは、RDS の start/stop DBCluster が入っているバージョンで
CHANGELOG から探してみると2.319.0で入っており、やはりそのままでは使えません。

aws-sdk-js/CHANGELOG.md at master · aws/aws-sdk-js · GitHub

feature: RDS: This launch enables RDS start-db-cluster and stop-db-cluster. Stopping and starting Amazon Aurora clusters helps you manage costs for development and test environments.

Lambda Layers で解決する

今までだと関数のコードと一緒に zip にしてアップしていたのですが、関数の容量が大きくなってしまうため
Re:invent 2018 で発表された Lambda Layers を使ってみます。

詳細な手順は以下の記事にわかりやすく書かれていますが、Python の例なので Node.js の場合の差分のみ記載します。

qiita.com

最新の AWS SDK の場合は以下のコマンドを実行して、できあがった zip をアップロードします。

$ mkdir nodejs && cd nodejs
$ yarn add aws-sdk
$ cd ../
$ zip aws-sdk-nodejs-latest.zip -r nodejs

Layers の作成が完了したら、aws-sdkをインポートすることで実行できるようになります。
※ Layers に aws-sdk が存在する場合は、実行環境のデフォルトのものより優先されてインポートされるようです。

RDS.stopDBClusterが使えるようになった参考コードは以下です。

const AWS = require('aws-sdk');

exports.handler = (e, ctx) => {
    const rds = new AWS.RDS();
    const params = {
        DBClusterIdentifier: CLUSTER_NAME
    };
    rds.stopDBCluster(params, (err, data) => {
        if (err) console.log(err);
        ctx.succeed();
    });
}

まとめ

  • Lambda で AWS SDK for JavaScript – 2.290.0 以降のバージョンを使いたい場合は対策が必要。
  • Lambda Layersを使うと、関数の容量を抑えらる・他の関数でも使い回せる と言ったメリットがある!

参考

docs.aws.amazon.com

dev.classmethod.jp

GameWith Engineer Meetup #1 に参加した

8/21に GameWith Engineer Meetup #1 に参加してきた.

内容は

  • インフラ基盤
  • レガシーコードとの向き合い方
  • ブロックチェーンゲーム開発

の3本立て.
インフラの事例は各社サービスによって特徴があり解決方法に発見があるし, 7月は Solidity を勉強してハッカソンに参加したので, ブロックチェーンゲーム開発にも興味があり日々業務で関わっている方の話が聞けるかなと期待しての参加. Q&Aは記憶に残っているところのみ.

gamewith.connpass.com

GameWithを支えるインフラ基盤 / @serima

www.slideshare.net

Q&A

  • ELBの暖気などスケール対策は何かやっているか?
    -> 恒常的にアクセスがあるため、特段やっていないが問題は起きていない。

  • リクエストの性質は?
    -> GET リクエストでリードアクセスが大半

  • DDoS 対策は?
    -> 特にしてない
    -> CDN は画像にのみ利用

  • リクエスト予測が外れたことはあったか?
    -> 過去にゲームのイベント開始時間がずれたことによるトラブルがあったが、ここ1年はそういったことは起きていない

レガシーコードの中でも迅速にユーザーに価値を届ける / @m3m0r7)

www.slideshare.net

Q&A

  • レビューは完全にランダムで担当割り振っている?
    -> スキルレベル問わず完全なランダム
    -> リリースは QA エンジニアがチェックして問題なければ通す

ブロックチェーンゲーム開発の取り組み / @takepon_phd

speakerdeck.com

Q&A

  • サイドチェーン、プライベートチェーンなどあると思うがなぜ Ethereum ?
    -> コミュニティとの関係性、開発に関する情報や開発者の数が多いため Ethereum を選んだ

その他・まとめ

インスタンス台数の増減の決定を, 過去の数値から算出 + 攻略部の方の経験値で行っていたのが面白かった.
まだ最適化が必要だと話していたが, 人間の意思決定を過去のデータでサポートするこのモデルは高確率で最適な数値を導き出せそうな予感がした.
もちろんオートスケールはあるものの, 突発的なリクエスト変動を事前にある程度予測するには有効な手段だと感じた.

記念すべき第1回!で, これからやっていくぞ感が溢れていた.
参加者は12,3人 + GameWith の方で, 距離が近く質問がしやすく(自分も2,3質問した)参加者の方は色々と持ち帰れたのではないかな.

Slack Slash Command を外部から叩ける slack-cmd を作った

www.npmjs.com

github.com

 使い方

$ npm install -g slack-cmd
特定チャンネルのトピックを更新する.
$ slack-cmd -w xxx -c topic -t "this channel is for developer" -C xxxxx -T xxxx-xxxxxxxxx-xxxx
GtiHub の更新情報が Slack に流れるようにする.

GitHub | Slack App Directory をインストール/設定したあとで

$ slack-cmd -w xxx -c github -t "subscribe owner/repository" -C xxxxx -T xxxx-xxxxxxxxx-xxxx

 作った背景

ChatOps で使うために作った Slack Slash Command たちを外部(ターミナル, CI のプロセス)からでも実行したかった.

Slack の GitHub App が使いにくくて, プログラムからいい感じに叩けるようにしたかった.

その他/学び

  • 引数をハンドリングするのに commander.js が便利と聞いて使ってみたらとても良かった( npm ツール開発の生産性あがる!

github.com

  • "Content-Type": "multipart/form-data" で複数データを指定するには, ヘッダに boundary={boundary} を定義して --{boundary} でデータの区切りを指定する

  • 2本目の npm ツールということで init から publish までスムーズに進められた.

  • 開発にかかった時間: 約4時間

Ethereum dApps をローカル環境で動かす

dApps 開発者ギルド勉強会 #1 に参加して
ローカル環境で dApps をデプロイして動かすことろまでができたので記録を残しておく.

環境構築と Truffle を使って Ganache のローカルチェーンにデプロイするところまでは
オオキマキさん (@ookimaki_JP) のブログの通りにすすめていけば問題なくできると思う. (ありがたい!)

 環境構築

givinglog.com

 Ethereum dApps Quickstart

givinglog.com

Ethereum dApps Quickstart の動作確認

MetaMask は file://~ から始まる URL では動作しないため, live-server を使って確認する.

$ npm install -g live-server
$ cd src/
$ live-server

ブラウザが自動で立ち上がり http://127.0.0.1:8080 が開く.

テキストエリアに文字を入れて, set をクリックで MetaMask が表示されるのでそのまま submit

alert で Txhash: 0xxxxxx と表示されれば成功.

Ganache の Transactions タブでも同じアドレスが確認できるはず.

発生したエラーと対策

npm install でエラー

  async awaitCurrentBlock () {
        ^^^^^^^^^^^^^^^^^

SyntaxError: Unexpected identifier
対策

7.6系以降の Node.js を使用する.
安定版の8.x系を使っておけば安心.

truffle migrate でエラー 

$ truffle migrate
Using network 'development'.

Error: Attempting to run transaction which calls a contract function, but recipient address 0xxxxx is not a contract address
対策
$ truffle migrate --reset

github.com

 Provided address "0xxxxx" is invalid (ブラウザのconsole)

 対策

src/index.htmlcontractAddress が間違っているので, truffle migrate した時のコントラクトアドレスを再度確認して正しいものを指定する.

 contract.methods.set is not a function (ブラウザのconsole)

対策

src/js/contract_abi.js の contractABI が間違っているので,   build/contracts/SimpleStore.json の abi を正しくコピーする.

 MetaMask - RPC Error: Error: Error: [ethjs-rpc] rpc error with payload (ブラウザのconsole)

MetaMask - RPC Error: Error: Error: [ethjs-rpc] rpc error with payload
対策

src/index.htmlcontractAddress が間違っているので, truffle migrate した時のコントラクトアドレスを再度確認して正しいものを指定する.

所感

  • ひとりでやったら1週間ぐらいかかりそうな内容が2時間でできた!
  • わからないことは気軽に聞くことができたり, 一緒に考えながらやっていけたり dApps 開発者ギルドに感謝!