音声でSORACOM SIMの状態を変更する

Google Home(Mini)を購入しました。
初めてのスマートスピーカーで標準の機能のみでも それなりに楽しめますが、醍醐味は独自のアプリケーションを開発できることかと思います。ということで作ってみました。

アーキテクチャ

そこで思いついたのが音声でSORACOM SIMの状態を変更するというアイディア。
SORACOMではAPIを公開しており、プログラマブルにSIMの状態(有効/無効、速度等)を変更することができますので、音声でSIMの状態を変更できるようにしてみます。

今回は上記のアーキテクチャにより、音声で下記5つの状態に変更できるようにしてみます。

  • 使用中 ー 速度 s1.fast
  • 使用中 ー 速度 s1.standard
  • 使用中 ー 速度 s1.slow
  • 使用中 ー 速度 s1.minimum
  • 休止

※ AWSと交えて開発するんだったら Amazon Echo では、という話もありますが・・・

Lambda関数の設置

まずはLambda関数を作成します。
Lambda⇒関数の作成にてPython3.6の関数を作成します。
特にAWS内へのアクセスは行わないのでIAMロールは「lambda_basic_execution」でOK。

なお、requestsモジュールはLambda標準で含まれていませんので、zipでまとめてアップロードする必要があります。以下記事を参考にしました。

import requests
import json

soracom_address='(SORACOMの登録メールアドレス)'
soracom_password='(同パスワード)'

def lambda_handler(event, context):
    # 入力値処理
    status_desired = event['status']
    speed_desired = event['speed']
    
    # 認証&APIKey/Token入手
    headers = {'Content-Type': 'application/json'}
    payload = {'email': soracom_address, 'password': soracom_password}
    response = requests.post("https://api.soracom.io/v1/auth", headers=headers,data=json.dumps(payload)).text
    data = json.loads(response)

    try:
        apikey = data['apiKey']
        token = data['token']
    except:
        return 'Invalid Username/Password'

    headers = {
        'Accept': 'application/json',
        'X-Soracom-Api-Key': apikey,
        'X-Soracom-Token': token
    }
    # 状態取得
    response = requests.get("https://api.soracom.io/v1/subscribers",headers=headers,data=json.dumps(payload)).text
    data = json.loads(response)
    imsi =  data[0]['imsi']
    status = data[0]['status']
    speed = data[0]['speedClass']
        
    # SIM状態変更
    if status != status_desired:
        url = 'https://api.soracom.io/v1/subscribers/' + imsi + '/'
        if status_desired == 'active':
            url = url + 'activate'
        else: 
            url = url + 'deactivate'
        response = requests.post(url,headers=headers).text
        data = json.loads(response)
        status = data['status']
        
    # 速度変更
    # speed_desiredが空の場合はスキップ
    if speed != speed_desired and speed_desired:
        headers = {
            'Content-Type': 'application/json',
            'Accept': 'application/json',
            'X-Soracom-Api-Key': apikey,
            'X-Soracom-Token': token
        }
        payload = {'speedClass': speed_desired }
        url = 'https://api.soracom.io/v1/subscribers/' + imsi + '/update_speed_class'
        response = requests.post(url,headers=headers,data=json.dumps(payload)).text
        data = json.loads(response)
        speed = data['speedClass']
        
    return 'status={} speed={}'.format(status,speed)

引数は有効/休止とスピードの2パラメータの仕様にしました。
テストイベントに以下のようなJSONデータを与え動作を確認することができます。

{
    "status":"active"
    "speed":"s1.slow"
}

API Gatewayの設定

続いて作成したLambda関数を公開するためにAPI Gatewayの設定を行います。

APIの作成をクリックし、API名を入力します。
続いてアクションからメソッドの作成を選択し、POSTアクションを作成、Lambda関数を呼び出せるようにします。

メソッドの定義ができたら、アクションからAPIのデプロイを選択します。
APIエンドポイントのURLが表示されるので、それをメモしておきます。

IFTTTの設定

IFTTTは様々なWebサービス同士を連携できるようにするサービスとなります(無料)
まずはアカウントを作成しログインします。

ログイン後、My Appletsタブから New Appletを選択し、新しいレシピを作成します。
まず、If this then thatのthisを選択し、本レシピの実行条件を指定します。
実行条件のサービスはGoogle Assistantを選択します。

「Say a simple phrase」を選択し、トリガーとする発話内容を入力します。

続けてthatの方(実行内容)を設定します。

webhook、Make a web requestを選択します。

Web Requestの実行内容として、API GatewayのURL及び受け渡すJSONデータを入力します。

以上のApplet(レシピ)を、合計5パターン作成し完了です。

感想

以上により、音声にてSORACOM SIMの状態を変更することができました。
流行のスマートスピーカーを利用したアプリケーションが簡単に開発でき、驚きです。

このアーキテクチャを思い立ったのは、API Gateway⇒Lambda⇒API Call で外部APIを呼び出す流れは汎用性が高いと思ったからなのですが、クラウドのサーバレス開発は慣れると簡単で面白いですね。

またアイディアが思いついたら色々作ってみたいと思いました。