アプリを実装するほどではないし、メールでは利便性がちょっと・・・
というときにSMSでの通知が要件に上がることがあるかと思います。
ElixirでSMS送信の例としてクラウドコミュニケーションサービスTwilioと、TwilioAPIのラッパー実装として公開されているex_twilioを使って実装してみようと思います。
Liveviewを使った開発の流れについては以前誰でも試せるチュートリアル記事をかきましたので、こちらをぜひ試してみて下さい。
Twilioのトライアルアカウント登録を行う
まずはtwilio側の準備として無料クレジット付きのトライアルアカウントを取得し、SMS送信サービスのセットアップを行います。
無料トライアルは以下のURLから申し込みできます。
(アカウントの開設には2段階認証に使用する携帯電話番号が必要です。)
以下のページを参考に、SMSのテスト送信まで実施します。
以下が大まかな流れとなります。
- Twilioのトライアルアカウント登録と無料のクレジットを取得する。
- 最初のTwilio電話番号(発信者としての電話番号)を取得する(Japanの番号ではSMSが対応していないので注意)
- Programmable Messagingのサービスを作成する。
- コンソールのTry SMSメニューからテスト送信を実施する。
SMS送信に必要なID
twilio経由でSMS送信を行うには管理コンソール
Account > Keys & Credentials > Live credentialsから
Account SIDとAuth tokenの二つの認証情報を確認しておきます。
ex_twilioを導入する
phoenixプロジェクトを作成する
mix phx.new sample_ex_twilio
依存関係定義にex_twilioを追加してインストールします
defp deps do
[
~中略~
{:ex_twilio, "~> 0.9.1"},
~中略~
]
end
cd sample_ex_twilio
mix deps.get
mix ecto.create
下記のパラメータに前項で確認したAccount SIDとAuth tokenを設定します。
TWILIO_ACCOUNT_SID
TWILIO_AUTH_TOKEN
~中略~
config :ex_twilio, account_sid: "TWILIO_ACCOUNT_SID",
auth_token: "TWILIO_AUTH_TOKEN"
~中略~
本稿では単純化のためにConfigに直接認証情報を記載していますが、製品実装やサンプルとしてGitHubなどに公開する際は、認証情報は環境変数などコード外で設定するようにしてください
ex_twilioのread.meでも同様の内容が説明されています。
SMS送信アプリのサンプル実装
Liveviewのモデルを生成する
以下のコマンドでSMSの内容と、送信ステータスを表すLiveViewのモデル実装を生成します。
mix phx.gen.live Messages SmsMessage sms_messages target_number:string calling_number:string message_body:string send_status:string
生成されたエンドポイントをrouterに定義します。
コマンド実行結果で提案される内容からメッセージの一覧をルート"/"に変更して登録しています。
live "/", SmsMessageLive.Index, :index
live "/sms_messages/new", SmsMessageLive.Index, :new
live "/sms_messages/:id/edit", SmsMessageLive.Index, :edit
live "/sms_messages/:id", SmsMessageLive.Show, :show
live "/sms_messages/:id/show/edit", SmsMessageLive.Show, :edit
ex_twilioを使ったSMS送信機能の実装
phx.gen.liveコマンドで既にsms_messageモデルの照会登録変更削除については実装されていますので、それらとtwilio_exのSMS送信関数 Message.create/2 を使ってSMS送信とステータスの制御を実装します。
def send_sms_message(%SmsMessage{} = sms_message) do
# 送信ステータスを送信中に更新
{:ok, sms_message} = update_sms_message(sms_message, %{:send_status => "sending"})
# SMSメッセージを送信
with {:ok, result} <-
Message.create(
to: sms_message.target_number,
from: sms_message.calling_number,
body: sms_message.message_body
) do
# 正常終了した場合、ステータスを成功に更新
{:ok, ms_message} = update_sms_message(sms_message, %{:send_status => "success"})
else
# エラーが発生した場合、ステータスをエラーに更新
{:error, result} ->
{:ok, ms_message} = update_sms_message(sms_message, %{:send_status => "error"})
{:error, result}
end
end
一覧画面に送信ボタンのイベントハンドラを追加します。
~中略~
@impl true
def handle_event("send_message", %{"id" => id}, socket) do
{:ok, _} = id
|> Messages.get_sms_message!()
|> Messages.send_sms_message()
{:noreply, assign(socket, :sms_messages, list_sms_messages())}
end
~中略~
一覧画面のテンプレートに上記ハンドラを呼ぶ送信ボタンを追加します。
ついでに不要なshowとDeleteリンクを削除します。
~中略~
<td>
<span><%= link "Send Message", to: "#", phx_click: "send_message", phx_value_id: sms_message.id, data: [confirm: "Are you sure?"], class: "button"%></span>
<span><%= live_patch "Edit", to: Routes.sms_message_index_path(@socket, :edit, sms_message), class: "button"%></span>
<!--
<span><%= live_redirect "Show", to: Routes.sms_message_show_path(@socket, :show, sms_message) %></span>
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: sms_message.id, data: [confirm: "Are you sure?"] %></span>
-->
</td>
~中略~
SMS送信確認
Phoenixを起動します。
mix phx.server
一覧画面にアクセスしNew Sms messageリンクをクリックします。
送信先の電話番号、送信元の電話番号(事前に取得したSMSに対応したTwilio電話番号)、メッセージ本文、初期ステータス(適当にno_sendとしています。)を入力しsaveボタンをクリックします。
トライアルアカウントでは送信先は事前に認証済の電話番号に限定されている為、あて先はアカウント登録時にしていした電話番号を使用してください。
一覧にメッセージデータが登録されました。
SEND MESSAGEボタンをクリックすると実装した送信機能が実行されます。
ステータスが更新されsuccessになりました。
送信先に指定した電話番号でSMSを受け取ることができました
※Snet from your Twilio trial account -の文字はトライアルアカウントでの送信時に自動で設定されます。
まとめ
twilioとex_twilioを使って簡単な送信画面を実装することができました。
LiveViewを使うとベースとなるMVCのテンプレが簡単に生成できるので、実施したい部分を直ぐに動くアプリとして試作に持っていけるのがうれしいですね。