ES2015で書く!チャットに画像投稿すると効果画像と結合してくれるボット

こんにちは、鍋山です。
この頃、ずいぶんと長い工数のかかるボットを開発していました。
コーディングはES2015とlodashに頼ることで、コード量の削減と可読性が良くなったように思います。
Node.js開発者の活動も盛んになっており、今後のdaab開発においても楽しさと快適さが期待できそうです。

今回は、チャットでボットに画像を送信すると、その画像を他の画像と結合してくれるボットを作ります。
結合する「他の画像」は、PNG形式の背景が透過している画像を利用します。

====

例えば下記のような、「写真」+「Booooom!という文字のPNGファイル」の結合画像を作ります。
f:id:nabeyama:20160207150934j:plain


今回のdaab開発環境

Node.js v4.2.4
OS X 10.11(El Capitan)

ローカルインストールしたnpmパッケージ

gm
www.npmjs.com

uuid
www.npmjs.com

gmはNode.jsでGraphicsMagickやImageMagicを使えるようにするパッケージです。
uuidはランダムな文字列を生成する為に使います。

グローバルインストールしたパッケージ

ImageMagic
www.npmjs.com

ImageMagicは画像処理を行ってくれる有名なライブラリですね。 今回はこちらを使用しました。
npmによるインストールでなくても使えますので、既にインストール済みの場合は特に改めてインストールする必要はありません。


​準備

事前インストール

グローバルインストール

brew install imagemagick

ローカルインストール
(画像効果ボット用のプロジェクトディレクトリ内で実行します)

npm install --save gm
npm install --save uuid

プロジェクトの初期環境構築


推奨する開発の進め方は、小刻みに実行して検証することです。
(Node.jsやhubot開発、daab開発ベテランの方は読み飛ばしてくださいね)
最初に実行して検証したいところは、PING/PONGですよね。
基本的で簡単なことではありますが、これができなきゃ始まらないdaab開発ですから、1つずつ小刻みに確認しながら進めていきます。
daabのPING/PONGまでの構築については、こちらの記事を参考に作ってください。


実装

ローカルインストールしたgmの実行結果を確かめる!

​PING/PONGがうまくいったら、ローカルインストールしたgmの実行結果を確かめてみましょう。
いきなり今回の本命の機能の実行となりますが、gmのGitHubページかnpmのページを参考にコードを書きます。

constについて

​ ES2015でボットを書く際には、変数や関数の宣言にはconstを使うようにしています。 constは再定義が不可な変数を宣言します。 注意点としては、変数の再代入は不可ですが、オブジェクトのプロパティの変更は可能というところです。

​arrow functionについて

arrow functionは、これまでは書いていたfunctionを短縮できます。
() => {}の形式で書けるのですが、この形式で書くとレキシカルスコープとなり、arrow function内で記述するthisの意味がこれまでと変わるので注意が必要です。

developer.mozilla.org

​ それではdaab runで実行してみましょう。
うまくいけば、ボットに話しかけるまでもなく、before_effect.jpgを最大辺240ピクセルにリサイズし、新たにafter_effect.jpgが作成されていることでしょう。


使い勝手を良くしたボットに書き換える

gmの効果を確認できたところで、使い勝手の良いボットに書き換えていきます。

実装したい機能としては、

  1. ボットが画像を受け取ったら、その画像をリサイズする
  2. あらかじめ設定しておいた画像と結合する
  3. 結合した画像を添付して返信する

といったところですが、プラスαの機能が欲しかったので、

  1. ボットがテキスト+PNG画像を受け取ると、それを効果画像として追加登録する(最大3個まで)
  2. 追加登録した効果画像を削除することができるようにする
  3. 複数の効果画像の中から、どの画像と結合するかを選択できるようにする
  4. どの画像と結合するかをランダム設定できるようにする
  5. ボットから送信する結合画像のファイル名をユニークにする(uuidを利用)

といった機能も追加しました。

今回のボットは実務で活用することが目的ではなく、面白そうだから作ってみよう!という気持ちで作りましたので、このくらいの機能までで良いかなと思います。

下記がそのコード全容になります。

ボットの中の処理に加えることをしていないので、プロジェクトディレクトリ直下に、compositeディレクトリの用意が必要です。
それから、同様にeffectディレクトリを作成し、その中に効果ファイルを設置しておく必要があります。
効果画像ファイルについては、任意のもので大丈夫です。
更にそのeffectディレクトリ内にaddディレクトリを作成してください。

f:id:nabeyama:20160207180140p:plain

あらかじめ効果画像を設定しておくことが可能ですが、その為には効果画像の準備が必要になります。
背景を透過にしたPNGファイルを作成するなどして、前述のディレクトリ内に設置しておきます。

また、下記コード部分が効果の名前とパス+ファイル名になっていますので、任意に修正してください。

うまくコードやディレクトリ、効果画像の準備ができましたらdaab runで実行してみましょう!

効果画像を追加する場合は、「効果の名前」+「PNGの添付画像」を送信します。
f:id:nabeyama:20160208094530p:plain

追加した効果画像を使うように選択し、結合する画像を送信します。 f:id:nabeyama:20160208094705p:plain

すると結果が・・・!
f:id:nabeyama:20160208094748p:plain

目線を隠すように「Booooom!」が!!
効果画像が結合の仕方に調整が必要ですね・・・。


このボットは、個人的に使っているRaspberry Piに設置して動かしています。
画像処理に必要なimageMagickのインストールやその各コマンドをインストールしておく必要がありますので、その準備さえ整っていれば実行できるかと思います。

現在の業務で開発中のボットも、それ以前のボットも個人的に書いているコードもES2015を使って書いているのですが、これまでになかったJavaScriptの機能がとても便利だと実感しています。

今回の効果画像ボットのコードも、このようにES2015を使って書いてます!といった部分をアピールしたかった意図もあります。

ボットを書くならこんな使い方もある!を探しつつ今後もボットを書いていきます。

タイトルとURLをコピーしました