SORACOM Air のイベントハンドラーと AWS Lambda を連携してみる

  • 20
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

SORACOM リリース記念リレーブログ の 10/8 分です!

SORACOM Beam の tcp to https ネタを用意してたら、先を越されてしまった(業界用語で言うと"メソられた")ため、急遽別のネタです。

イベントハンドラーとは

SORACOM Air にはイベントハンドラーという機能があります。

イベントハンドラーはSIMの通信容量をトリガーとして

  • メール通知
  • 速度クラスの変更
  • AWS Lambda ファンクションの実行

を行うものです。

上2つは「監視」機能でも使用されているのですが、3つめの Lambda ファンクションの実行を使うと色々な事が出来そうなので、試してみました。

AWS Lambda ファンクションをご存知ない方に説明しますと、JavaScript や Java のコードをイベント駆動で起動するための AWS のサービスになります。

※詳細情報は イベントハンドラー機能詳細 を参照

例:使用量が一定を超えたら Slack にお知らせする

通信量一定の容量以上に達した場合に、Slackのチャンネルに晒す^H^H通知を行います。

パラメーター

イベントハンドラーから起動される Lambda ファンクションには、下記のように event オブジェクトが渡されます。

{
  "imsi":"対象のimsi",
  "parameter1":"上記のparameter1",
  "parameter2":"上記のparameter2",
  "parameter3":"上記のparameter3"
}

parameter1 には Daily/Monthly/Totalの種別、parameter2 には閾値の通信容量、parameter3には slackの web hook path を渡す事にします。

slackの設定

まず https://{team名}.slack.com/services/new/incoming-webhook にアクセスして、 Slack の incoming webhook を作成します。
その際に発行される Webhook URL が
https://hooks.slack.com/services/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
のような形式になるので、parameter3には /services 以降の
/services/T04CJJPJP/B0C37JEH0/GsKRwBf5dWZcCUwca7Bk0Iw9
を渡します。

AWS 側の設定

Lambda Functionの作成

LambdaのFunctionを作成し、HTTPのリクエストを行うプログラムを作成します。

  • Function新規作成画面を開きます
  • Configure function に下記の例のように入力
    • Name: 任意(lambda2slackなど)
    • Description: 任意
    • Runtime: Node.js
  • Lambda function codeには、下記のコードを貼り付けして下さい
// Generated by CoffeeScript 1.10.0
var https, slack;

https = require('https');

slack = {
  channel: "#general",
  username: "SORACOM",
  emoji: ":signal_strength:"
};

exports.handler = function(event, context) {
  var options, payload, req;
  options = {
    method: 'POST',
    hostname: 'hooks.slack.com',
    port: 443,
    path: event.parameter3
  };
  payload = {
    channel: slack.channel,
    username: slack.username,
    icon_emoji: slack.emoji,
    text: event.parameter1 + " traffic of your SIM (IMSI: " + event.imsi + ") exceeded " + event.parameter2 + "."
  };
  req = https.request(options, function(res) {
    res.setEncoding('utf8');
    return res.on('data', function(d) {
      console.log(d);
      context.succeed(d);
    });
  });
  req.on('error', function(e) {
    context.fail(e.message);
  });
  req.write(JSON.stringify(payload));
  req.end();
};

return;

  • Role は ドロップダウンから Create New Role の下の *Basic Exection Role を選んで下さい (新しいタブが開きますが、ポップアップウィンドウがブロックされるかもしれませんので、許可して下さい)
  • 特に変更をせず、許可 を押すと Role に lambda_basic_exection が選択されます
  • Next を押して次の画面で Create Function を選びますと、Functionの作成が終わります
  • Test ボタンを押すと Function のテストが行えます。例として以下のようなパラメータを指定して下さい
{
  "imsi": "12345",
  "parameter1": "Daily",
  "parameter2": "1GB",
  "parameter3": "/services/.../..."
}
  • Execution result: succeeded となり、okと表示されたら、Lambdaの設定は完了です。
    SlackにDaily traffic of your SIM (IMSI: 12345) exceeded 1GB.のようなメッセージがポストされているか確認して下さい。

<テスト実行イメージ>
lambda2slack

SORACOM側の設定

設定内容をJSONで記述し、soracom event_handler create に渡します(パラメータは適宜読み替えてください)。

$ cat req.json
{
    "targetOperatorId": "OP0000000000",
    "name": "1日1GBでslackに通知",
    "description": "1日1GB利用時",
    "ruleConfig": {
        "type": "DailyTrafficRule",
        "properties": {
            "inactiveTimeoutDateConst": "BEGINNING_OF_NEXT_DAY",
            "limitTotalTrafficMegaByte": 1000
        }
    },
    "actionConfigList": [
        {
          "properties": {
            "accessKey": "AWSアクセスキー",
            "secretAccessKey": "AWSシークレットキー",
            "endpoint": "https://lambda.ap-northeast-1.amazonaws.com",
            "functionName": "lambda2slack",
            "executionDateTimeConst": "IMMEDIATELY",
            "parameter1": "Daily",
            "parameter2": "1GB",
            "parameter3": "/services/T04CJJPJP/B0C37JEH0/GsKRwBf5dWZcCUwca7Bk0Iw9"
          },
          "type": "InvokeAWSLambdaAction"
        }
    ]
}
$ soracom event_handler create --req "$(cat req.json)"
{
  "result": "success"
}

しばらく待つと、slackにポストされました(実験のため、閾値を1MBにしてあります)。
slack

おわりに

Lambda から SORACOM API client for Node.js を使う事で、例えば一定以上通信した際に休止して翌月になったら解約、といった処理を入れる事で、ちょっとしたプリペイドSIMの仕組みを作れそうですね。