OVERFLOW: AUTO;

Aiming to be modern, practical skilled front-end engineer.

Nuxt.js 公式ドキュメントに沿って GAE デプロイしたけどエラーになったので対応した

Nuxt.js を GAE (Google AppEngine) にデプロイするのに詰まってしまったのでその対応の備忘録

ちなみに Nuxt.js は SPA で作っている。

起きたエラー

ja.nuxtjs.org

Nuxt.js のドキュメントを参考にデプロイを進めたものの、デプロイしたはずのページでは以下のメッセージが表示されていた。

Error: Server Error The server encountered an error and could not complete your request. Please try again in 30 seconds.

30秒どころか一晩経っても正常に動く気配はない。

対応したこと

GAE にデプロイする際、app.yml が必要になるが、Nuxt.js の公式ドキュメントでは以下のように書かれていた。

runtime: nodejs10

instance_class: F2

handlers:
  - url: /_nuxt
    static_dir: .nuxt/dist/client
    secure: always
,,,

結論から言うと、static_dir の指定先がまずかった。yarn build コマンドだとたしかに .nuxt/dist/client にミニファイされたコードが生成されるが、それは SSR のお話。

SPA だと yarn generate コマンドで静的ファイルを生成するので、dist としなきゃならなかった。

変更後

runtime: nodejs12

instance_class: F2

handlers:
  - url: /dist
    static_dir: dist
    secure: always
,,,

原因究明した手順

gcloud app logt tail コマンドで GAE のログをリアルタイムで確認することができる。
この存在に気づくまで GAE のダッシュボードで必死に探していた。いやいや、そっちにもあってほしいんだが。

確認してみると、こんなエラーをずっと吐いていたようだ。

2020-12-23 14:40:57 default[20201223t233734]  "GET / HTTP/1.1" 304
2020-12-23 14:40:58 default[20201223t233734]  "GET /_nuxt/xxxxxx.js HTTP/1.1" 404
2020-12-23 14:40:58 default[20201223t233734]  "GET /_nuxt/xxxxxx.js HTTP/1.1" 404
2020-12-23 14:40:58 default[20201223t233734]  "GET /_nuxt/xxxxxx.js HTTP/1.1" 404
2020-12-23 14:40:58 default[20201223t233734]  "GET /_nuxt/xxxxxx.js HTTP/1.1" 404

GET /-nuxt/xxxxxx.js ?」
「いや、yarn build したら .nuxt/dist/client になるはずじゃない?」
と、ここでやっと気づいて対応することができた。

参考にしたサイト

nishinatoshiharu.com

"OK Google" + Nature Remo で部屋の照明をコントロールする

長く過ごす自宅環境をもっと楽しくしていこうと思い、Nature Remo の API で遊んでみました。

経緯

もう2年前になりますが、社内の LT 大会で1位をいただき、賞品にスマートリモコン Nature Remo をいただきました。

家電をアプリでコントロールできるという代物なんですが、当時持っていた家電が古すぎてほとんど使えていませんでした。家時間が増えたことも相まって、今年になってエアコンと照明を新調したため対応家電が増えて遊べる環境が整ってまいりました。

今回はスマホで「OK Google, 休憩入ります」と話すと部屋の照明を消してくれる遊びをやってみます。

環境

  • Android スマートフォン (Pixel3)
  • Nature Remo (第二世代)
  • 照明
  • IFTTT
  • AWS API Gateway

Nature Remo の設定、照明との連携は先に済ませておきます。

想定する動作

Google Assistant での音声リクエストから消灯までの流れは以下のようになります。

  1. Google Assistant で Webhook を叩く。
  2. Webhook が AWS API Gateway にリクエスト。
  3. AWS API Gateway が Nature Remo の Web API を叩く。
  4. Nature Remo が作動して照明を操作する。

準備

Nature Remo

Nature Remo の利用を開始する際にアカウントを作成します。以下の URL から同じアカウントでログインし、アクセストークンを発行します。

アクセストークンは再表示できないので忘れずにメモっておきます。

https://home.nature.global/

Nature Remo の OpenAPI 情報はこちらにまとまっています。

https://developer.nature.global/

家電の ID を取得してみます。

エンドポイントは https://api.nature.global/1/appliances で、先ほどのアクセストークンを付けてリクエストします。

f:id:show-hei:20201223030429p:plain

登録されている家電の情報を取得してきました。アイリスオーヤマの照明であることが分かりますね。

ここで表示される家電の ID をメモっておきます。また、家電の操作の情報も記述されているので確認しておきます。

[
    {
        "id": "{家電 ID}",
        "device": {},
        "model": {},
        "light": { // ① 照明として登録されている場合、このキー名になっている
            "buttons": [
                {
                    "name": "on", // ②
                    "image": "ico_on",
                    "label": "Light_on"
                },
                {
                    "name": "off", // ②
                    "image": "ico_off",
                    "label": "Light_off"
                },
                {
                    "name": "on-100", // ②
                    "image": "ico_light_all",
                    "label": "Light_all"
                },,,,
            ]
        }
    }
]

照明を操作するエンドポイント URL は https://api.nature.global/1/appliances/{家電 ID}/①?button=② のような構成になります。

今回の場合だと https://api.nature.global/1/appliances/{家電 ID}/light?button=off となります。

接続している家電の情報を取得するだけでなく、それらの家電を操作する API も存在しており、今回は照明を消灯する操作の API を使用することにします。

API Gateway

AWS API Gateway から [API を作成] > REST API [構築] を選択します。任意の API 名を入力し作成します。

※ 今回の API は IFTTT で使うのみで他者には共有しないため、プライベート (VPC からのみアクセス可) にはしていません。

照明の操作は POST リクエストのため、[リソース] > [アクション] から POST メソッドを選択します。

メソッドの設定は以下のように行います。

  • 統合タイプ: HTTP
  • HTTP メソッド: POST
  • エンドポイント URL: https://api.nature.global/1/appliances/{家電 ID}/light?button=off
  • HTTP ヘッダー: Authorization : Bearer {アクセストークン}

設定したら再度 [リソース] > [アクション] を開き、[API のデプロイ] を選択します。デプロイするステージなど適宜入力すると API の完成です。

IFTTT

API Gateway で作った URL を IFTTT の Webhook に叩かせましょう。

IFTTT の create から新規の Applet を作っていきます。

ifttt.com

以下が Applet の作成手順になりますが、シンプルな UI であまり迷わずに直感的に作ることができると思います。

Applet 作成: "If This" 項目

  1. If ThisGoogle Assistant を選択。
  2. trigger として Say a simple phrase を選択。
  3. trigger 設定: What do you want to say?休憩入ります と入力。(句読点は入れないよう注意)
  4. trigger 設定: What do you want the Assistant to say in response?ゆっくり休んでね と入力 (ここは空欄でも可)
  5. trigger 設定: Language で Japanese を選択し、Create trigger をクリック。

Applet 作成: "Then That" 項目

  1. Then ThatWebhooks を選択。
  2. action として Make a web request を選択。
  3. web request 設定: URL に API Gateway で作成した API を入力。
  4. web request 設定: Method -> POST, Content Type -> application/json を選択し、Create action をクリック。

完成

以上の工程で完成となります。

手持ちのスマホや Google home などで「OK Google, 休憩入ります」と話せば「ゆっくり休んでね」と応えてくれて消灯までしてくれるようになりました。

さいごに

もう少し実装して、休憩時間の終わりも知らせてくれると嬉しいですね。

アラーム代わりに照明を点けてくれて、ついでに Spotify API 経由で音楽を流してくれる、みたいにすると午後も楽しくお仕事できそうです。