f3: sms 自動転送を考えてみる


.
/ 2019/08/02 訂正 /
/ sms-receive.php 内の mb_send_mail 処理が抜けていたため /


昨今の sns / sms サービスは、ともに 
端末依存、sim 依存のモノが多い

sms は sim というよりも 電話回線に紐付くもので
しょうがないといえばしょうがないけど
複数端末運用をしていると、B 端末で確認できない
みたいなことになって不便を感じる

前回記事 [f2: sms - imessage 連携テスト]
https://qiita.com/cxfgp/items/5af80bbdef161a1a519c
の imessage (icloud 転送) のように

確かにローカル端末側での自動転送という方法は
以下のようにいくつかあるけれど
双方の端末を常時オンラインにして、
アプリ常駐したり、
ID の紐付けをしておかないといけなかったり
片方が常時オンラインではない運用 になると、
思うようにいかない

1. iFTTT(Android SMS) や Auto SMS などのアプリ常駐連携
2. imessage の icloud 転送
3. RCS ( +メッセージ 等 ) -> まだ未知数

もっとこう 端末依存せずにメール自動転送のように
気軽に転送してくれるモノはないのかと思い、

sms -> cloud sms -> メール 自動転送 と
メール送信 -> cloud sms -> sms 受信 を
試してみました


---
### **[ まとめ ]**

1. sms -> cloud sms -> メール 自動転送 は可能
2. メール送信 -> cloud sms -> sms 受信 も可能
3. 環境問題(料金、国際)がクリアにならないと運用はきびしい
4. 現時点では、企業向けまたは、SMS 認証向けの印象


---
### **[ お品書き ]**

1. 買い出し
2. キッチン
3. 仕込1 (SMS -> Nexmo -> MAIL)
4. 仕込2 (MAIL -> Nexmo -> SMS)
5. 食感
6. デザート


---
### **[ 1. 買い出し ]**


候補は以下2つあったけれど

Twilio
https://www.twilio.com/

Nexmo
https://www.nexmo.com/


Twilio は、WEB API が用意されているものの
Programmable SMS という GUI での SMS テスト送信が
うまくいかなかったので
(環境や設定の問題と思います、多分)
Nexmo にしました


Twillio の場合は、
@kidach1 様の

TwilioとRailsで、1通1円のSMS認証を実装してみる
https://qiita.com/kidach1/items/cd63063fa98aaa5030bd

が、わかりやすいです

Nexmo については
Qiita Organization ユーザーでもある WACUL 様の

SMS送信サービスのNexmoを利用する
http://blog.wacul.co.jp/blog/2014/10/07/nexmo/

に、色々概要(+ Node.js)があるのでわかりやすいです


---
### **[ 2. キッチン ]**

さくらのレンタルサーバ
スタンダード

php 7.2

Nexmo SMS API


---
### **[ 3. 仕込 1 (SMS -> Nexmo -> MAIL) ]**


・SMS を受信したら メールに 自動転送する


ひとまず番号を取得しました
アメリカの番号です (010-1-XX-XXXX-XXXX)

Nexmo 管理コンソール上で
フックする php の URL を記載します

Webhook URL for Inbound Message
https://xxxx.xxxx/xx/sms-receive.php


ものすごく手っ取り早くするなら
以下でできました


```php:sms-receive.php

#!/usr/local/bin/php

<?php

mb_language("Japanese");
mb_internal_encoding("UTF-8");

$frm20 = $_GET;
$mobile20 = $frm20['msisdn'];

if(isset($mobile20))
{ 

$now20 = date('Y-m-d H:i:s');
$too20 = $frm20['to'];
$message20 = $frm20['text'];
$timestamp20 = $frm20['message-timestamp'];

$name2 = "FROM-CLOUD-SMS: ".$now20;

$text1 = $message20;
$text5 = htmlspecialchars_decode($text1, ENT_NOQUOTES);
$text6 = "\n".$timestamp20."\n\n"."FROM: ".$mobile20."\n\n"."TO: ".$too20."\n\n".$text5."\n\n";

$to = 'RECEIVE@MAILADDRESS';

$subject = $name2;
$message = $text6;
$headers = 'From: FROM@MAILADDRESS' . "\r\n";

	 if (mb_send_mail($to, $subject, $message, $headers)) {
		//   echo "send mail is OK";
	 } else {
		//   echo "send mail is NG";
	 } 

 }

?>

```

※ message-timestamp はアメリカ時間なので、
   9時間プラスで想定する必要あり

アメリカの番号 (010-1-XX-XXXX-XXXX) に
SMS を送信すれば、指定のメールアドレス
$to = 'RECEIVE@MAILADDRESS';
に 内容が受信されます

( この場合は SMS -> Nexmo への国際 SMS 送信料がかかります )
( 後述する送信料に注意！ )


---
### **[ 4. 仕込 2 (MAIL -> Nexmo -> SMS) ]**

・メール送信による 相手への SMS 送信



MAIL -> Nexmo の部分は、

.mailfilter で受信メールを 
php に受け渡してパイプ処理します


Nexmo -> SMS の部分は、

Nexmo 管理コンソール上で提供される
・url
・api_key
・api_secret
を用いて

・from (自分の番号)
・to (送信先番号)
・text (本文)

を curl すれば 送信できます


```php

$url = 'https://rest.nexmo.com/sms/json?' . http_build_query([

'api_key' => 'XXXXXXXX',
'api_secret' => 'XXXXXXXXXXXXXXXX',
'to' => '81XXXXXXXXXX',
'from' => '1XXXXXXXXXXXXXX',
'text' => 'HONBUN'

]);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);


```

php パイプするメールアドレスに
メール送信すれば、
指定した to (送信先番号) に
SMS が届きます

(この場合は Nexmo -> SMS の送信料がかかります)


---
### **[ 5. 食感 ]**


cloud を使用した メール送受信による 
SMS 送受信は上記の通りできました

が、

その他に問題がいくつかあり
実現困難な壁が待っています



(1) SMS 受信時の SMS 送信者名


Nexmo から SMS が送信され、
端末の SMS が受信するのですが、
送信者名が、NXSMS となっています

詳細を見てみると、
+81 6XXXX
となっていました

これはよく言われることですが、
海外の事業者から国内に入ってきたときに
ネットワーク事業者を経由するため、
番号が維持されずに端末に送信される為です

今回は docomo 経由なのですが、
softbank でも au でも発生する可能性はあります

Nexmo にも問い合わせましたが、
日本のネットワーク事業者(いわゆる3大キャリア)
に依存する為、私どもではどうすることもできません
という回答でした

要するに、SMS を送信したい相手に
自分の Nexmo の SMS 番号 を伝えても
その番号では受信がされない為、受信した相手も困惑します

もっとも、自分の Nexmo の SMS 番号も、
国際 SMS 番号になるので、伝える時点で
相手に不信がられます



(2) 送信料


Nexmo から 国内(日本)への送信料金は
2018/10/07 送信時点で 1通 0.07 ユーロ (約9円) でした
(EUR 0.07 = JPY 9.18 -> 2018/10/07 円相場)

もちろん、国内での通常の SMS 送信よりはちょっと高いので
そこも問題ではありますが、それよりも、逆ルート
相手が Nexmo 宛てに SMS を送信するいわゆる国際 SMS の
送信料金が以下で、運用のきびしさを目の当たりにします


docomo 国際 SMS 通信料
https://www.nttdocomo.co.jp/service/world/worldcall/outline_m/sms/
半角160文字、全角70文字まで 送信料：50円/1通

softbank 国際 SMS 通信料
https://www.softbank.jp/mobile/service/global/outgoing/mail/services/
1～70文字(全角の場合) 送信料：100円/1通

au 国際 SMS 通信料
https://www.au.com/mobile/service/global/sms/
半角160文字、全角70文字まで 送信料：100円/1通


・自分 メール -> Nexmo -> SMS -> 相手
 = 9円/1通

・相手 -> 国際 SMS -> Nexmo -> メール -> 自分
 = 50円 or 100円/1通


今度 SMS の 番号を変えたので、以後はここに送信してね
と、相手に 国際電話番号的な SMS 番号を伝えたとして
相手は 1通送信するごとに、月額の携帯代として
50円または100円が加算され請求されます

(パケット通信料は別として、
送信料という名目がない無料の) 
メール か imessage か、
SNS メッセージにして、と言われますよね


(3) 国際 SMS の送信処理時間

iphone の場合ですが、
通常の SMS 送信時間は、数秒といった印象ですが、
Nexmo というか、国際 SMS を送信するときは、
に、なると思いますが、送信をタップしてから
処理が完了するまで、30秒 - 40秒くらいの時間が
かかりました、これも、

あなたの教えてくれた番号に SMS 送信すると
すぐ終わらないのはなぜ？と言われますね

(環境依存であれば必ずしもではないのかもしれません)



(4) 国内送達率


たとえば 企業が顧客に対して SMS 送信をする場合に、
各顧客の端末に SMS が送信(到達) = 受信
できるかどうかの割合のことです

今回テストした環境では、送信者名の問題はあるにせよ、
Nexmo の場合は、送達時間も含めて
送達率は 100% 良好でした

経路の途中に何かがあると、送達率は低くなります


---
### **[ 6. デザート ]**


本当は、@kidach1 様のように、
あわよくば WEBアプリで SMS 認証も
と思っていましたが、なんといっても、料金の問題と
送信者名表示の問題はいかんともしがたく、
環境問題のハードルが高いので、
メール と cloud sms を用いた sms 自動転送運用は、
現段階では 見送りになってます

RCS が今後どういう展開を見せるのか
imessage がどう変わっていくのか
といったところも踏まえて
何か別の方法を模索する必要がありそうです

---

.