今日は何のセールスの日？Voiceflowで即答してくれるアレクサたんを作ってみる

# 店舗にいるとわからなくなることがある。山ほどあるセールスやキャンペーンの類に。
私は現在とあるスーパーの本社採用担当として勤務しているが、そんな私にも店舗で働く新入社員時代があった。そしていつも大量にあるキャンペーンやセールスに悩まされていたのである。
毎月10日、20日など特定の日にちに決まってやってくるセールスはいいのだが、ランダムに展開される「ポイント2倍ウィーク」（※注：時に3倍やら10倍やら色々ある）やお誕生日の割引パスポートやらギフトの早得セールやら野球の球団応援セールスやら、なにやらかにやらうんぬんかんぬん（以下略）に「**なんでこんなにセールス多いねん、一度に覚えられんわ！**」とまだ若かった私は翻弄されるばかりであった。
一体今日は何のセールスをやっている日なのか、すべてを網羅し、諳んじることができる販売員などいるのだろうか？いや、いない。（反語）
※いらっしゃったらごめんなさい。

そこで私はとあるものを開発することにした。最近はアレクサをノーコードで実装できるという。本当なのだろうか。そんな便利なことがこの世にあっていいのだろうか。私の頭の中のイメージはこうだ。
![アレクサ最初.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/7e090ba0-bfe4-8342-7d59-bd8ae9af0503.jpeg)
たまに百戦錬磨の販売員でも「ん？このキャンペーン初耳。どんな内容なんだ？」と思う謎のキャンペーンがある。まずはその日にやっているセールス、続いてキャンペーンの詳細、ここまで網羅できるアレクサがいたら即戦力である。私は胸に静かな情熱を秘め、いざ実装に取り掛かるのであった…。

# 1.準備するもの
　　:point_up_2_tone1:Voiceflow
　　:point_up_2_tone1:Googleスプレッドシート
　　　　Googleスプレッドシートには予め下記のようにデータを入れておく。
![スプレッドシート.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/8ded1ee8-0a4f-45f3-bd76-c62719a89bc3.jpeg)
今回はシート名を「セールスシート」、A1セルには`date` B1セルには`sales1`という名称を入力しておいた。

:::note warn
シート名は日本語表記ではなく、英語表記が望ましい
:::

# 2.参考にした記事

https://zenn.dev/kun432/books/f6e1b45fb930118d6524

こちらの記事を参考にログイン・プロジェクトの新規作成をするところまでお進みいただきたい。

# 3.完成品お披露目
まずは完成品動画をお披露目しよう。

https://twitter.com/katrina01208823/status/1538172023763251200

続いて完成フローの全体図をお見せする。
![全体フロー図.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/7eec8b0e-d2e9-a964-4f68-3a16b24cc281.jpeg)
おわかりだろうか、今回のアレクサは3つのフェーズから成り立っている。
一つ目のフェーズが「IFゾーン」
二つ目のフェーズが「スプレッドシートゾーン」
三つ目のフェーズが「Choiceゾーン」である。
それではそれぞれのフェーズの実装方法を順にレクチャーしよう。

# 4.実装編～３つのフェーズに挑む～
## 4-1. IFゾーン
IFゾーンは4つのブロックから成り立っている
ブロック名|説明
---|---
①Speakブロック|何日のセールスが知りたいですか？という質問をする
②Captureブロック|ユーザーの発話を聞き取る
③Conditionブロック|特定の条件で振り分ける　※以下本文ではIFブロックと呼ぶ
④Speakブロック|今回条件に当てはまらなかった場合、このコメントを発話させる

Speakブロックはコメントを入力するだけでしゃべってくれるので、そんなに難しくはない。そのため、今回は②と③の設定について詳しく説明していく。

### 4-1-1.Captureブロックの設定
![キャプチャの設定.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/ef4aba0f-16d7-cacc-6b4d-63843e7451b2.jpeg)
`Entire user reply`を選択し、その下には`date`と記入して`create new variable`を押す。ユーザーの返信全体を`date`という変数にするという意味である。ここではわかりやすいようにスプレッドシートの列名と同じ名称にしたが、変数の名前は好きなものにしてもらって構わない。
### 4-1-2. IFブロックの設定
スプレッドシートには6月までのセールスしか入っていない。12月1日といったようにかなり先の日付を指定して私のアレクサをいじめるやつがいるかもしれないので、エラー回避としてIFブロックを置く。
今回は`date`の値が「6月」という文字を含まない場合は④のSpeakブロックへ、それ以外の返答（6月＊日という返答）は⑤へ進ませるという設定にした。
![ifブロック.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/1f07869a-2f7c-a95b-4218-3b4fd2a6ca2b.jpeg)
`Variable`には先ほど自分で作成した`date`という変数を選択して入力、`Does not contain`を選択し`6月`と入力しよう。
また、`NO match`の設定も忘れてはいけない。
![ノーマッチ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/e9a8be78-0431-c6b6-8334-ce7ede30e4c7.jpeg)
`path`のところにぼっちをつけると、ブロックにお尻の穴が増える。
`If`の選択肢は④のSpeakブロックにつなげ、さらに④のSpeakブロックから①のSpeakブロックへ戻るように線をつないでおく。また`No Match`の選択肢は⑤のブロックに接続しよう。
ちなみに12月1日とユーザーが答えると、アレクサはこのように答える。

https://twitter.com/katrina01208823/status/1538175807323271169

## 4-2. スプレッドシートゾーン
いよいよ今回の最大難関であるスプレッドシートゾーンについて説明する。このゾーンは２つのブロックで構成される。
ブロック名|説明
---|---
⑤Google Sheetsブロック|スプレットシートとVoice Flowを接続するブロック
⑥Speakブロック|セールス名を答えるブロック
### 4-2-1. Google Sheetsブロックの設定
まずは一番最初に準備しておいたGoogleスプレッドシートとGoogle Sheetsブロックをリンクさせよう。
![スプシ１.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/c3d62472-a10b-e853-950f-b105ca731619.jpeg)
一番最初に「君はこのスプレッドシートをどのように使いたいのか」と聞かれる。今回は情報取得が目的なので、`Rretriebe Data`を選択する。
![スプシ２.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/ad1de184-5394-d2ed-4d8a-5f35ea24514c.jpeg)
続いてユーザー名を聞かれるので、ここは自分のIDを選択しよう。
![スプシ３.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/ad566a45-c817-d8d6-ea57-2e183b59e86b.jpeg)
今回使用するスプレッドシートの情報を入力していく。Spreadsheet欄には`セールスシート`と入力、`Sheet`欄には`sheet1`と入力する。
![スプシ４.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/9c5cb2fd-c396-0c47-21a5-0215b118ee55.jpeg)
ここからが重要である。With Settingsの欄の左側は`date(0)`列を選択する。右側には`{date}`を入力する。Mapping　Outputの欄の左側は`sales1(1)`列を選択、右側には新たに`fact`と入力する。
スプレッドシートの`date`列の値と変数`{date}`の値がイコールであれば、`Sales1`列の値を拾ってきてそれを`{fact}`という変数に設定するという意味である。
### 4-2-2. Speakブロックの設定
それではSpeakブロックに「この日は`{fact}`の日ですよ」と打ち込んで、きちんと値を返すか実験してみよう。

:::note warn
ユーザーが入力した情報`{date}`とスプレッドシートdate行の値が**完全に一致**していないと、アレクサは値を返すことができない。うまくいかない場合は入力の値が間違っていないか確認してみよう。
:::
## 4-3. Choiceゾーン
Choiceゾーンは9個のブロックから構成される。ブロック数は非常に多いが、Choiceブロックの使い方さえわかれば楽しくなってくるところである。
ブロック名|説明
---|---
⑦Speakブロック|キャンペーンの詳細について知りたいですか？という質問をする
⑧Choiceブロック|キャンペーン名ごとに振り分けるブロック
⑨-Aブロック|⑧への答えその１
⑨-Bブロック|⑧への答えその２
⑨-Cブロック|聞き取れなかった時用のエラー回避ブロック
⑩Speakブロック|他のキャンペーンについての質問はないか聞く
⑪Choiceブロック|はい・いいえを振り分けるブロック
⑫Speakブロック|聞き取れなかった時用のエラー回避ブロック
⑬Speakブロック|終了時のメッセージを告げるブロック
### 4-3-1 Choiceブロックの設定
![チョイス１.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/811b9684-d31b-48b7-bf4e-974e0dfd10ac.jpeg)
まずChoiceブロックの設定を開き`Add Choice`を押す。
今回はプロトタイプなので2つのキャンペーン選択肢（①若者応援キャンペーン　②サンクスデー）を設定してみることにする。（※注：本来であればおそらく常に10個以上はあるのではないか。現場で働いている販売員に敬意を表する。）
![チョイス２.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/24541948-e0d0-6c0a-c011-c74b8ee1248e.jpeg)
Path1欄に選択肢の名前を入力する。今回はwakamonoouenと入力する。好きな名前を入れていただいて問題ない。

:::note info
インフォメーション
この欄は謎にアルファベットしか入力できない。
:::

![チョイス３.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/fdf08322-8939-6357-605d-c978bcbfd686.jpeg)
続いて`Utteranders`欄にユーザーがしゃべりそうな言葉を入力してEnterボタンを押す作業を繰り返す。多ければ多いほど揺らぎがなくなるのでよい。
![チョイス４.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/46ba65f5-d080-94a4-d32b-07f30b2b7e2e.jpeg)
上記作業が終わったら再び`Add Choice`を押して、今度は「サンクスデー」についても同じ要領で入力していく。
![チョイス５.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2675304/d0740a87-33fa-db9c-a755-4d8be709f3e8.jpeg)
また、エラー回避用に選択肢のいずれでもない解答が来た場合の設定もしておく。No MatchのPath部分が上記のようになっている場合は＋部分を押してほしい。そうするとNo Matchのお尻の穴が増えるはずだ。

設定方法は以上だ。あとはそれぞれのブロックを用意し接続するだけ。好きなだけ分岐させるとよい。
# 5.辛口フィードバックに泣く(´；ω；`)
ここまでの作業が終わると次第に次のような思いが芽生えてくるはずだ。「俺のアレクサたんかわええ…。」手をかければかけるほど、時間をかければかけるほど我が子がかわいくなってしょうがないターンに入っていく。とんでもなく良いものができた。早速みんなにお披露目しよう。

出勤日は土曜日だったため人が少なく、とりあえず知り合いを片っ端から捕まえて私のアレクサを披露していく。「ねえねえ見て！わたしのアレクサすごくない？」
以下、Aさん（以前店舗で一緒だった総務部女性）Bさん（デジタル勉強中の若手男性社員。パンを焼くのが上手）Cさん（システムの偉い人）から出た共通のダメ出しを記載する。

<font color="DeepPink">**「コメント長くね・・・？」**</font>

https://twitter.com/katrina01208823/status/1538181589724983297

た、確かに長いのかもしれないけれど…。だけど販売員にとっては全部必要な情報なのだ。対象者もキャンペーン期間も支払い方法も他のセールスと重複するかどうかも全部全部必要な情報なんだもん！

<font color="BlueViolet">**Aさん**</font>「気持ちはわかるけど、店舗でこんなにじっと長時間聞くことは無いよね。」
<font color="BlueViolet">**Bさん**</font>「急いでいる人向けではないですね。知りたい情報だけ教えてくれればいいです。1回で何もかも詰め込みすぎなのでは。」
<font color="BlueViolet">**Cさん**</font>「スキップしたくなる」

ひ、ひどい…。こんなにアレクサたん一生懸命しゃべっているのに…。でもたしかにおっしゃるとおりだ。これでは情報を目で見たほうが早い。音声認識の良いところ、それは「**知りたい情報だけをすぐに取り出せること**」である。おそらく本来はこうすべきであった。

<font color="BlueViolet">**ユーザー**</font>「キャンペーン期間はいつ？」
<font color="BlueViolet">**アレクサ**</font>「〇月×日～△月◇日」です。
<font color="BlueViolet">**ユーザー**</font>「対象者は？」
<font color="BlueViolet">**アレクサ**</font>「30歳以下の人です。」
<font color="BlueViolet">**ユーザー**</font>「支払方法は？」
<font color="BlueViolet">**アレクサ**</font>「グループ会社のクレジットカードが登録されたスマホ決済のみです。」

会話形式で質問ができる、それが**アレクサの魅力**なのだ。なんということだ、私はまだ彼の本当の魅力がわかっていなかった。ごめんよ、アレクサたん。落ち込む私に「いいところもあるよ」という優しいフィードバックもいただいたので下記に記しておく。

<font color="BlueViolet">**Aさん**</font>「店舗が少人数で運営している場合、聞きたくても聞けないことがあるから安心感はあるよね。」
<font color="BlueViolet">**Cさん**</font>「最後のブロックの「励まし」からの着想で、回答をしたあとに、一言くすっと出来るようなのをランダムで話し始めたら、ほっとひとときの「癒し」が醸し出されるかもなんて思ったりもしました。アレクサの中に見え隠れする人格・・・あれ？これってもしかして？みたいな。**プログラムって、無機質なようで、結構人のクセだったり、人柄（？）みたいなものも見えてくる**ので、私が作ったんだよ！みたいなものが潜むと、機械的じゃなくなって、親しみも出てくるのかなーなんて思いました。実用的に店の人に使ってもらう！っていう意味でね。」

みんな、ありがとう。そしてCさん、随分いいこと言う。そうだ、これで終わりじゃない。私ならもっとアレクサたんの魅力を存分に引き出せるはずだ！ということで次回に続く、かもしれない。