Laravel5.3之後有提供Notification方法,裡面提到有整合nexmo簡訊的一些教學,但後來我研究實作後,Notification需要搭配Model/Database方法後才能傳送簡訊,這部分有點不太方便。所以本篇只教學如何使用nexmo發送簡訊的套件,並搭配Redis簡易實作簡訊OTP方法。
Prepare
- Laravel
- Redis
- Apply Nexmo account
install nexmo/client
1
|
composer require nexmo/client
|
config/services.php
1
2
3
4
5
6
7
|
'nexmo' => [
'key' => env('NEXMO_KEY'),
'secret' => env('NEXMO_SECRET'),
'sms_from' => env('NEXMO_FROM'),
'ttl' => 600, //otp存活時間
'retry_after' => 120, //下次傳送等待時間(避免濫發)
],
|
.env
1
2
3
|
NEXMO_KEY=[your nexmo key]
NEXMO_SECRET=[your nexmo secret]
NEXMO_FROM=[your nexmo register/buy phone]
|
you can get nexmo keys when logging
NEXMO_FROM
: 我是使用註冊時所登入的號碼,預設會是Test numbers
注意Test Number是有使用上限
Create route, controller
routes/api.php
1
|
Route::get('/otp/{phone}', 'SMSController@demo');
|
app/Http/Controllers/SMSController.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class SMSController extends Controller
{
/**
* Send demo OTP
*
* @param string $phone
*
* @return json user object
*/
public function demo(string $phone)
{
$otp = mt_rand(1000000, 9999999);
$key = "NEXMO:SMS:" . $phone;
$key_retry = $key . ':RETRY';
$ttl_retry = Redis::ttl($key_retry);
if ($ttl_retry > 0) {
throw new BadRequestHttpException(
"Please wait $ttl_retry sec and retry",
null,
0,
['Retry-After' => $ttl_retry]
);
}
Redis::setex($key_retry, $retry_ttl, 1);
Redis::setex($key, $key_ttl, $value);
//create client with api key and secret
$client = new \Nexmo\Client(
new \Nexmo\Client\Credentials\Basic(config('services.nexmo.key'), config('services.nexmo.secret'))
);
//send message using simple api params
$message = $client->message()->send(
[
'to' => $phone,
'from' => config('services.nexmo.sms_from'),
'text' => sprintf('Your OTP code is %s, please activite this in %d mins', $otp, (config('services.nexmo.ttl') / 60))
]
);
return response()->json(
[
"message" => "Successfully send demo sms"
], 200
);
}
}
|
Run Test
http://localhost:8000/api/otp/demo/886912345678
Conclusion & Feature
- nexmo傳入電話號碼為全部數字,沒有
+ 號
- OTP產生7碼數字
- Redis有TTL特性,可以設定每個key的存活時間,這邊設定2種ttl。1是otp ttl;2是retry otp ttl 。 20~32行代碼中提到
- 34~46行待碼為傳簡訊方法,可以將它方封裝成
job queue
方式在背景執行,當大量request時減少api回傳時間
- 此Redis TTL應用方法也可以用在傳Email上