SORACOM LTE-M Buttion スマート設定機能の変数置換機能の検証

# この記事は

2020年11月のSORACOM Technology Campで発表された、[「SORACOM LTE-M Button」デバイスのスマート設定機能](https://blog.soracom.com/ja-jp/2020/11/17/smart-configure-for-soracom-lte-m/)を検証した結果です。

# 新機能

管理コンソールの「ガジェット管理」に「LTE-M Button for Enterprise」が増えており、こちらから「新規デバイス設定」を押すと簡単に「ボタンを押すとメールを送る」機能が設定できてしまいます。

実際にメールを送るのは、SORACOM側で準備されたAWS Lambda関数が行います。動作としては以下のようになります。

1. ガジェット管理から設定すると、SIMグループを新規作成または設定変更される
2. メールに関する設定はSIMグループのタグとして保存されている
3. グループの設定でSORACOM FunkがONになり、独自のLambda関数のARNが設定される
4. Lambda呼び出しの権限設定に「空欄」というものが増えている。SORACOMで準備した関数を、SORACOMの権限で呼び出すから追加の権限設定が不要ということの模様
5. 呼び出されたLambdaでは、起動後にSIMグループのタグ情報をAPI経由で取得し、サブジェクトと本文の変数展開を行ってメール送信を実施する

# 変数展開

ここで、初期データの本文を見てみます。

```
ボタン{{subscriber.tags.name}}が{{event.clickTypeName}}クリックされました。

・電池残量:{{event.batteryLevelPercent}}%
・緯度,経度:{{context.location.lat}},{{context.location.lon}}(簡易位置即位機能で表示)
```

この`{{ .. }}`の部分がデータで置き換わります。例えば`{{event.clickTypeName}}`は「SINGLE/DOUBLE/LONG」のいずれかになります。

さて、この表記、何か見覚えありませんか？SORACOM Funkを使ってボタンからAWS Lambdaを呼び出したことがある方は、ボタンのクリックデータや簡易位置即位機能で取得されたcontextデータとしてこういう形で渡っていることをご存じかと思います。

ということで、これを見た私は以下のように推測しました。

- `{{ .. }}`の部分は、SORACOMで準備したLambda関数内で同じ変数の値に置き換えられる
- ただし、いくつか特殊なものがある
  - `event.batteryLevelPercent`はないのでこれは関数内で`event.batteryLevel`を元にパーセント表記に置き換えられている
  - `subscriber.tags.name`はSIM(SORACOMではSIMのことをsubscriberと表現します)の「nameという名前のtagの値」に置き換わるので、メタデータサービスを利用している
  - メタデータの置き換えはLambda側で行われる(Orbitが自動で設定されてそこで処理するわけではない。Orbitは追加料金も発生するから勝手に設定するのは微妙だからと思われる)

そして、さらに以下の事ができるのではないかと予測しました。

- `subscribers.tags`ではname以外のタグも取得できるのではないか？
- メール本文やサブジェクト、送信先などをSIMグループのタグの値から取得している以上、タグの置き換えは`group.tags`で取れないか？
- eventで渡る部分(LambdaにPOSTされる値)に追加することでさらに新しい置き換えが可能ではないか？

予測したら、試すしかありません。早速やってみました。

#タグの情報

まず、SIMの設定で適当なタグの値を設定します。ここでは`tagtest`という名前に`タグのテスト`という値を設定します。

同じくSIMグループの設定で適当なタグの値を設定します。ここでは`grouptagtest`という名前に`グループタグのテスト`という値を設定します。

次に、本文に`{{subscribers.tags.tagtest}}`と`{{group.tags.grouptagtest}}`を入れて、このように変更します。

```
SIMのタグは{{subscriber.tags.tagtest}}だよ！
グループのタグは{{group.tags.grouptagtest}}だよ！
```

ボタンを押してみると、こんなメールが届きました。

```
SIMのタグはタグのテストだよ！
グループのタグはグループタグのテストだよ！
```

予想通りですね！

#データを増やしてみる

次にデータを増やしてみましょう。データをいじるのであればOrbitの出番です。

Orbitのプログラム全体は先日公開しました[「SORACOM Orbitでボタンのデータを触ってみた(AssemblyScript編)」](https://qiita.com/kkimura/items/1af1c33d7d3862e1a454)を参照してください。

以下の行を追加し、データを増やします。

```typescript:Typescript
encoder.setString("datatest","Hello,I'm Orbit!")
```

そして、本文に``{{event.datatest}}``を追加して以下のようにします。

```
SIMのタグは{{subscriber.tags.tagtest}}だよ！
グループのタグは{{group.tags.grouptagtest}}だよ！
追加したデータは{{event.datatest}}だよ！
```

ボタンを押すとこんな感じのメールが届きました。

```
SIMのタグはタグのテストだよ！
グループのタグはグループタグのテストだよ！
追加したデータはHello,I'm Orbit!だよ！
```

こちらもうまくいきましたね！

# 置換機能のまとめ

本文ならびにサブジェクトには変数展開を埋め込むことができ、そのルールは以下の通りです。

- `{{subscribers.tags.$TAGNAME}}`と書くと、ボタンのSIMのタグ「`$TAGNAME`」に設定された値に置き換わる
- `{{group.tags.$TAGNAME}}``と書くと、SIMグループのタグ「`$TAGNAME`」に設定された値に置き換わる
- `{{event.$VARIABLENAME}}``と書くと、LambdaにPOSTされるデータ中の変数`$VARIABLENAME`の値に置き換わる
  - ボタンだと`clickType`,`clickTypeName`,`batteryLevel`
  - 特殊な値として`{{event.batteryLevelPercent}}`があり、バッテリーレベルを％表示してくれる
- `{{content.$VARIABLENAME}}`と書くことで簡易位置情報などの情報に変換される

・・・と、ここまで書いたところで同じことが書いてある公式ページがあることに気がつきました。**この検証の意味 is 何** orz

[SORACOM LTE-M Button for Enterprise 機能の説明](https://dev.soracom.io/jp/enterprise_button/how-it-works/)

(メール設定のページしか見て無くてこちらに気づかず、情報無いもんだと思ってた・・・と言い訳しておこう)

# ボタン以外でいける？

こちらの機能、「ボタン向けのスマート設定機能」として提供されていますが、ここまで見て分かるように

- 公式に提供されたLambdaを設定し、そのLambdaがメールを送る
- SIMグループのタグ`mailSubject`の値をサブジェクト、タグ`mailBody`の値を本文としたメールがタグ`mailAddress`に指定されたアドレスに送られる
- SIMならびにSIMグループのタグの値、LambdaにPOSTした値を置換して本文やサブジェクトに埋め込める(置換はLambdaで行われる)

ということになりますので、ボタンじゃないデバイスでも利用可能なのか・・・？ということも予測されるのですが、試したところうまく動きませんでした。
タグの値やデータの形も揃えてみたのですが駄目だったので、恐らくLambda側でSIMの情報を取得したりでなんらかの制限がかけられているものと思われます。

ただ、今後この枠組みを使った別の公式Funk(と呼んで良いのか？)は出てくるのではないかと大変楽しみにしています。

# まとめ

- ボタンのスマート設定機能は超便利
- ボタン以外のSIMでは使えないようになってる模様
- ちゃんと公式情報は読みましょう