キャッシュレス時代の「子どものおこづかい」ってどうしたらいいんだろう

# 我が家のおこづかい事情
ウチには5歳になる娘がいまして、お手伝いなどしてくれたら「お小遣い」をあげる、というのをやっています。
しかし、**キャッシュレス時代**、財布の中に小銭がない時の方が多く、「あげるね〜」と約束をしたっきり忘れてた。。。というのがちょくちょく発生しています。

**これでは、パパの信用がなくなってしまう！！！！！**

# やりたいこと
要件をまとめると以下のようになりました！

:::note info
財布の中に、小銭があろうがなかろうが、「お小遣いをあげる約束」をメモできるアプリが欲しい
:::
:::note info
教育のため「お小遣いをあげてる感」の演出は欲しい
:::
:::note info
娘（5歳・スマホなし）が自分で、どのくらいお小遣いが貯まったのか？を確認できるようにしたい
:::

# 以上を踏まえて、構成図
![スクリーンショット 2022-08-11 0.43.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/2d0191ba-d5ca-b363-e12c-57733304c1a7.png)

:::note info
財布の中に、小銭があろうがなかろうが、「お小遣いをあげる約束」をメモできるアプリが欲しい
:::
LINE Botでメモを取るのが一番簡単で、ママへの展開も簡単かなと思いました。お小遣いを入力できる人は、LINEのユーザーIDで制限をかけておけばひとまず良さそう


:::note info
教育のため「お小遣いをあげてる感」の演出は欲しい
:::
悩みました。LINEBotのリッチメニューと、リプライメッセージで「チャリーン」といった効果音を出すといった工夫してみたいと思います

:::note info
娘（5歳・スマホなし）が自分で、どのくらいお小遣いが貯まったのか？を確認できるようにしたい
:::
スマホがないので、根本的にアプローチを考えないといけません。
さいわいにも我が家には**Amazon Alexa**があり、娘も音声入力で音楽を流すのは日常的にやっているので、Amazon Alexaでお小遣いの合計を確認できるようにしたいと思います。

# 実装

## LINE Bot編
### オウム返しLINEBotを準備
こちらの記事を参考に、パパッとオウム返しLINEBotを準備しました
[5分でつくるLINEBot](https://qiita.com/cog1t0/items/0d121ee6d48a8c1634fc)

### リッチメニュー設定
![スクリーンショット 2022-08-11 1.20.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/cb82b034-e4b3-cbb2-40b3-900a1adb1c21.png)
「いらすとや」さんからお金の画像をお借りし、リッチメニューに設定しました。
お金の画像をタップすると「chage:10」という形式で、テキストが入力されます

### Google App Scriptの実装
基本的な部分はオウム返しLINEBotで実装してあるので、差分だけ紹介です。

```js:charge:10といった入力をスプレッドシートに反映させ、messageを作って返す関数
function insertCharge(txt){
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet1');
  const charge = txt.replace('charge:','');
  const values = sheet.getDataRange().getValues();
  const numRow = values.length
  // timestamp
  var today = new Date
  sheet.getRange(numRow + 1, 1).setValue(Utilities.formatDate(today,'JST','yyyy/MM/dd'));
  // charge
  sheet.getRange(numRow + 1, 2).setValue(charge);

  return {'type': 'text', 'text': charge + "円を追加したよ！"};
}
```

```js:お金がチャリーンっていう効果音のオーディオメッセージを返却する関数
function moneyAudio() {
  return {
				"type": "audio",
				"originalContentUrl": "https://cog1t0.github.io/public_img/money.mp3",
				"duration": 1000 // 音声ファイルの長さ（ミリ秒）
			}
}
```
[効果音ラボ](https://soundeffect-lab.info/sound/various/)さんからお借りしました。
[GithubPagesで画像のホスティング](https://qiita.com/cog1t0/items/0cc21346f1ebba5ce7f0)の記事を参考に効果音のデータを公開しアクセスしてます

doPost関数の中で、messagesを作成する際に、ユーザーメッセージにcharge:が含まれているという条件を設定してます
```js
if ( user_message.match(/charge:/)) {
  messages.push( insertCharge(user_message) )
  messages.push( moneyAudio() )
}
```

### API編
スプレッドシートの「sheet1」に入力された内容を合計して表示するためだけのシートを作成します
![スクリーンショット 2022-08-11 1.33.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/7b90b72f-66e1-cead-bd38-fe1af4d1da15.png)

[SSSAPI](https://sssapi.app/)というサービスでこのシートをAPIとして公開します。
スプレッドシートのURLを貼り付けるだけで、APIにしてくれるすごいサービスです！

直感的に使えますが、以下の設定が必要です
![スクリーンショット 2022-08-11 1.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/d0769636-e143-23cd-aa7c-f35a6c98bf2d.png)

:::note warn
1行目の場合は配列にしない、を選択しているとAPIを使うときにラクです
:::
:::note warn
LINEBotから入力があっても、自動更新がOFFだと反映されません。自動更新をONにしておくと、数分待つと最新の状態になります
:::

## Amazon Alexa編

### アカウントの作成
[alexaの開発者ページ](https://developer.amazon.com/ja-JP/alexa)にアクセスしアカウント登録を行いましょう

### チュートリアル動画を見て、なんとなく理解しましょう
独特な言葉が多く、直感的に使いにくいです。
[チュートリアル動画](https://developer.amazon.com/ja-JP/alexa/alexa-skills-kit/get-deeper/tutorials-code-samples/build-an-engaging-alexa-skill)を観とかないと混乱するのである程度観てから始めるの推奨です。
![スクリーンショット 2022-08-11 21.10.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/77f7b5ca-8050-cab4-f4d2-f95279034e50.png)
＊Alexaコンソールに初めて触った私のイメージ

### コンソールで開発
#### Alexaスキル開発を選択
![スクリーンショット 2022-08-11 23.22.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/9c3737ce-6416-c74b-e246-7b99310aa9e6.png)

#### コンソールを選択
![スクリーンショット 2022-08-11 23.22.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/044a398e-da12-c887-ff08-d82b802d59b2.png)

#### スキルの作成を選択
![スクリーンショット 2022-08-11 23.23.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/237ce420-24e5-584f-3a6b-6870dc871e86.png)

#### 新しいスキルを作成
スキル名：お好きなものを
スキルに追加するモデル：カスタム
バックエンドリソースをホスティングする方法：Alexa-hosted(Node.js）
![スクリーンショット 2022-08-11 23.25.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/3c2f219c-ce9f-e7ba-a967-7a2d144d8ea5.png)
![スクリーンショット 2022-08-11 23.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/a440fc38-17a8-c7a1-0b78-284039db97bd.png)

[Alexa-hostedスキル](https://developer.amazon.com/ja-JP/docs/alexa/hosted-skills/build-a-skill-end-to-end-using-an-alexa-hosted-skill.html)の説明によると「AWS無料利用枠を超えた場合、追加のリソースのプロビジョニングには独自のAWSアカウントが必要です。」とのことなので、無料利用枠を超えると勝手に止まります。

#### スキルに追加するテンプレート：スクラッチで作成
![スクリーンショット 2022-08-11 23.31.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/b771eea0-3856-959d-5606-8457028e5bb6.png)

テンプレートで続けるを選択し、しばらく待ちます
![スクリーンショット 2022-08-11 23.31.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/b607c026-791f-29f2-ed97-6fa8a57e297d.png)

スキルビルダーが立ち上がります
![スクリーンショット 2022-08-11 23.37.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/ff463e7b-f71e-04c7-278b-1b44b410b027.png)

#### コードエディタを編集
コードエディタを編集していきます
![スクリーンショット 2022-08-11 23.38.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/0ebe84b0-577d-fe3e-5b59-9dcf106ae16f.png)

今回実装するのは、スキルを呼び出したら、スプレッドシートの残高を教えてくれるだけの単純なスキルです
![スクリーンショット 2022-08-11 0.43.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/2d0191ba-d5ca-b363-e12c-57733304c1a7.png)

編集するファイルは二つだけです。
・package.json
・index.js

```json:package.json
{
  "name": "hello-world",
  "version": "1.2.0",
  "description": "alexa utility for quickly building skills",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Amazon Alexa",
  "license": "Apache License",
  "dependencies": {
    "ask-sdk-core": "^2.7.0",
    "ask-sdk-model": "^1.19.0",
    "aws-sdk": "^2.326.0",
    "axios": "^0.27.2" 
  }
}
```
変更は1行だけで、axiosを新規に追加したのみです。適切なバージョンは都度変わるので、調べてください。

```js:index.js
/* *
 * This sample demonstrates handling intents from an Alexa skill using the Alexa Skills Kit SDK (v2).
 * Please visit https://alexa.design/cookbook for additional examples on implementing slots, dialog management,
 * session persistence, api calls, and more.
 * */
const Alexa = require('ask-sdk-core');
const axios = require("axios"); // <= 新規追加

//　スプレッドシートのAPIにアクセスして、お小遣いの残高を取得する関数
const getBalanceData = async () => {
    try {
        const response = await axios.get(
          "https://api.sssapi.app/xxxxxxxxxxxxxxxx" // <= SSSAPIで作ったAPIのURL
        );
        return response.data;
    } catch (error) {
        console.error(error)
    }
}

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    async handle(handlerInput) {
        const data = await getBalanceData(); // <= 残高を取得
        const speakOutput = `えみちゃんのおこづかいは${data.balance}円だよ！`; // <= アレクサにしゃべってもらう内容を組み立て

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .getResponse();
    }
};
/// 以降いろんな処理が書いてありますが、使いません
```
デフォルトでいろいろ記述が書いてありますが、今回使うのは「スキルが呼び出されたときに最初に反応する関数（LaunchRequestHandler）だけなので、それ以外は省略します。

#### 編集が終わったらデプロイ
![スクリーンショット 2022-08-11 23.53.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/56cbfb5c-dd9f-cbfe-3592-4cf61eb8829b.png)
ちょっと時間かかります

#### テストしてみる
ヘッダーメニューの「テスト」を選択し、テストが無効になっているので「開発中」を選択しテストできるようにします。スキル名を呼び出したら残高を読み上げることをテストします。
![スクリーンショット 2022-08-11 23.54.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/ea884510-519f-a501-e665-3c1cfaed80d3.png)

#### 公開の設定を行う
ヘッダーメニューの「テスト」を選択し、内容を~~適当に~~埋めていきます。
![スクリーンショット 2022-08-11 23.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/970cfc45-5b8c-9627-44fd-435c27aebe5f.png)
![スクリーンショット 2022-08-11 23.57.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/f097fdc6-c6f3-0e1c-bdf0-3d26725d52d9.png)

#### プライバシーとコンプライアンスの設定
![スクリーンショット 2022-08-11 23.59.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/097ae866-ca50-7fd6-ef1b-9aa5b231ae36.png)

:::note warn
自分の5歳の娘が使うので、「このスキルは13歳未満のお子様を対象としていますか？」に「はい」と答えましたが、それが原因で審査落とされたので、審査通すために「いいえ」を選択しました。（Amazonから認定された人じゃないと作れないらしい）
:::

#### 公開範囲の設定
![スクリーンショット 2022-08-12 0.03.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/4a096b42-1bfb-9e75-2105-098570d0761e.png)

:::note warn
正直、公開したくなかったのですが、公開しないとスキルが使えなかったので、公開にしました。（公開せずに自端末でスキル使えるようにする方法があったら教えてください🙇‍♂️）
:::

#### 申請を行う
ヘッダーメニューの「認定」から申請を行います。
だいたい24時間くらい待ったら、承認が降りました。

# 使ってみた
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">アレクサスキル、検証放置してたら出来るようになってた🤗 <a href="https://t.co/1QtixvzAeW">pic.twitter.com/1QtixvzAeW</a></p>&mdash; 桑原 陸也 / Kuwabara Rikuya (@r19_tech) <a href="https://twitter.com/r19_tech/status/1557373330054717440?ref_src=twsrc%5Etfw">August 10, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## 娘の反応
**オーディオメッセージが面白かった**らしく、何度も「チャリーン！」の音を再生して楽しんでいました！
　![S__4104241.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27192/6323fb37-1479-5ff3-e712-179c91e077a7.jpeg)

アレクサのスキルを、娘が自分で開くのもできたので、これから貯まっていくのが楽しみな様子でした。

## 妻の反応
・**現状、特に問題意識はなかったけど、LINE Botでできるのは面白そう**
・ジジババに使ってもらうのは、際限なくチャリーンしそうだからやめとこう
・**引き出しが現状できないので、LINEBotからできるようぜひして欲しい**
・お小遣いが20円、30円の場合は、10円2回押すとかで代用できそう
・「チャリーン」は自動再生にしてほしい（ **LINE Botの仕様** なんです。。。と伝えて納得してもらった）
・このお小遣いは何をしてもらったものなのか？の**メモ機能**がほしい

=> 妻には課題感は特にないってのは笑いましたが、家族で使うってなったら使ってみる〜といっていたので、特に使うハードルは高くなさそう！

# 今後の課題
・「お小遣いをあげる約束」は無事にメモできるようになりましたが、残高を現金化した際の収支合わせは、スプレッドシートのデータを直で操作する必要があるので、このあたりもLINEBotで簡単にできるようにしてみたい。
・メモ機能、、、たしかにあると便利そう！
・ジジババに使ってもらうのは渋ってましたが、そもそも、その場にいないと「ジジババがおこづかいあげた感」が全然ないので、見せ方と運用を工夫して、試せるようにしてみたい。

# まとめ
・アレクサスキルは初めて作ってみましたが、**意外と簡単にスキル実装できる**というのがわかってよかったです
・**スマートスピーカーを使えると、家庭の課題解決は一気にいろんな可能性が増えた感じがする**ので、もっと複雑なことができるスキルにも挑戦してみたい！