iOSのSiriと任意のアプリ / Webアプリとをハンズフリー連携させる方法
2016/03/16
価値ある情報をユーザー視点で発信するブログ
2016/03/16
もくじ
iOS 5.xとiPhone 4Sという組み合わせのみに許された禁断の新機能、Siri。
日本語対応したiOS 5.1リリース直後、僕のTwitterのタイムラインはSiri専用タイムラインになるほどでした。
Newton Message Pad所有者の僕は、Messagepad Padのアシスタント機能を想起します。
あのころ夢でしかなかったものが、こうして現実になっていることに感動を禁じ得ません。
さて、そんな素敵なSiriも、使い始めると欲が出てきます。
その最たるものは、サードパーティーのアプリケーションへの対応ではないでしょうか。
住所録に登録しての画面のタップを経由するURLの起動はできますが、その仕組み上、起動可能なのはあらかじめ登録された静的なもののみで、Siriならではの醍醐味にやや欠けます。
Googleでの検索のように、アプリケーションないしWebサービスに、そのときどきに応じて違うキーワードないしパラメーターを渡したいものです。
そんなことを考えてHTTP Proxyを使った実験してみました。(続きは[Read More]から)
コンテンツフィルタ機能を持ったHTTP Proxyを使えば、Siriを利用する際にAppleのサーバーとの間で行なわれる通信を監視し、必要に応じていいようにやりとりを改変できると考えました。
そうした用途に使えるものにPrivoxyなどがあります。
Privoxy – Home Page |
しかし、mitmproxyというSiriの使うhttps通信の解析用ソフトウェアを使ってみたところ、Siriはここを通さず通信をすることが分かるにとどまりました。
mitmproxy – home |
どうも、Siriの通信は、そのほかのhttps通信とは別扱いなようです。
Siriを直接いじるには、Siriの使うサーバであるguzzoni.apple.comにアクセスしようとしたときに、自分のサーバにアクセスが行くようDNSに変更を加える必要があるようです。
Wi-FiはDNSの設定ができますが、3GはDNSの設定ができません。
仮にできてもWi-Fi環境下だけでは不完全燃焼。この先はJailbreakが必要になってしまうので、ここで引き返します。
Siriのハックをするに当たり目指したいことがあります。それは、音声入力後、画面のタップ無しにアクションを起こすこと。
iPhoneはポケットの中に入れたまま、ハンズフリーで事を成し遂げたいわけです。住所録を使う方法は、画面のタップが必要なので使えません。
使えそうなのは、「Webで検索」です。Webで検索は以下のシーケンスでブラウザの起動に至ります。
最初のSiriの呼び出しさえヘッドフォンマイクのボタンから済ませてしまえば、後は音声だけでブラウザの起動、検索結果の表示まで、文字通りハンズフリーでオペレーションが可能です。
Siriから利用できる検索サイトは、少なくとも四つあります(もっとあったら教えてください)。日本語環境の場合、検索サイトと検索クエリは以下のようになります。
正直BingとYahoo!は使いません。Wikipediaも、どっちかといえば使いません。
これら使わない検索サイトへのアクセスを横取りすれば、目的が果たせそうです。
Photo: andrewmalone
やはり、ここでもHTTP Proxyが登場します。
Siriの通信と違い、こちらは普通にMobile Safariでのことですので、HTTP Proxyを設定すれば、それらの通信の横取りができます。
iPhone単体で設定できるHTTP ProxyはWi-Fi側のみで、そのままでは3G側が手すきになってしまいますが、iPhone 構成ユーティリティを使用すると3G側のHTTP Proxyの設定が可能です。設定方法は後述します。
iPhone構成ユーティリティ 3.5 – Mac OS X |
iPhone構成ユーティリティ 3.5 – Windows システム用 |
HTTP Proxyで、特定のサイトへのアクセスを転送するような仕組みが必要です。
先般紹介したPrivoxyでもできるかと思いますが、やや大げさ。
HTTP Proxyの定番Squidと、リダイレクタのSquirmを組み合わせて使います。
これらをiPhoneからアクセス可能な場所にあるサーバにインストールします。
僕はUbuntuを利用しているので、Ubuntuへのインストール例です。
リダイレクタのSquirmの方からインストールします。build-essentialなどの、コンパイルに必要なツールはインストールしておいてください。僕の環境には、既にいろいろとインストールしてあるので、何が必要かよく分からない状態です……。
まずはダウンロードと展開。
$ wget http://squirm.foote.com.au/squirm-1.0betaB.tar.gz
$ tar xvzf squirm-1.0betaB.tar.gz
続いてパッチを当てます。これは、squirmによる処理対象にするIPアドレスの指定が面倒なので、すべてsquirmを通すようにするものです。
iPhoneの3Gに使われるIPアドレス空間は日々広がっており、個別に指定するのは現実的ではありません。
$ wget http://hitoriblog.com/wp-content/uploads/2012/03/squirm-1.0betaB.diff
$ patch -p0 < squirm-1.0betaB.diff
squirmのサブディレクトリ、regex内にある正規表現関係のファイルをコンパイルします。
$ cd squirm-1.0betaB/regex
$ ./configure
$ make clean
$ make
$ cp -p regex.o regex.h ..
ここでMakefileのinstallパートにあるユーザ名squidをproxyに変更します。Ubuntuでは、Squidがユーザproxyで実行されるからです。
$ cd ..
$ vi Makefile
編集が終わったら、引き続き以下でsquirmをインストール。
$ make
$ sudo make install
設定ファイルのひな形をコピーします。
$ sudo bash
# cd /usr/local/squirm/etc
# cp -p squirm.patterns.dist squirm.patterns
# cp -p squirm.local.dist squirm.local
コピーしたsquirm.patternsを編集。
# vi squirm.pattern
以下を追記。これで、Bingにアクセスしたときに、自分のサーバに転送されます。SiriからBingに与えられた引数は、丸々自分のサーバで引き取ります。この例では、「http://hogehoge.com/siri/index.html」に転送しています。
regexi ^http://m\.bing\.com/search/CommonPage\.aspx\?(.*)http://hogehoge.com/siri/index.html?\1
正規表現で?以降の引数にマッチする正規表現を()でグループ指定。\1で後方参照しています。
保存終了。
続いて、Squidのパッケージをインストールします。
# apt-get install squid
Squidの設定ファイルを編集。
# cd /etc/squid
# cp -p squid.conf squid.conf.org
# vi squid.conf
まずは、ポートの指定。ポートを指定してください。デフォルトからは変えた方がいいと思います。
http_port 8080
iPhoneの3Gからと、自分の使うローカルネットワークからのみつながるようにACLを設定します。
不特定のiPhoneユーザーから使われてしまう可能性は残してしまいます。
「acl localnet src 192.168.0.0/16 # RFC1918 possible internal network」の下辺りに追記。
# 自宅のWAN側のアドレス等
acl allow_hosts src xxx.xxx.xxx.xxx
# SoftBank iPhone 3Gのホスト名
acl panda_world srcdomain .panda-world.ne.jp
「http_access allow localhost」の下辺りに以下を追記。
http_access allow allow_hosts
http_access allow panda_world
url_rewrite_programにSquirmを設定するための設定を加えます。
以下を追記。squid.confをurl_rewrite_programで検索するとコメントアウトされた部分が見つかるので、その辺りに追記するのがいいと思います。
url_rewrite_program /usr/local/squirm/bin/squirm
url_rewrite_children 10
一応、Proxy経由であることを示すヘッダ隠すための設定を加えます。
以下を追記。
forwarded_for off
header_access Referer deny all
header_access X-Forwarded-For deny all
header_access Via deny all
header_access Cache-Control deny all
保存終了。
Squidを再起動します。
# service squid restart
# exit
このままではHTTP Proxyを他人に使われてしまいますので、パスワード認証をかけます。ただ、問題が発生するので、実際には適用していません。(後述)
.htpasswdファイルを生成。
$ cd /etc/apache2
$ sudo bash
# htpasswd -c .htpasswd [ユーザー名]
Squidの設定ファイルを編集。
# vi /etc/squid/squid.conf
以下を追記します。
auth_param basic program /usr/lib/squid/ncsa_auth /etc/apache2/.htpasswd
auth_param basic children 5
auth_param basic realm Squid proxy-caching web server
auth_param basic credentialsttl 2 hours
acl password proxy_auth REQUIRED
http_access allow password
Squidを再起動します。
# service squid restart
# exit
ただ、この設定では、「設定>Wi-Fi>使用中のネットワーク名>HTTPプロキシ>認証」のユーザ名、パスワードを入力していても、アプリケーションによっては頻繁にHTTP Proxyのパスワード認証を求められてしまい実用になりません。一切求められないアプリケーションもあるので、実装の差であろうと思います。
CFNetworkなどの低位のAPIを使っていたり、標準のAPI以外のライブラリを使っていると、パスワード認証の設定が無視されるのかもしれません。
3G側は、そもそも認証ありのHTTP Proxyを設定できないようです。
ひとまず諦めて認証を外して遊んで、飽きたところでサーバを落としましたが、どなたか対象方法をご存知の方がいらしたら教えてください。
ここまでで、Bingでの検索クエリを自分のサーバに転送するHTTP Proxyの設定は完了しました。これに合わせたiPhone側の設定をします。
パスワード認証に関しての問題は前述の通りですので、パスワード認証無しの設定です。
▲設定するAPの右端をタップ。
▲一番下までスクロールし、「HTTPプロキシ」を手動に選択。その下に現れるHTTP Proxyサーバの設定欄に、サーバのURLとポート番号を入力。
これでWi-Fiの設定が完了です。Squidの設定で、自宅のWAN側のIPアドレスないしホスト名がSquidにアクセス許可されるようにしてください。
続いて、3G側のHTTP Proxyの設定ですが、これには、前述の通りiPhone 構成ユーティリティを利用します。
▲「構成プロファイル」をクリック、「新規」ボタンをクリック。これで新規プロファイルが作成されます。
▲「一般」タブが選択された状態かと思いますので、「名前」に「SiriProxy」などと。識別子に「com.hitoriblog.siriproxy」などと入力。適当で構いません。
▲項目が縦に並ぶ列を一番下までスクロール。すると「APN」という項目があるのでクリック。さらに、「構成」ボタンをクリックします。
▲APNの設定と共にHTTP Proxyも設定できます。APN情報は間違うと、重い料金を課されるなど悲惨な結果を招く可能性がありますので、よく調べてください。結果に一切の責任を負えません。以下はSoftBankのiPhoneの3G用のAPN設定です。
▲「書き出す」ボタンをクリック。
▲署名は「なし」で、「書き出し」。ファイル名の指定を促されるので「SiriProxy」などで。
書き出したSiriProxy.mobileconfigをメールに添付し、自分宛に送ります。
▲到着したメールに添付されたSiriProxy.mobileconfigをタップ。
▲プロファイルのインストール画面に遷移するので、「インストール」ボタンをタップ。
これで、3G側もHTTP Proxy経由でのアクセスとなりました。
squirmで「http://m.bing.com/search/CommonPage.aspx」宛のアクセスを「http://hogehoge.com/siri/index.html」に転送するようにしたので、転送先のindex.htmlを用意します。
Bingに渡される検索キーワードは「http://m.bing.com/search/CommonPage.aspx?q=iPhone」といったようにパラメータqとして指定されています。引数は丸ごと持ってきていますので、これをここではJavaScriptで取得します。
簡単ですが、引数として渡された検索キーワードをページに表示するサンプルです。
実際に動かしてみた様子を動画にしました。「テストテストをビングで検索」と発声しています。
検索キーワードをページに表示する代わりに、コメントアウトしたTweetbot連携を有効にした場合のデモです。「テストツイートをビングで検索」と発声しています。
かように、検索キーワードを転送先のページに渡すことができるので、転送先ページの処理次第で、いかようなこともできることになります。
僕は、MyScriptsというiOS用の開発環境を使い、渡されたキーワードをそのままTwitterにツイートするようにしました。上掲の転送用ページの中にコメントアウトされたMyScript連携の行ですね。
MyScripts
カテゴリ: 仕事効率化
価格: ¥350
MyScripts側のスクリプトは以下です。渡されたテキストを、一切の問い合わせ無しでツイートするものです。
[iOS]MyScipts単体でTwitterに投稿するスクリプトTweetItでいろいろ捗る | ひとりぶろぐ |
これを転送先のページから起動するようにすると、iPhoneをポケットに入れたまま、ヘッドフォンマイクの発話ボタンを長押しでSiriを起動し、「[つぶやきたいこと]をビングで検索」と発声するだけでTwitterに「[つぶやきたいこと]」の部分を投稿することができます。名付けて「ハンズフリーツイート」!
もちろん、Twitterへの投稿部分を転送先のページからサーバ上のPHP、Ruby、Pythonでやってしまうのでも構いません。
ポケットの中にiPhoneを入れたまま、ヘッドフォンマイクのボタンと音声だけのインターフェースで用を足す、というスタイルがSiriの萌えポイントだと思っているので、これで様々な可能性が開けたと喜んでいます。
キーワードの形式に応じて動作を変更するようにすれば、「ハンズフリーツイート」と「ハンズフリーEvernote」を使い分けといったこともできるかと思います。
「テストツイートをつぶやくをビングで検索」、「昼食650円レバニラ炒めをメモをビングで検索」などと発声するということです。
やってみると分かりますが、自然な文法ではないので、結構意識しないと、立て板に水のごとく発声できません(笑)。
これができるようになると、キーワードに応じてSiriに任意の文章をしゃべってもらいたくなりますが、その方法はありません。
サーバ側で動的に音声合成し、mp3などを生成。それを再生するしかないでしょう。
ここまで書いておいてナンですが、これを実行に移す人は居ないでしょう。
これをサービス化して、簡単な設定で使えるようにしてあげたいのはヤマヤマなのですが、それはプロバイダを営むのとほぼ同義なので、僕にはそれができません。
どうしてもやりたい人は、VPSを借りて自分で設定するか、知り合いを頼るほか無いかと思います。
なにせ、普通のHTTP Proxyの商用サービスすらあまりありませんからね。