kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

Kubernetesクラスタの証明書更新(kubeadm)

f:id:kun432:20210120011530p:plain

メモ。

kubeadmで作成したkubernetesクラスターの証明書の期限はデフォルト1年になっていて、ソースコードに埋め込まれています。なのでパッケージを使っている場合はオプションとかでは変更できませんが、kubeadm cert renewというコマンドで更新ができるみたいです。試してみました。

環境

以下のチュートリアルで紹介しているVagrantのレポジトリで作成したクラスタで試してみます。

GitHubのレポジトリはこちら。

パッケージを使っているので、更新切れの状態は再現できないのですが、残りの証明書期限がが更新されているか?で確認してみたいと思います。

  • Ubuntu 18.04.6 LTS
  • docker-5:19.03.8~3-0~ubuntu-bionic
  • containerd-1.2.13-1
  • kubernetes-1.18.0-00
  • calico v3.13

Vagrantではシェルスクリプトを使ってプロビジョニングしてます。kubeadm initはこんな感じ。

sudo kubeadm init \
  --control-plane-endpoint="${IPADDR}:6443" \
  --apiserver-advertise-address="${IPADDR}" \
  --kubernetes-version="v1.18.0" \
  --pod-network-cidr="192.168.0.0/16" \
  --upload-certs

証明書の期限の確認

公式に従って、kubeadm certs check-expirationを実行してみる。

vagrant@master:~$ sudo kubeadm certs check-expiration
unknown command "certs" for "kubeadm"
To see the stack trace of this error execute with --v=5 or higher

サブコマンドcertsが対応していない・・・ドキュメントを見る限りv1.15でstableになってるように思えるのだけど、v1.18でもstableではないのかな?alphaをつけてみる

vagrant@master:~$ sudo kubeadm alpha certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Jan 01, 2023 13:06 UTC   364d                                    no
apiserver                  Jan 01, 2023 13:06 UTC   364d            ca                      no
apiserver-etcd-client      Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Jan 01, 2023 13:06 UTC   364d            ca                      no
controller-manager.conf    Jan 01, 2023 13:06 UTC   364d                                    no
etcd-healthcheck-client    Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
etcd-peer                  Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
etcd-server                Jan 01, 2023 13:06 UTC   364d            etcd-ca                 no
front-proxy-client         Jan 01, 2023 13:06 UTC   364d            front-proxy-ca          no
scheduler.conf             Jan 01, 2023 13:06 UTC   364d                                    no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Dec 30, 2031 13:06 UTC   9y              no
etcd-ca                 Dec 30, 2031 13:06 UTC   9y              no
front-proxy-ca          Dec 30, 2031 13:06 UTC   9y              no

ということでcerts renewで更新してみる。alphaつきで。

vagrant@master:~$ sudo kubeadm alpha certs renew all
[renew] Reading configuration from the cluster...
[renew] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
certificate for serving the Kubernetes API renewed
certificate the apiserver uses to access etcd renewed
certificate for the API server to connect to kubelet renewed
certificate embedded in the kubeconfig file for the controller manager to use renewed
certificate for liveness probes to healthcheck etcd renewed
certificate for etcd nodes to communicate with each other renewed
certificate for serving etcd renewed
certificate for the front proxy client renewed
certificate embedded in the kubeconfig file for the scheduler manager to use renewed

一応できたっぽいので確認。

vagrant@master:~$ sudo kubeadm alpha certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Jan 01, 2023 13:51 UTC   364d                                    no
apiserver                  Jan 01, 2023 13:51 UTC   364d            ca                      no
apiserver-etcd-client      Jan 01, 2023 13:51 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Jan 01, 2023 13:51 UTC   364d            ca                      no
controller-manager.conf    Jan 01, 2023 13:51 UTC   364d                                    no
etcd-healthcheck-client    Jan 01, 2023 13:51 UTC   364d            etcd-ca                 no
etcd-peer                  Jan 01, 2023 13:51 UTC   364d            etcd-ca                 no
etcd-server                Jan 01, 2023 13:52 UTC   364d            etcd-ca                 no
front-proxy-client         Jan 01, 2023 13:52 UTC   364d            front-proxy-ca          no
scheduler.conf             Jan 01, 2023 13:52 UTC   364d                                    no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Dec 30, 2031 13:06 UTC   9y              no
etcd-ca                 Dec 30, 2031 13:06 UTC   9y              no
front-proxy-ca          Dec 30, 2031 13:06 UTC   9y              no

更新されていますね。/etc/kubernetes以下も更新されている。ここは一旦バックアップしておいたほうが良かったかも。

vagrant@master:~$ ls -lt /etc/kubernetes/
total 36
-rw------- 1 root root 5433 Jan  1 22:52 scheduler.conf
-rw------- 1 root root 5485 Jan  1 22:51 controller-manager.conf
-rw------- 1 root root 5449 Jan  1 22:51 admin.conf
-rw------- 1 root root 1861 Jan  1 22:06 kubelet.conf
drwxr-xr-x 2 root root 4096 Jan  1 22:06 manifests
drwxr-xr-x 3 root root 4096 Jan  1 22:06 pki

とりあえずは問題なさそう。api-serverの再起動が必要になるっぽい。いっそrebootしてみます。

vagrant@master:~$ sudo reboot

reboot後にかんたんに動作確認してみる。ということでkubeconfigも更新。

$ cp -pir ~/.kube ~/.kube_BK
$ sudo cp /etc/kuberentes/admin.conf ~/.kube/config
vagrant@master:~$ kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
master     Ready    master   57m   v1.18.0
worker-1   Ready    <none>   52m   v1.18.0
worker-2   Ready    <none>   46m   v1.18.0

vagrant@master:~$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-5f579f6866-tlgb7   1/1     Running   1          58m
kube-system   calico-node-vhhsq                          1/1     Running   1          58m
kube-system   calico-node-xg2dn                          1/1     Running   0          48m
kube-system   calico-node-xr9br                          1/1     Running   0          53m
kube-system   coredns-66bff467f8-74txk                   1/1     Running   1          58m
kube-system   coredns-66bff467f8-xhc94                   1/1     Running   1          58m
kube-system   etcd-master                                1/1     Running   1          58m
kube-system   kube-apiserver-master                      1/1     Running   1          58m
kube-system   kube-controller-manager-master             1/1     Running   1          58m
kube-system   kube-proxy-7ncn4                           1/1     Running   1          58m
kube-system   kube-proxy-flrfp                           1/1     Running   0          48m
kube-system   kube-proxy-wm7pp                           1/1     Running   0          53m
kube-system   kube-scheduler-master                      1/1     Running   1          58m

kubectlがつながるまでに少し時間がかかるのとcorednsがなかなか上がってこなかったぐらいで、最終的には問題なかった。

workerもrebootしてみます。

vagrant@worker-1:~$ sudo reboot
vagrant@worker-2:~$ sudo reboot

こちらも問題なし。

ただ、公式のドキュメントを見る限り、kubeletの証明書も更新されるのかなと思うんだけど。

Note: kubelet.conf is not included in the list above because kubeadm configures kubelet for automatic certificate renewal with rotatable certificates under /var/lib/kubelet/pki. To repair an expired kubelet client certificate see Kubelet client certificate rotation fails.

更新されていないように見える。(ノード構築してkubeadm joinしたときのタイムスタンプになってる様子)

vagrant@master:~$ sudo ls -lt /var/lib/kubelet/pki
total 12
-rw------- 1 root root 2761 Jan  1 22:06 kubelet-client-2022-01-01-22-06-22.pem
lrwxrwxrwx 1 root root   59 Jan  1 22:06 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2022-01-01-22-06-22.pem
-rw-r--r-- 1 root root 2153 Jan  1 22:06 kubelet.crt
-rw------- 1 root root 1675 Jan  1 22:06 kubelet.key
vagrant@worker-1:~$ sudo ls -lt /var/lib/kubelet/pki
total 12
-rw------- 1 root root 1070 Jan  1 22:11 kubelet-client-2022-01-01-22-11-34.pem
lrwxrwxrwx 1 root root   59 Jan  1 22:11 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2022-01-01-22-11-34.pem
-rw-r--r-- 1 root root 2165 Jan  1 22:11 kubelet.crt
-rw------- 1 root root 1675 Jan  1 22:11 kubelet.key
vagrant@worker-2:~$ sudo ls -lt /var/lib/kubelet/pki
total 12
-rw------- 1 root root 1066 Jan  1 22:16 kubelet-client-2022-01-01-22-16-39.pem
lrwxrwxrwx 1 root root   59 Jan  1 22:16 kubelet-client-current.pem -> /var/lib/kubelet/pki/kubelet-client-2022-01-01-22-16-39.pem
-rw-r--r-- 1 root root 2165 Jan  1 22:16 kubelet.crt
-rw------- 1 root root 1675 Jan  1 22:16 kubelet.key

勝手に更新されるんだろうか?色々見てると、token作り直してbootstrapさせるみたいだけど/etc/kubernetes/kubelet-bootstrap.confもないしなぁ。。。

このあたりやっぱりソースいじって、実際にその状況作ってみないとわからない。

Voiceflow Dialog Management APIことはじめ

f:id:kun432:20210313005910p:plain

ずいぶんとご無沙汰してしまいましたが、久々のVoiceflowエントリ。

以下で紹介したVoiceflow SDK,実はすでにObsoleteになっています・・・・

Voiceflow SDKに変わって、現在新しく提供されているのが『Voiceflow Dialog Management API』です。

どのように使うのか、実際にやってみましょう。

目次

カスタムアシスタントとDialog Management APIについて

まず最初に、カスタムアシスタントについて説明しておきましょう。比較としてわかりやすいので、最初にAlexaやGoogle向けのプロジェクトを作成した場合の構成をまとめてみました。

f:id:kun432:20211228222135p:plain

VoiceflowでAlexa/Google向けプロジェクトを作る場合、VoiceflowのGUIインタフェース上で会話フローを作成するので、このあたりの構成をあまり意識することはありませんが、実際には、

  • スマートスピーカーが受け取ったユーザの発話を、それぞれのプラットフォームが提供しているクラウドに渡す。
  • プラットフォームのクラウド上で音声認識を行い、インテントやスロットなどをバックエンドの会話ロジックに渡す。
  • バックエンドが受け取ったインテントやスロットをもとに会話の流れを判断して応答を返す。

というような流れになります。Voiceflow上では「プロジェクト」として作成していますが、実際には「対話モデル」と「会話ロジック」は別々に処理されて、それぞれが連携する形です。そしてユーザと直接触れ合うインタフェース部分は「スマートスピーカー」が担います。

これに対して、カスタムアシスタントの場合はこんな感じになります(多少正確ではないです)

f:id:kun432:20211228223111p:plain

カスタムアシスタントは独自のアシスタントです。AlexaやGoogleの場合にプラットフォームが提供するクラウド部分も、バックエンドとまとめてVoiceflowが提供しますが、ユーザとのインタフェース部分は用意されていません。この部分については開発者が自分で用意する必要があります。

これだけ聞くとカスタムアシスタントのほうが面倒に思えますが、逆にいうとAlexa/Google向けプロジェクトでは、それぞれが提供している枠組み以外の使い方ができません。つまりフロントエンドのユーザインタフェース部分もそれぞれのプラットフォームが提供するスマートスピーカーしか使えないわけですね(Googleの場合はスマホのGoogleアシスタントアプリも使えますが)。

カスタムアシスタントではこの制限がないため、フロントエンド部分は自由に選択ができます。例えばこのあたり。

  • Webサイト内の埋め込みチャットボット
  • スマホアプリのチャットボット
  • いろいろなチャットツール(Slack/LINE/MS Teams/Facebook Messenger/Discordなどなど)

これらを、バックエンドとして作成したVoiceflowプロジェクトとつなぐごとで、さまざまなインタフェースに対応した音声/チャットボットを作成することができるというわけですね。

そして、この開発者が作成するフロントエンドとVoiceflowのプロジェクトをつなぐのが『Voiceflow Dialog Management API』というわけです。

ちなみに以前ご紹介した「Voiceflow SDK」は、このAPIとの接続処理などをラップしたクライアント向けライブラリとして提供されていましたが、APIが独立して提供されるようになり、仕様もおそらく変わったため、Obsoleteされたということだと思います。なお、今のDialog Management APIにあわせた新しいSDKが近々出るみたいです)

Dialog Management APIの種類

Dialog Management APIには2つの種類があります。

  • State API
  • Stateless API

"State"というのは、会話の「状態」です。Voiceflowの会話フローの中で、誰の会話フローなのか?会話フローのどこにいるか?会話フロー中のどんな情報を保持しているのか?を管理します。

State APIは、この「状態」をVoiceflow側が持ちます。開発者側は一意となるキーを用意してAPIにリクエストを送るだけで、面倒な会話の状態管理をVoiceflow側に任せることができ、単にVoiceflowとつなぎこむ処理だけに集中することができます。

Stateless APIは、Voiceflow側では状態を持たずに、開発者側のアプリ側など自前で持つことになります。したがって、会話の流れを追うためには毎回すべての「状態」に関する情報をAPIに投げる必要があり、セッションや状態の管理も自前で行う必要がありますが、その反面、細かくセッション管理を行いたい場合や、センシティブな情報をクラウド側に渡さずにきちんと自分で管理したい場合などに向いている、というわけですね。

今回は簡単に使えるState APIの方を使ってみましょう。

サンプルプロジェクト

サンプルとなるプロジェクトを用意しました。以下の.vfファイルをダウンロードしてください(右クリックでダウンロード)。

https://raw.githubusercontent.com/kun432/voiceflow-samples/main/dialog-managment-api/dialog-management-api-sample.vf

Voiceflowのプロジェクト一覧画面の右上にあるインポートメニューからインポートします。

f:id:kun432:20220101023503j:plain

インポートされたらプロジェクトを開きます。(もし以下のメッセージが消えてしまって見えない場合は「Dialog Management APIサンプル」という名前のプロジェクトを開いてください。)

f:id:kun432:20220101023539j:plain

こんな感じのプロジェクトが開きます。

f:id:kun432:20220101024159p:plain

カスタムアシスタントプロジェクトでは、プロジェクトをインポートした場合や対話モデルを変更した場合、トレーニングが必要になります。右上の青いアイコンをクリックしてテスト画面に移ります。

f:id:kun432:20220101024000j:plain

右側に「トレーニングが必要」というようなメッセージが表示されるかと思いますので、"Train your assistant"をクリックします。

f:id:kun432:20220101024321j:plain

対話モデルのトレーニングが行われます。少し待ちます。

f:id:kun432:20220101025810p:plain

Trainedが100%になっていればトレーニングは完了です。下にある"Run test"をクリックしてテストしてみましょう。

f:id:kun432:20220101030157j:plain

f:id:kun432:20220101024647p:plain

ユーザの名前と年齢を聞くだけのとてもシンプルなものですね。名前と年齢は、恒久的な変数として保存するようにしてます。よって、2回目以降は何も聞かれずにこういうふうになる想定です。

f:id:kun432:20220101024820p:plain

ちなみに、Voiceflowのテストモードでは変数は恒久的に保存されませんが、変数の値を自分でいじることができます。これにより、擬似的に2回目以降を再現することができます。 f:id:kun432:20220101025610j:plain

これをDialog Management API経由で動かせるようにします。

APIキー・バージョンIDの取得

Dialog Manament APIにアクセスするには以下が必要になります。

  • APIキー
    • Dialog Management API経由でプロジェクトにアクセスするための認証キー。
    • 現状はプロジェクト単位ではなく、「すべて」のプロジェクトにアクセスできるようになってしまうため、取り扱い注意!
  • バージョンID
    • 個々のプロジェクトを区別するためのID。
    • こちらは漏れても多分大丈夫。

これらを取得していきましょう。

プロジェクト画面の左にある"Integration"をクリックします。

f:id:kun432:20220101030905j:plain

APIキーの発行画面が表示されます。

f:id:kun432:20220101031522p:plain

実行例が表示されていると思いますが、ここにバージョンIDがありますので控えておきます。

f:id:kun432:20220101031656j:plain

ちなみにプロジェクトのURLからも確認できます。

f:id:kun432:20220101034219j:plain

次にAPIキーです。こちらは実行例にも表示されていません(それだけ重要ということですね)。下の方に"Create API Key"というメニューがありますので、ここの"Create Key"をクリックします。

f:id:kun432:20220101034901j:plain

APIキーが表示されます。APIキーは一度表示されたあとは再度表示することはできません(削除して作り直すしかなくなります)。"Copy to Clipborad"をクリックすると、クリップボードに保存されるので、どこか安全な場所にペーストして保管しておきましょう

f:id:kun432:20220101035050j:plain

これでDialog Management APIを使うのに必要な情報が集まりました。

Node.jsでDialog Management APIにアクセスする

では実際にコードを書いてDialog Managemet APIにアクセスしてみましょう。Node.jsでやってみたいと思いますので実行環境を用意しておいてください。

公式のサンプルコードは以下のレポジトリのnodeJSディレクトリ以下にあります。

が、残念ながらこれ動きません!問い合わせてみたところ、現在APIの仕様変更を行っている途中らしく、サンプルコードはすでにそれに合わせたものになっていますが、仕様変更されたAPIがまだリリースされていないので、このサンプルコードでは動かないということみたいです。

ということで、仕様変更前のAPIに合わせたサンプルコードのレポジトリを用意しました。

ちなみに、仕様変更後のAPIでは、バージョンIDが不要になり、APIキーはプロジェクト単位になるだけらしいので、基本的なAPIリクエストやロジックは、公式のサンプルコードも私のサンプルコードも大きな違いはないです。

git cloneします。

$ git clone https://github.com/kun432/voiceflow-dialog-management-api-sample-ja
$ cd voiceflow-dialog-management-api-sample-ja/nodejs-cli

必要なライブラリをインストールします。

$ npm install

index.jsをエディタで開いて、以下のYOUR_API_KEY_HEREYOUR_VERSION_ID_HEREを先程取得したAPIキー・バージョンIDで書き換えてください。

const API_KEY = "YOUR_API_KEY_HERE";
const VERSION_ID = "YOUR_VERSION_ID_HERE";

では実行してみましょう。

$ npm start

ここからコマンドラインの対話がスタートします。

> voiceflow-api-nodejs-example@1.0.0 start
> node index.js

セッションを開始します。
> ユーザーIDを入力してください。: 

ユーザーIDと書いていますが、これが「状態」を管理するためのキーのことです。一般的にこのキーはユーザーごとに管理することが多いと思いますので、ユーザーIDという言い方にしています。適当な文字列を入力します。あとは質問に従って入力してください。

...
> ユーザーIDを入力してください。: 000001
...
あなたのお名前を言ってください。
> 入力: 太郎
...
太郎 さん、こんにちは。
あなたの年齢を言ってください。
> 入力: 20歳
...
太郎 さんの年齢は、20 歳です。
セッションを終了します。

一通り入力が終わるとセッションは終了です。Voiceflow上でのテストと同じように、NodeJSのコードからもプロジェクトの会話フローにアクセスできているのがわかりますね。

もう一度実行してみましょう。ユーザーIDに先ほどと同じ文字列を入力してみてください。

$ npm start

> voiceflow-api-nodejs-example@1.0.0 start
> node index.js

セッションを開始します。
> ユーザーIDを入力してください。: 000001
...
太郎 さん、こんにちは。
太郎 さんの年齢は、20 歳です。
セッションを終了します。

はい、入力を求められることなく実行が完了し、かつ、1回目に入力した情報がきちんと表示されています。つまりユーザーIDに会話の「状態」が永続的に紐付いているということになります。State APIを使うとこのように会話の状態をVoiceflow側で保存してくれます。

サンプルコードはこんな感じです。

cURLでDialog Management APIにアクセスする

では次にcURLを使って詳細にやってみましょう。

最初にAPIキー、バージョンID、ユーザーIDをセットしておきます。

$ API_KEY='VF.XXXXXXXXXXXXXXXXXXX.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
$ VERSION_ID='XXXXXXXXXXXXXXXXXXXX'
$ USER_ID='000002'

State APIで会話のやり取りを行うためのエンドポイントは以下になります。

https://general-runtime.voiceflow.com/state/$VERSION_ID/user/$USER_ID/interact

AuthorizationヘッダーにAPIキーをセットして、JSONでリクエストを投げればよいです。やってみましょう。

まずは会話フローの開始です。会話フローを開始するには以下のようなJSONを投げます。

{
    "request": { 
        "type": "launch"
    }
}

type: launchで会話フローの一番最初から実行されます。

$ curl -s -X POST "https://general-runtime.voiceflow.com/state/$VERSION_ID/user/$USER_ID/interact" -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"request": {"type": "launch"}}' | jq .
[
  {
    "type": "speak",
    "payload": {
      "message": "あなたのお名前を言ってください。",
      "type": "message"
    }
  }
]

最初のspeak blockの内容が返ってきていますね。

こちらからの応答を送信するには以下のようなJSONを投げます。

{
    "request": { 
        "type": "text",
        "payload": "送信する文字列"
    }
}
$ curl -s -X POST "https://general-runtime.voiceflow.com/state/$VERSION_ID/user/$USER_ID/interact" -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"request": {"type": "text", "payload": "花子"}}' | jq .
[
  {
    "type": "path",
    "payload": {
      "path": "choice:1"
    }
  },
  {
    "type": "speak",
    "payload": {
      "message": "花子 さん、こんにちは。",
      "type": "message"
    }
  },
  {
    "type": "speak",
    "payload": {
      "message": "あなたの年齢を言ってください。",
      "type": "message"
    }
  }
]

ちなみにAPIからのレスポンスは配列で返ってきます。複数のSpeak blockに分かれている場合などは順番に返ってきてますし、発話の応答以外にもChoice blockの分岐っぽい情報が含まれていたりします。

さらに返してみます。

$ curl -s -X POST "https://general-runtime.voiceflow.com/state/$VERSION_ID/user/$USER_ID/interact" -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"request": {"type": "text", "payload": "25歳"}}' | jq .
[
  {
    "type": "path",
    "payload": {
      "path": "choice:1"
    }
  },
  {
    "type": "speak",
    "payload": {
      "message": "花子 さんの年齢は、25 歳です。",
      "type": "message"
    }
  },
  {
    "type": "end"
  }
]

会話フローが終了すると、type: endが返ってきます。

同じユーザーIDを使って再度type: launchでリクエストを送ると、ちゃんと会話の状態が保存されていることがわかります。

$ curl -s -X POST "https://general-runtime.voiceflow.com/state/$VERSION_ID/user/$USER_ID/interact" -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"request": {"type": "launch"}}' | jq .
[
  {
    "type": "speak",
    "payload": {
      "message": "花子 さん、こんにちは。",
      "type": "message"
    }
  },
  {
    "type": "speak",
    "payload": {
      "message": "花子 さんの年齢は、25 歳です。",
      "type": "message"
    }
  },
  {
    "type": "end"
  }
]

まとめ

ということで、Dialog Management APIに触ってみました。SDKも便利でしたが、APIもシンプルに使えて便利ですね。

State APIには他にも、状態の取得や削除といったこともできますし、Stateless APIであれば、手元で状態の管理が行なえますので、ユースケースに合わせて選択すればよいかと思います。詳細はドキュメントをご覧ください。

www.voiceflow.com

次回はLINEやSlackなどと実際に連携してみたいと思います。

買ってよかったもの2021

f:id:kun432:20211230010652p:plain

お題「#買って良かった2021」

去年に引き続き、今年買ってよかったもののまとめ。リモートもすっかり普通になって、全体的にお家にこもって使うものが多い感じになりました。

2020年版はこちら。

目次

買ってよかったもの

FLEXISPOT昇降スタンディングデスクE3W

※実際に購入したものとは型番が異なります。

流行りに乗って、昇降スタンディングデスク買ってしまいました。実際にはあまり昇降させてないしスタンディングで使うこともあまりなかったりしますが、前に使っていたものよりもデスクスペースも広いし、モニタやデスクライトも全部アームでつけれてとても満足。奥さんの分も買って向い合せでリビングに鎮座させてます。ネット依存度高いし、仕事専用の部屋をわざわざ作るのもね、ということで。ホームオフィスっぽくて満足してます。

天板は120x60。もうちょっと広くすればよかったかなと思ったりもするけれど、スペースの都合上、この辺が限界でした。

椅子は去年買った↓を使っているけど、ちょっといい椅子がほしいなーと思っているところ。

これレビューがとても良いので気になってます。

ウクレレ

f:id:kun432:20211229220313j:plain

夫婦で一緒に楽しめる趣味が欲しいなーと思って、不意に思い立って始めてみました。音もそんなに大きくないし、ボディも小さくて取り回ししやすいので、弾きたいときにサラッと弾けるのがよいですね。ただフレットの狭さはちょっとつらい気がしたので、最初からコンサートタイプを選びました。

そして、さらに大きな音が欲しくなってテナータイプも買ってしまいました。フレットも広いので弾きやすいです。

こういうのを練習してます。

ギター歴はそこそこあるので私の方は違和感なかったのですが、いっしょに始めた奥さんの方は弦楽器初めてということもあって、最初のハードルがなかなか高かったみたい。でも一緒にやってるうちに↑の動画と同じぐらいは弾けるようになっててびっくりです。

年取っても一緒に弾けるといいなと思います。

Spark Amp

ギターアンプなのですが、これはほんとすごい。詳しくはこの動画を。

アプリと連動して、アンプシミュレータやエフェクターが色々使えるのはもちろん、動画を解析してコードを表示したり、自動的にコード進行を生成したりして、とこんなところでも機械学習がガンガン活用されていて、ギターアンプにも「スマート」な時代が来てるのだなーと実感できます。実際に自宅でアンプを鳴らすことはほとんどないのだけど(小さくてもやっぱりうるさいのでマンションだとちょっと難しい・・・)、ヘッドフォンも使えるので特に困らないし、コンパクトなので取り回しもしやすい。

これを買ったおかげで、より便利に活用すべく、色々買い足したりして、結構散財してますw

フットスイッチがあれば完璧だけど、結構するのですよね・・・ちょっと悩み中

Pan& / パンスク

f:id:kun432:20211229235035p:plain

今年新たに始めた宅配パンのサブスクです。去年もBASE BREADを使っていてそれなりに満足していたのですが、ちょっとづつ求めるものが変わってきて、今は以下の2つを併用しています。

  • Pan& (https://pand.jp/
    • パンのバリエーションはそれなりに豊富。新作はたまにしか出ない。
    • 1回のボリュームは自分で調整できるし、まとめ買いでの割引などもあって、コスパはまあまあ。
  • パンスク (https://pansuku.com/
    • 全国のパン屋さんから毎月1回送られてくる。何が来るかは来てのお楽しみ。
    • 価格に対してボリュームはちょっと少なく感じる。

BASE BREAD、そんなに悪いわけではないんですが、選べるバリエーションがとても少なくて飽きちゃったんですよね。完全食で健康志向がウリなので、ちょっとお門違いな理由なのかもしれないけど。

その点、上記の2サイトはバリエーションの問題を解決してくれるのでを満たしてくれるので満足していますが、1ヶ月間毎朝消費することを考えると片方だけだと微妙に痒いところに手が届かない感もあって、ややコストは張りますが今のところは併用するのがいい感じになってます。

他にもパンのサブスクはいろいろあるみたいなので、気が向いたら試してみたい。

ウイニングポスト9 2021

Winning Post 9 2021

Winning Post 9 2021

  • コーエーテクモゲームス
Amazon

「ウマ娘」をちょっと始めてみて、少し本格的にやりたいなーと思ったのがきっかけ。競馬ゲームは初代ダビスタ・初代ウイニングポスト以来だからもう何十年ぶりだろう?いつのまにやらめちゃめちゃ進化しててびっくり。シンボリルドルフの時代にさかのぼって、そこから自分だけの競馬史をなぞったりできてので、とても懐かしい気持ちになったり。ただ、これほんと辞め時が難しくて時間を際限なく消費するので自制心が必要ですw。

そうしているうちに2022が出るらしいのでまた時間泥棒に・・・・

【PS4】Winning Post 9 2022

【PS4】Winning Post 9 2022

  • コーエーテクモゲームス
Amazon

即PAT

f:id:kun432:20211230000654p:plain

そんな競馬ゲーム熱は冷めやらず、ついにリアル競馬へ。いつでも自宅で馬券が買える「即PAT」に加入してしまいました!

馬券買うのも数十年ぶり。昔は単勝/複勝/枠連/馬連しかなかったのが、今は3連単/複やらマルチやらいろんな買い方も増えているし、あと地方競馬や海外競馬の馬券もスマホでサラッと買えたりして、隔世の感が半端ないです。ファミコンでPATとかの時代がホント懐かしい・・・

毎週末、100円単位でちびちびやってる程度ですが、楽しいですね(全然勝てないけど)。そして今年最後の大きなレースはなんとかゲットしました!

f:id:kun432:20211230013632j:plain

競馬情報サイトもものすごく便利になっていて、こちらにもとてもお世話になってます。

ウマ娘からリアル競馬に行く人が増えているらしく、こういう逆転現象は面白いですね。

お耳に合いましたら

ポッドキャストがテーマということで興味を持って、なんの気なしに見始めたらガッツリ一気見てしまいました。普通の会社員である主人公がポッドキャストを始めるっていうのが今っぽいし、ポッドキャストの機材の話とかもちょっと面白かったですね。普段はドラマとかあまり見ない(毎週決まった時間に1時間拘束されるのが苦痛、いちいち録画もめんどくさい)のですが、こういう30分ぐらいのゆるーい感じのやつだと気楽に見れてよいです。今は配信サイトで好きなときに見れますしね。

ちなみに、番組中でやっているポッドキャスト、実際に聞けたりします。(Spotifyがスポンサーなので納得)

花澤さんのオープニングもラブリーな感じでよいです。

Amazon Primeビデオなどの配信サイトで見れます、つまりEcho Showで見れたりするわけですね!興味があればぜひ。

Raspberry Pi

今更感満載ですが、きっかけはこれ。

f:id:kun432:20211230010351j:plain

Raspberry Pi Kubernetes クラスタ・モニタ付です!残念ながら時間がなくてまだ完成していない!w

のだけど、久々にRPi触ってみてやっぱりお手軽で面白いなーと。普通に使うだけならクラウドなりVMなりのほうが便利ではあるんだけど、ハードで組むのはやっぱり面白いです。結構お金はかかってますがw

PoE+のスイッチやBGP喋れるコンパクトルータと組み合わせて、おもちゃだけど本格的なおうちKubernetesクラスタを組む予定。これはまたそのうちまとめます。

RPiの在庫不足で入手が一番苦労したのだけど、なんとか最低限の台数は確保しました。あとworkerノード用に1台追加したいなーと。

ついでにこいつも。キーボードはいまいちだけど、一体型はやっぱり便利ですね。

FireHD10Plus

毎日一番ヘビーに活用してるのがこれ。先代を持ってるのだけど、結構重たく感じることが多くなってきたのでリプレースしました。新型はさすがにキビキビ動きますし、ストレージも64GBで当面困ることはなさそう。スマホよりもこっちの使用頻度のほうが高いですね、画面も大きくて老眼にもやさしいしw。ブラウジング/YouTube/Kindleはこれで十分です。あとはShowモードも使えるので、持ち出せるEcho Showとしても活用できます。

キーボードも合わせて買ってみたのだけど、こちらはちょっとキー配列にクセがあってとっつけず。でもまあ旅行とかで持っていく分にはいいかもしれない。

まとめ

リモートワーク環境が普通になってその中で使うものが多くなってますね、ただ「ワーク」感はあまりなくって、より普段の生活に近いものが多い気がします。こうやってライフスタイルも変わっていくのかなーと思ったりしてます。