Monthly Archives: 6月 2016

2016-06-29

【ドヤリングにも安心】Facebookメッセンジャーbotで作るMac盗難防止用カメラ監視サービス

最近毎週沼津に行くようになったCTO室のJ.Nです。

CTO室では研究期間というものがあり、好きなテーマで一定期間技術検証することができるため今回はFacebookメッセンジャーbotの検証も兼ねて監視カメラサービスをMacAirを使い作成してみました。

IMG_3025

上記はFacebookボットに「写真(マシン名)撮ってね」と問いかけると、対象のMacAirのカメラが写真を撮って送信してくれるサービスです。

 

 

cafe_nomad_man

カフェでMacAirを扱っている時(ドヤリングしている時)に、机にMacAirを置いたままトイレに行った時などに使うと簡易盗難防止になります。

 

Facebookメッセンジャーbotとは?

Facebookメッセンジャーbotとはメッセンジャーの会話の相手となってユーザーとの会話から自動的に何らかの処理をしてくれるアプリケーションになります。

LINEもボットサービスを展開していますが、ボットサービスの狙いとしてはEC、クーポン、MAP、銀行、賃貸、宿泊など各社のサービスアプリの機能を全てボットの会話で完結することにあるようです。

 

スクリーンショット 2016-06-29 16.47.10

https://developers.facebook.com/docs/messenger-platform/

 

 

Facebookメッセンジャーbot開発に必要なもの

  • Facebookアプリケーション (Facebook開発者登録をしてアプリを作成)
  • Facebookページ (botはFacebookページに紐づける必要があるため)
  • Facebookからメッセージを受け取るHTTPSのコールバックサーバー (VPSやクラウドサービスをレンタルして構築)
  • HTTPS証明書  (Let’s Encryptで無料で取得可能)

上記までの手順は特に難しくはないでしょう。

HTTPSのサーバーは今回ConoHa(https://www.conoha.jp/conoha/)でRuby Sinatra+Nginxで作成しました。

FacebookメッセンジャーBotサーバー概要図

 

Untitled(1) (6)

  1. クライアントからBotへメッセージを送信
  2. Facebootのメッセンジャーサーバーがメッセージを指定されたコールバックURLへ転送
  3. ボットアプリケーション・サーバーが何らかの処理をして応答メッセージをメッセンジャーサーバーに送信
  4. メッセンジャーサーバーがクライアントにメッセージを転送

上記の手順のポイントは、ボットアプリケーションサーバーはクライアントに直接メッセージを送れないという事です。

コーディング自体は簡単でエコーサーバーや、Amazon商品検索ボットなどはすぐ作成できます。

 

 

IMG_2535

 

スクリーンショット 2016-06-29 15.34.17

 

作成した監視カメラサービス「SAKIMORI」

概要

sakimori

Bot Application Server

基本的な構成は「FacebookメッセンジャーBotサーバー概要図」と同じですが、カメラマシン(MacAir)がカメラ撮影命令を待機(ポーリング)するため、今回はAWSのSQSを利用しています。メッセージ・キューシステムが使えればなんでもいいのですが、kafkaやRabbitMQをグローバルIPでポート開放するのもセキュリティ的に不安なのとサーバー構築にも工数がかかるのでHTTPでキューがやり取りできるAmazon Simple Queue Serviceを選定しました。リクエスト100万までは無料なので良いです(https://aws.amazon.com/jp/sqs/pricing/)。

Bot Application Serverはクライアント(メッセンジャー)からの撮影メッセージ「写真 (マシン名) 撮ってね」を変換し、SQSにメッセージキューを格納します。

 

 

カメラマシン

クライアントには今回MacAirを使用します。

スクリーンショット 2016-06-29 16.26.49

プログラムからMacAirのカメラを制御するには「imagesnap」というアプリケーションが必要になるのでインストールします。

home  brewでインストール可能です。(http://brewformulas.org/Imagesnap)

SQSをポーリングし撮影命令を受け取ると撮影し画像ファイルをImage Serverに送信し、画像URLを取得しBot Application Serverに返却します。

 

Image Server

メッセンジャーBotの仕様として、画像ファイルを直接クライアントに送信することができない(画像URLとして送信する必要がある)ため画像ファイルを一度どこかのサーバーにアップロードする必要があります。そのためcurlのコマンドでファイルがアップロードできる簡易アップロードサーバーをSinatraで作成しました。

カメラマシンからのアップロード要求を受付し、画像ファイル格納後の画像URLをカメラマシンに返却します。

ソースコード

SAKIMORI Server
SAKIMORI Client for mac
SAKIMORI Image Server

作ってみた感想

  • botサーバーを作る事自体は簡単なのでボットサービスではアイディアが必要。
  • FacebookメッセンジャーのメッセージはコールバックURLとの通信がうまくいかなかった場合再送を繰り返すので、メッセージの重複チェックが必要。
  • 一通りサービスを作ってしばらく使っていくと作成したアプリで安定しない個所がわかるので、まずは自分が使いたくなるボットを作ると良い。
  • Facebookボットはcallbackサーバーと一定時間通信がないと一度アプリケーションごと遮断するのでreactiveの作業が必要(下記の画面)

スクリーンショット 2016-06-29 16.15.55

改善点

今回はサービスの完成度として自分が使える程度に作ったのでちゃんとしたサービスとしてリリースする場合以下の改善点が残っています。

  • 複数人が使える想定に作っていないため、サービスとして作るにはユーザーIDやマシンIDの採番を考える必要がある。
  • 画像はHTTP/HTTPSで公開しているのでGoogleなどのキャッシュに残って困る画像が映る場合は、画像のURLのパラメーターに認証キーをつけるなどの対策が必要。
  • クライアントからの撮影完了メッセージを受け取るのは別バッチサーバーを立てるべき。HTTPのやりとりの中でポーリングしない、
  • Facebookメッセンジャーのメッセージはうまく届かないときなど同じメッセージを再送し続けるので、重複したメッセージは処理しないようにする。(そうしないと延々と画像がメッセージに送られてくる)
  • MacAirを持ち運びするとWiFiが切れた場合SQSポーリングアプリはネットワークエラーを起こすので対策が必要。
  • クライアントはMacだけでなくラズパイやintel EdisonなどのIoT機器でも動作できるようにするべき。

上記の改善点をプルリクエストしてくれたりforkして改善してもらえるとありがたいです!!

 

2016-06-27

Javaマイクロフレームワーク探訪

こんにちは、GMO NIKKOのNigoです。
マイクロサービスアーキテクチャを採用しているプロダクトに関わっているんだから
アジリティの高いフレームワークの持ち駒を増やしておきたいよね、ということで
JavaでSinatraライクなマイクロフレームワーク、さらに一番人気と評判の
Spark Frameworkを触ってみることにしたのですが・・

SinatraはいわずとしれたRuby製の超軽量フレームワークです。
Webアプリケーションフレームワークの定石となっているMVCを崩して1クラス
ほんの数行でWebサービスを立ち上げられる脅威のアジリティをもっています。
さらに簡易ながら、RESTクライアントとしてもRESTサーバとしても活用できる
ことからSaaS APIの試用からハッカソンのバックエンドモックまでとにかくいますぐ
動くものを作るという用途にかけては非常に優れたフレームワークだと思います。

1. Spark Frameworkとは

Spark Frameworkとは、GitHubにそのものずばり「A Sinatra inspired framework for java」
とかかれておりますが、Sinatraの影響を受けて開発されている軽量なJava製の
Webアプリケーションフレームワークです。
(分散処理基盤のApache Sparkとはまったくの別物です、念のため)
公式を見ていただくと一目瞭然ですが、コード量・公開までの手順量の少なさは非常に
インパクトがあります。

2. Spark Frameworkでhello world

必要なものは公式の通りにEclipse, Maven, java8。
すでにEclipse4.4、java8は個人環境に入っており、MavenもEclipsem2eプラグイン
がはいっていたため10分程度で動くかなと思ったのですが、Mavenを
触るのが久しぶりだったり、java8でコンパイルするための設定が必要だったりで
結局半日近く。なかなかすんなりとは動きませんでした。
あまり触っていないMavenでの環境構築だから仕方がない+自分の不勉強を呪いつつhello world。
参考までにコードは下記です、サンプルそのままです。

3. そしてデプロイへ・・

Sinatra inspired tiny frameworkだからデプロイもさくっとできるだろう
と見込んでいたのですがなんだか色々と見込み違いがありました。
デフォルトでJettyが組み込んであるからこれを使うのだとばかり思っていたのですが
公式をよくよく確認するとservretに組み込んでtomcatにデプロイとあり、んーこれはちょっと・・。
何か別の方法はないかと探し回りこちらを参考にさせていただいて、
ローカルのvagrant環境上のUbuntuにデプロイというところまではたどりつきました。
Herokuへのデプロイなどの情報はみつかったため、想定しているデプロイ先はPaaSかTomcatかという割り切り仕様なのかもしれませんが、せっかくマイクロフレームワークをうたっているので単体で簡単に完結する仕組みが欲しいなあと思いました。
(この辺は調査不足です、Spring Bootも似たような起動の仕組みなので組み込みjettyに起動時パラメータを渡す設定があれば実行可能jar+起動スクリプトでいけそうな気がします。)
下記は今回作成したpom.xmlです。

4. まとめ

当初予定ではさくっとSpark Frameworkの環境構築を済ませて
<公式チュートリアル>をブログ用にいくつかこなしたうえで
Sinatraと性能比較をしてやはりSpark Frameworkおすすめですね!というシナリオを
描いていたのですが、現段階では情報の少なさも相まって少し求めていたものと
違うかなという印象です。しかしライブラリをうまく組み合わせることでひょっとしたら
化けるのかもという予感もあります。
以上非常に煮え切らない内容で大変恐縮ですが、マイクロフレームワークを
比較検討中の方や、spark frameworkが気になっているけどなかなか
触る時間がないというような方の一助となれば幸いです。

2016-06-23

AndroidアプリとGPSとFirebaseで帰宅を知らせる

こんにちは。GMOアドマーケティングのT.Mです。
会社から帰宅するときに家族にこれから帰る連絡をしているのですが、
毎日同じ文章を入れるのも面倒なので、
Androidアプリ、GPS、Firebaseを使って考えてみました。

仕組みは簡単で、AndroidアプリでGPSの経度/緯度を取得し、
Firebaseのリアルタイムデータベースに書き込みます。
自宅のPCは、Firebaseのリアルタイムデータベースの変更を受け取り、
特定の距離まで近づいたら音を鳴らします。
距離の計算にはGoogle Maps APIを使用しました。

android_gps_firebase_kouseizu

1. Firebaseの用意

Firebaseは、リアルタイムデータベースが特徴的なmBaaSで、
先日のGoogleI/O 2016で大幅なバージョンアップが発表されました。

今回はリアルタイムデータベースを使用します。
Firebaseにログイン(Googleアカウントでログイン出来ます)し、新規プロジェクトを作成します。
プロジェクト画面の左側にある”Database”を選択するとデータベースの内容が表示されます。
最初はなにもデータがなく、英数字だけ書かれていますが、それがデータベース名になります。

データの持ち方は以下のようにしました。
FirabaseのデータはJSONになります。
“home”が自宅、”location”が現在位置にします。

2. Androidアプリ

GPSで取得した緯度/経度をFirebaseに書き込むアプリを作成します。

Androidアプリで経度、緯度を取得する方法は公式ドキュメントが詳しいと思います。

AndroidアプリでFirebaseを使うにはSDKを組み込みます。
組み込み方は公式ドキュメントを参照ください。

自宅の位置”home”に書き込むには地図から選べると便利だと思いますが、
今回はやっつけでテキストボックスで数値を入れるようにしてしまいました。。

現在位置”location”へはGPSで取得した値をFirebaseに書き込みます。

Firebaseへの書き込み方は簡単です。
まずインスタンスと各値へアクセスするための参照を取得します。

“home”へはボタンタップ時に、”location”へはLocationListener#onLocationChanged()時に
Firebaseへ書き込んでいます。

3. 自宅PCで監視

Node.jsでFirabaseを使用します。
組み込み方は公式ドキュメントを参照ください。
組み込む途中で設定ファイルをダウンロードしておきます。

Node.jsでFirebaseのデータを取得します。
“home”も”location”も同様のやり方で取得できます。

valueイベントは”home”以下の子要素を全て取ってきます。
他にもchild_changedイベントも変更を受け取れますが、
“home”以下で変更にあった子要素だけ受け取れました。
今回はlatitude、longitude欲しかったのでvalueイベントにしました。

次に取得した緯度/経度をGoogle Map APIを使用し、距離を求めます。
Google Maps APIの使い方は公式ドキュメントを参照ください。

Google Maps APIを呼ぶタイミングは、”location”変更時にし、
取得できたJSONデータから距離だけ使います。

最後に取得した距離がしきい値より近ければ、音を鳴らします。
MacならsayコマンドをNode.jsから実行することで簡単に”あと何メートルです”と
音声で伝えることが出来ます。
今回は、PC代わりにRaspberry Piを使用したので、
Open JTalkとaplayを使用し、音声で伝えることが出来ました。

まとめ

Firebaseのリアルタイムデータベースは、使い出す前の準備に戸惑いましたが、
使い出したら自宅PC側でイベント登録しておけば、
変更があった時点で処理が動くので簡単に使うことが出来ました。
Firebaseには他にも機能があるので、それらも使ってみたいと思いました。

以上です。

2016-06-15

UnityC# で完結できるAndroidプラグインを簡単に作っちゃうぞ!☆ミ

Techブログを書かせていただけることになりました、
JWordのokiyoです。自称iOSエンジニアです。

ここ最近、UnityのAndroidプラグインを作成することをやらせていただいているので、
そちらの方法をご紹介いたします。

UnityでネィティブのAndroid(Java)のメソッドをコールすることができます。
複雑な内容(サービスを使う等)の場合、Androidプロジェクトをjarファイル化してから
jarファイルにアクセス方法が作りやすく分かりやすいのですが・・・。

簡単な内容については、直接ネィティブクラスにアクセスすれば良いので、
Unity上でコーディングでき、とてもオススメです。

例えば、ウェブブラウザを表示する時など、
jarファイル化してURLスキームを指定してIntentを発行、、等もいいのですが、
ささっとUnity上で動作する感じで作れますので、おすすめです。

他にも、GooglePlayService等から、ユニークIDを取得したい時、
下記の内容で作ればOKです。
この場合、UnityのAssets->Plugins->Androidフォルダの中に、GooglePlayServicesを配置します。
Androidフォルダの中のファイルにはアクセスすることができます。

これでAndroidで実行時、AndroidJavaClass or AndroidJavaObjectのクラス経由で、
ファイルを読みに行ってくれます。

ちなみに、パーミッション設定もお忘れなく。。
(UnityのAssets->Plugins->Androidフォルダの中に、AndroidManifest置いて、パーミッションを追加しておけばOK!)

下記を参考に作らせていただきました。http://docs.unity3d.com/jp/current/ScriptReference/AndroidJavaObject.CallStatic.html
http://qiita.com/YukiMiyatake/items/c8c2ef396fbf4457ba4f

このブログ、みんなカッコいい内容で更新されていますね~。
しょぼくてスマソです><。
次は誰でしょうか~。目が離せませんね!

でわでわ~☆ミ