naoki86star

インターネットの片隅でなにかしら書いてみる

SMS notification on Amazon SNS (...by clojure)

前置き

 Amazon SNSを使ったSMS通知を試してみました。よく2段階認証で携帯のほうにSMSが飛んでくるアレをクラウドサービスを使って飛ばせるのか興味を持ってすぐに試せそうなものを検索してこれをやってみようと思ったからです。

  • Amazon SNSというのは他のサービスと同様、AWSアカウントに紐ついて実行できるサービスのひとつであり、送信者から受信者に送信方法を介して通知を送る抽象サービス、と理解
  • このうちの送信方法の一つにSMSがある
  • システム的に、SMSでメッセージを送るとき、プロモーションもしくはトランザクションの2通りがある
  • SMSではコンソール・すなわちweb画面から送信を試してみることができる
  • 料金体系をチェックしておく、お試し使いでトランザクションを数メッセージ飛ばす程度なら全然驚くような料金にはならない、はず
準備と実装

 awsのアカウントを持っていてec2のインスタンスを起動したことがある、ところからスタート。あわせてaws cliのAPIの設定も以前に経験あり。
 まず、SMSプリファレンスというものを設定する。AWSコンソールから設定できる、もしくはAPIでも設定できると読めるが、コンソールすなわちwebの画面から設定した。設定したのはデフォルトのメッセージタイプ=トランザクションとアカウントの使用制限=1、送信者IDはオプションとあって適当なアルファベット単語を入れました。開発者ガイドみてみると、送信者IDというのは今記載時点で、JPはnot supportみたいです。

受信者が携帯電話番号の場合のユーザー通知に Amazon SNS を使用する (SMS 送信) - Amazon Simple Notification Service
SMS メッセージプリファレンスの設定 - Amazon Simple Notification Service
サポートされているリージョンおよび国 - Amazon Simple Notification Service

 project.cljのdependenciesの部分、多分今回はSNSだけ使いたいので本来はもっとjarの数を絞れる書き方・手法がありそうには思うのですが、調べてません。最初のlein replでやや時間かかり(jar名のテキストが流れ)おそらくすべてのaws sdkおよび必要な依存jarを引っ張ってきてたと思われます。leiningenのdefault project.cljに一行足すだけで、すべてのaws sdkのクラスがrepl上でちょっとお試し使いできるのは、驚くべく素敵なことと感じてます。

 試行したコードはjavaのexampleそのままをclojure文法でAPIを呼び出せるようにしただけです。実装と呼ぶほどでないですね。aws sdkはこれからも試すことあると思います。githubおいてきます。

 送信操作はこんな感じ(phone-numberは伏せ)。実行5秒程度?で着信。自分の携帯に引数渡したままメッセージと、senderとしては "NOTICE"と表示されました。

ubuntu@ip-172-31-23-43:~/clj-aws-sdk$ lein repl
nREPL server started on port 39237 on host 127.0.0.1 - nrepl://127.0.0.1:39237
REPL-y 0.4.4, nREPL 0.6.0
Clojure 1.10.1
OpenJDK 64-Bit Server VM 11.0.7+10-LTS
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

clj-aws-sdk.core=> (clj-aws-sdk.example.sns/send-message "+8190********" "Hello world")
#object[com.amazonaws.services.sns.model.PublishResult 0x13dd0f69 {MessageId: 78560646-e71b-58f4-9db3-51599c867779}]
nil
clj-aws-sdk.core=>

その他として、

  • コンソールのSNSのページでは成功率というのが参照できました
  • メッセージ飛ばしたあと、すぐインスタンスは消去してしまいました。翌々日に料金見積もりコンソールみるとSNS/EC2/CloudWatch/DataTransferという4項目でてます。CloudWatchは無料送信枠数以下で0/DataTransferも0、合計$0.39(税別)とのこと。
  • (自分の電話番号のくせに、)3回くらい、国番号・局番部分を間違えて実行してしまいました。もし飛んだとしたら日本以外にいってしまってるはずですが、本当にspamぽく受け取った端末があればごめんなさいします。
考えておきたいこと

 Amazon SNSのこのSMSに関しては、利用方法自体はお手軽(実装の手数が少なそう)なことがわかりました。
 スマホのメッセンジャー以外の手段で、携帯の電話番号がわかっていれば相手に届くとても便利機能ですが、使いどころと落とし穴はいろいろピックアップしておきたいです。通知先の情報はもうそのまま世の中的に機微な情報なのでその扱いのほうに時間をかけることになりそうです。*4
 料金制限をかけられるというのは、ひとつ安心感あるシステム仕様だと思います。今時点個人用になにか使おうと思っているだけなのですけど、万一送信が無限ループで暴走するとかやりかねません。そうならないよう設計するのはもう書くことでもないかもですけど、仮にいろいろ肉付けしていくとそのたびに見直さないとなにを埋め込んでしまうやら。送信エラーの監視も毎回コンソールをみるでは追っつかないでしょう。それからこれは今の自分には縁がないですが他人に送るような使い方不特定多数に送る場合には、ひとつとして、受信拒否を希望する相手に送らないoptoutという仕組みを理解しておく必要もありそうです。

*1:ec2でubuntu20.04もう使えた!!

*2:aws sdkだからそうしたというより、最近の自分はjavaは大抵の場合にはこれを使っている

*3:Maven Repository: com.amazonaws » aws-java-sdkこっちみたら全然バージョン上だけどsdkすべてのどこそこに対する更新だろうなぁと思う

*4:自分の情報を使うお試しでもうっかり晒してしまうとかやりかねない