Google Home アプリを申請してリリースした


桜が一気に開花した今頃、桜の木の下を自転車で通り抜けるときの風は暖かいというより暑いですね。

んなことは置いといて、先日面白いものを買いました。

前から気になってたんですが、半額セールを逃してケチ性分のせいで買えないでいたところ、ヨドバシで「5,000円以上の買い物で半額セール」をやっていたので買いました。

すぐさま開封して、設定して、PCから音をキャストしたり、音楽を流したりして、興奮状態だったんですが、やっぱり自分で色々設定したいと思うのが、この世の常。
先日、俺の話を聞け!!LT大会 #8においてDialogFlowの使い方を軽く知ったので、もっと詳しく調べてみることに。
DialogFlowは無料で使えるのですぐにログインして、早速作成。ここらへんの方法は調べたら山ほど出てくるので、飛ばします。

んで、調べたらわかりますが、状況に応じて違う文章を返すなど少し高度なことをしようとするとDialogFlowだけでは、能力不足になります。(それでも文法解析などしてくれて非常にありがたい。)
というわけで、WebHookでバックエンドサーバに投げる必要があります。
調べてるとたいていNode.jsを使ってまして、色々ゴニョゴニョしてるようですが、買った勢いでNode.js環境整備は熱が冷めます。
手っ取り早くかける言語はPHPしか思いつかなかったのでPHPで実装することにしました。

というわけで今回の構成は

PHP-FPM <-(呼び出し・JSON返却)-> Nginx <-(WebHook)-> DialogFlow <-(接続)-> Actions on Google <-(「OK,Google アプリに繋いで」)-> Google Home

なんか見てる限りではJSONで{“speech”:”hoge”}と返しとけば、喋ってくれそうだと思い、すぐさまテストしたんですが、これまた喋らない。
しょうがないからドキュメント見てたらV1 APIとV2 APIがある。V2はbeta版で有効にしてるとV1 APIは使えなくなるらしい。
設定を確認してみるとV2 APIがONになってて、「無意識にONにしてたんだろうな〜」とbetaに無意識に反応する自分の習性を笑いながら読み進めると、「fulfillmentText」を埋めときゃなんとかなることを発見。

おまけに、’payload’ => ‘google’ => ‘expectUserResponse’ をfalseに設定しておくとアプリを終了できることも発見。
これはエラー処理に便利そう。

また、やり取りするJSONにはContextsというのがあり、どのIntentsを動作させるか制御するのに使うみたいなんですが、’parameters’の中に{‘parameter-name’ : ‘body’ }のように好きなデータを
詰め込めるので、サーバーにデータを保存せず、そこから取り出すことでセッション周りも考えなくていい素晴らしい設計になってることも発見。

技術的な話はまあいいとして、たまたま思いついたアプリ(正確にはアプリの移植)を2,3日で完成させまして、テストして修正をしてを繰り返し、まともに動く気がしてようやく欲が満たされました。
しかし、テストアプリは一週間に一度Action on Googleから「Test App」を押さないと使えなくなると判明。
これはめんどくさい。回避するには、隣の「Submit draft for review」を押せと。つまり公開しろという意味らしい。
高揚感に浸ってた自分は、Google Homeアプリをリリースしてみた(申請編) – Qittaなどのページを参考にさせていただきながら、プライバシーポリシーページなどを作成。
気をつけたのは

  • アプリ起動後にユーザが次に何をすべきか、終了方法をすべて音声で案内すること。
  • プライバシーポリシーのページは、個人情報を引き出すつもりはないことを明記すること。
  • 「もう一度」ということで再度読み上げる機能をつけること

こんな感じですかな。
土曜の夜に提出して、月曜になるのを待ってたんですが、日曜のうちに「こんなん相手にされないのではないか。」「実装が信用ならないと言われるんじゃないか。」と不安になるばかり。
そして月曜、早速メールが来てました。
題名は「〇〇 was not approved」でした。どんなどぎついお叱りが書かれてるのかと恐る恐る開けると、なんとも丁寧な文章で「カテゴリ変えたほうがいいんじゃないかな。」とありました。
優しいお言葉に背中を押されて、「あと一回は再挑戦してみようかな」とカテゴリを変えて送信すると、4時間後…

通ってました。
ネットを見る限りは4,5回はやり直しを食らってたので、正直何かの間違いじゃないかと何回もカレンダーの「4/2」を見直しました…4/1じゃない…エイプリルフールネタではない…だと…

で、何作ったのさ

MN2問題集 | Google アシスタント

これです。
もともとアマチュア無線技士3級問題集があったので、「この問題を読み上げて、数字で回答できたら手軽に練習できていいんじゃないの」と思いまして作りました。

もう一個、レビューしてもらいやすいようにと、県庁所在地当てクイズをつけたので、そちらの方も暇なときに遊んでみてください。

問題は思いついたら追加します。

以上、稚拙な文章ですが読んでいただきありがとうございます。

…ところでMN2問題集の「MN2」ってなんだよと思われたかもしれませんが、由来は「MaNa Application Software MoNdaisyu」からの「MNAS MN」からの「MN MN」からの「MN2」なんですが、なにせHSP実装のMN2初版は中学時代の黒産物でして、「MNが二個あるやん。略して短くしたろ。」みたいな軽い気持ちでつけたものです。略し方がガバガバで全くわけがわかんない。今回、別の名前を考えたんですが、アプリのアイコンから察せるようにセンス皆無なので、良い案が出ず、なんのアプリなのかひと目でわかるように「問題集」を付け足して「MN2問題集」となったわけです。「問題集が重複しとるやんけ。」と思ったあなた、そのとおりです。おまけに「エムエヌツー」という発音のしづらさ。自分は「OK Google、問題集」でショートカットを作成してます。

Rustにアセンブリを吐かせる方法


この記事はseccamp2017 Advent Calendar 2017の十六日目の記事です。

OS開発でどんなアセンブリにしてるか知りたいとき、xargoとか使っておきながらrustcにアセンブリを吐かせる方法は
手っ取り早い方法がxargoなりmakeなりする端末で、
env RUSTFLAGS="--emit asm" make ウンタラ
か、いっそ
export RUSTFLAGS="--emit asm"
しとけば
/target/(target-name)/(release or debug)/deps/に.sで吐かれてます。
以上

Rustのバイナリをstripしたらサイズが激減したお話


この記事はseccamp2017 Advent Calendar 2017の八日目の記事です。

短く。
Rustのバイナリですが、リリースビルドにしても

$ls -l test
-rwxr-xr-x 2 pg_mana users 5047040 12月 8 22:33 test*

なんで5MB近くあるんや、Hello,world!ぐらいしか書いてないぞや、とモゴモゴ言いたくなります。
ふと思い立ってstripした所

$strip test
$ls -l test
-rwxr-xr-x 2 pg_mana users 445368 12月 8 22:36 test*

なんかびっくりするほど減って必要なもんまで消してないか不安になるレベル。でも動く、動く(CD買った)。
恐らく大きなプロジェクトになれば減りは鈍くなると思うけど、他の合わせ技で減らせるはず。
要検証案件なので確認してから使ってください。

CybozuLiveの新着情報受信ソフト作った(Linux)


この記事はseccamp2017 Advent Calendar 2017の二日目の記事です。


もう十二月。
もうすぐ2018年になります。このサーバーも一年が過ぎようとしています。

さて、セキュリティキャンプとの直接の関係性は薄いのですが、セキュリティキャンプを機に触りだしたサイボウズLiveの新着情報を受信して通知するソフトウェアをQtで作りました。
クランアントじゃないのかよと飛んできそうですが、サイボウズLiveは2019年に終了するそうなので、あまり機能をつけると虚しくなりそうで機能を絞りました。
ウィンドウに新着情報を並べ、イベント内容が書かれているところをダブルクリックすると該当ページをブラウザで表示するというものです。
起動時自動実行したかったので起動オプションに-nをつけると起動時にウィンドウを表示せず通知欄に隠れます。
また通常起動してもウィンドウを閉じるを押すと通知欄に隠れます。終了するには設定=>終了を押してください。
コードもおいておきますが期待はしないでください…なんかいい機能あったらプルリクエストおねがいします。git初心者ですのでうまくできないかもしれませんが。
PG_MANA / Sardine — Bitbucket
セキュリティキャンプ直接の進捗はまた(したいことがたまりすぎた…)

Sardine-0.0.1-1.x86_64
署名公開鍵

どちらも一時的なURLです。Ruine.jpが整理でき次第そちらに置きます。
一応repo.ruine.jpが動作しだしました。不安定ですがどうぞ。
ドメイン整理でrepo.taprix.orgにおいてあります。
repo.taprix.org/pg_mana/linux/rpm/x86_64/は自作rpmパッケージのリポジトリになってます。
openSUSEでビルドしてます。他にもTwitterクライアントなどもありますのでどうぞ。
署名したのになぜか警告出るのだなこれが…署名がないって。

意外と便利でサイボウズLiveのページを固定しないでよくなりました。更新間隔は10くらいが良さげ?
めったに更新がないなら2時間でも。

Qtで同じ名前のスロットが複数ある時のconnectの仕方


前回の記事でPhonon::VideoPlayer::playをボタン押したら動作させたいなと思ったら複数スロットがあり、

void play(const Phonon::MediaSource &source);

を選んできて引数エラーになるので…
公式ドキュメントにある方法でやってみる(旧式のSIGNAL(),SLOT()形式ではこのような問題は起きない)
New Signal Slot Syntax in Qt 5

Phonon::VideoPlayer *videoplayer = new Phonon::VideoPlayer(Phonon::VideoCategory);
QPushButton *play = new QPushButton;
play->setIcon(this->style()->standardIcon(QStyle::SP_MediaPlay));
//====
connect(play,&QPushButton::clicked,videoplayer,static_cast<void (Phonon::VideoPlayer::*)(void)>(&Phonon::VideoPlayer::play));
//====

キャストするんだってさ。
以上。

Qtで作ったアプリでVLCをバックエンドとしてH.264な動画を再生する


どうも。
以前openSUSEのFirefoxでH264な動画再生をするため色々していたのですが、Qt製のソフト、詳しく言えばQMovieクラスだけではH.264な動画は再生できないことがわかっていました。(QMovieは「without sound」とある。)

そこで気になったのが以前書いたPhononのバックエンドをVLCに変えるの中で紹介したPhononというもの。
これはQtに付属しており、このバックエンドをVLCに変更し、VideoLAN本家のvlcを導入しておけばPhonon経由で再生できるのかもと思った次第です。
まずは開発に必要なものを揃えます。最低Qt開発環境とcmakeは入っているものとして…yastかzypperで「phonon4qt5-devel」を入れます。他のディストロでは似たようなものを入れてください。(もちろんバックエンドはVLCに変更済みにしておいてください。)

次にCMakeLists.txtに

find_package(Phonon4Qt5 REQUIRED)
target_link_libraries(プロジェクト名 ${PHONON_LIBRARY})

を追加します。
以下テストコード

#include <QApplication>
#include <QUrl>
#include <phonon/VideoPlayer>
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    Phonon::VideoPlayer player(Phonon::VideoCategory);
    player.show();
    player.play(QUrl("./test.mp4"));
    return app.exec();
}

これで再生できるはずです。
割とかんたんに再生できて、びっくりなんですが、player.play(QUrl(“http://…”))とUrl入れるとネットから持ってきて再生しだします。ストリーム再生はできてませんが。

というわけでメモでした。