iPhoneでテキストを音声入力してHTTPサーバにPOSTする
WebベースのTODOアプリを試作していたのですが、ブラウザ上のフォームからキーボードで入力するだけでなく、iPhoneの音声入力を用いて手がふさがっているときでも入力を行えるようにできないか方法を考えていました。その結果、「ショートカット」というiPhoneの標準アプリで実現できました。この記事でやり方を記載します。
「ショートカット」を使うと、以下の流れが簡単に実現できます。一連の操作がすべて音声で完結します。
- iPhoneがスリープ状態の時に、「Hey Siri タスク」と呼びかけることで自作のショートカットを起動する
- 「タスク」は自作のショートカットの名前。好きな名前を指定できる。
- ショートカット内で音声入力によりテキストを受け取る
- 受け取ったテキストを含むJSONを作成し、HTTPベースのAPIに対してPOSTする
- API呼び出し結果を音声で読み上げる
iOSバージョンは15.5です。
ショートカットの作り方
今回タスクを登録するAPIは、curlだと以下のようにして呼び出せる自作のものです。認証用のトークンとタスク名を含んだJSONをPOSTし、成功({"result":true}
)/失敗({"error":"some message"}
)がJSONで返ってきます。これを、ショートカットを用いて呼び出すことが目標です。
curl -X POST -H "Content-Type: application/json" -d '{"token":"xxx", "title":"hello from curl"}' https://******.cloudfunctions.net/addTask
「ショートカット」アプリを起動し、右上の「+」ボタンで新規ショートカットを作成します。
ショートカット作成画面です。上部の「ショートカット名」のところに任意の名前を付けます。この名前はSiriでショートカットを呼び出すときに使うので、短いカタカナにするのが良いと思います。画面下部の「App及びアクションを検索」を用いて「アクション」を追加していきます。
操作は直感的なのであまり悩まず進められると思います。以下の順序でアクションを並べれば完成です。
アクション名の一覧を示します。
ポイントは、
- 音声入力したテキストを変数に設定する
- 「URLの内容を取得」で「本文を要求」を設定し、フィールドの値に先ほど生成した変数を指定する。なお、tokenの内容は変数ではなく文字列をそのまま書いています。
- API呼び出し結果がJSONで得られるので、「辞書」に関する機能で解釈します。成功時は「完了」と音声で読み上げ、失敗時はエラーメッセージそのものを読み上げます(自分で使うアプリなのでこれで十分)。
Siriへの明示的な登録は不要で、ショートカット作成画面の上部に書いてある通り、「Hey Siri、タスク」と呼びかければ起動します。また、画面右下の再生ボタンでこの場で実行することも可能です。
(備考) APIの作り方
HTTP POSTを受け付けてデータベースに記録するAPIですが、FirebaseのFunctions機能を使って実装しています。詳細は割愛しますが、こんな感じの実装になっています。
import * as functions from "firebase-functions"; import * as admin from "firebase-admin"; admin.initializeApp(); export const addTask = functions.region("asia-northeast1").https .onRequest(async (request, response) => { try { // request.bodyにPOSTされたJSONが入っている const token = request.body.token; const title = request.body.title; // トークンの検証 (省略) // firestore(データベース)にデータを追加 const store = admin.firestore(); await store.collection("tasks").add({ title, }); response.send({"result": true}); } catch (error) { response.status(403).send({"error": (error as Error).message}); } });
以上のように、ショートカットアプリを使うことで、iPhoneアプリを開発せずとも音声入力、APIの呼び出しができることがわかりました。サーバサイドのコードさえ書ければ、ハンズフリーで様々なタスクをこなせて便利だと思います。