image

В этом кратком руководстве от Фила Леггеттера мы рассмотрим, как отправлять и получать SMS в приложении Laravel. Мы реализуем эту возможность, используя Nexmo — платформу облачных коммуникаций, которая предлагает API-интерфейсы для инициализации телефонных номеров, отправки и приема SMS (что мы и будем использовать), а так же для совершения звонков.


Предварительные требования


Нам понадобится учетная запись Nexmo, установленный Nexmo CLI (интерфейс командной строки), а так же ваше предустановленное приложение Laravel. Кроме того, понадобится локальное туннеллирование, что бы служба Nexmo могла сделать HTTP запрос на локальный веб-сервер. Мы рекомендуем ngrok.


Введение


Первым делом мы создадим наше приложение Laravel SMS:
composer create-project --prefer-dist laravel/laravel laravel-sms
cd laravel-sms

Далее, добавим пакет Nexmo Laravel в composer.json:
"require": {
    ...,
    "nexmo/laravel": "dev-master as 1.0",
    "nexmo/client": "dev-master as 1.0"
},

Примечание: когда эти пакеты выйдут из бета-версии, вам нужно всего лишь включить пакет nexmo/laravel, а nexmo/client будет добавлен автоматически в качестве зависимости.

Добавим сервис-провайдер Nexmo в ваш конфигурационный файл app.php:
'providers' => [
    ...,
    Nexmo\Laravel\NexmoServiceProvider::class
]

Примечание: вы так же можете добавить его в aliases, если хотите использовать фасад.

Установим пакеты и скопируем конфигурационный файл Nexmo:
› composer update
php artisan vendor:publish

Наконец, добавьте Nexmo API Key и API Secret в /config/nexmo.php, обновите значения API_KEY и API_SECRET, основываясь на значениях, содержащихся в настройках API в Nexmo Dashboard.
'api_key' => 'API_KEY',
'api_secret' => 'API_SECRET',

Примечание: при желании вы можете объявить значения в .env и env(...).


Отправка SMS


Примечание: для простоты мы добавим весь функционал в app/Http/routes.php.

Добавьте следующий маршрут в app/Http/routes.php:
Route::get('/sms/send/{to}', function(\Nexmo\Client $nexmo, $to){
    $message = $nexmo->message()->send([
        'to' => $to,
        'from' => '@leggetter',
        'text' => 'Sending SMS from Laravel. Woohoo!'
    ]);
    Log::info('sent message: ' . $message['message-id']);
});

Стоит отметить, что в приведенном коде from содержит значение @leggetter. Это сработает в Великобритании, но не в других странах.

image


Для тех из вас, кому нужно использовать реальный номер, давайте рассмотрим использование существующего номера, а так же его покупку.


Листинг, поиск и аренда номеров


Одной из предпосылок для этого урока был Nexmo CLI. Мы можем использовать его для множества действий, в том числе для работы с телефонными номерами (виртуальными номерами, если быть точным), которые связаны с нашей учетной записью. Если вы еще не сделали этого, вы должны установить и настроить CLI, где API_KEY и API_SECRET должны быть заменены учетными данными API, которые использовались ранее:
› npm install -g nexmo-cli
nexmo setup API_KEY API_SECRET

Теперь мы можем просмотреть доступные номера, которые мы уже арендовали, искать номера, доступные для аренды, а так же арендовать или отменить аренду определенного номера. Давайте начнем с того, что посмотрим на список номеров, которые уже доступны на нашей учетной записи:
› nexmo number:list
14155550123

В приведенном выше примере у меня есть номер. Если у вас нет номера, вы можете произвести поиск по номерам для аренды. Все, что вам необходимо для этого знать — это два символа кода страны в формате ISO 3166-1 alpha-2. На самом деле, это проще, чем кажется. Например, для Великобритании это GB, а для Соединенных Штатов — US (прим. пер.: а для России — RU). Давайте найдем номер для аренды в США:
› nexmo number:search US
14155550111
14155550222
14155550333

Если у вас нет номера, вы должны его купить, после чего вы сможете отправлять и получать SMS в тех странах, которые требуют реального исходящего номера.
› nexmo number:buy 14155550111 --confirm
Number purchased: 14155550111


Отправка SMS, наконец-то!


Теперь вам необходимо обновить код, что бы использовать только что купленный номер. Для этого нужно изменить значение from на env('NEXMO_NUMBER'), как на примере ниже:
Route::get('/sms/send/{to}', function(\Nexmo\Client $nexmo, $to){
    $message = $nexmo->message()->send([
        'to' => $to,
        'from' => env('NEXMO_NUMBER'),
        'text' => 'Sending SMS from Laravel. Woohoo!'
    ]);
    Log::info('sent message: ' . $message['message-id']);
});

Затем запустите сервер:
› php artisan serve
Laravel development server started on http://localhost:8000/

И перейдите к http://localhost:8000/sms/send/YOUR_NUMBER, где YOUR_NUMBER должен быть заменен на реальный номер, включая код страны, в формате E.164, т.е. в том же формате, который был показан во всех приведенных выше примерах.

В файле storage/logs/laravel.log вы увидите запись лога, относящуюся к сообщению, которое только что было отправлено, включая уникальный идентификатор сообщения в конце записи, например:
[2016-08-02 13:45:01] local.INFO: sent message: 03000000068F5D97


Приём входящего SMS


Для того, что бы наше приложение могло получать входящие SMS, нам необходимо выполнить несколько действий:
  1. Убедитесь, что приложение видно для Nexmo через локальный туннель
  2. Создайте маршрут для п��лучения SMS
  3. Отключите CSRF для маршрута, получающего SMS
  4. Сообщите Nexmo, по какому маршруту вызывать вебхук при получении сообщения


Начнем с того, что дадим платформе Nexmo доступ к нашему приложению через локальный туннель. Если предположить, что вы используете ngrok и ваш веб-сервер Laravel прослушивает порт 8000, вы можете сделать это следующим образом:
› ngrok http 8000
ngrok by @inconshreveable                                                (Ctrl+C to quit)

Tunnel Status                 online
Version                       2.1.3
Region                        United States (us)
Web Interface                 http://127.0.0.1:4041
Forwarding                    http://814882e9.ngrok.io -> localhost:8000
Forwarding                    https://814882e9.ngrok.io -> localhost:8000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

Выше вы можете увидеть, что поддомен на ngrok был успешно создан и теперь любые запросы к нему будут туннелироваться на наш локальный хост localhost:8000.

Теперь необходимо создать маршрут для получения SMS в файле routes.php:
Route::post('/sms/receive', function(\Nexmo\Client $nexmo){
});


По умолчанию Laravel не пропустит POST запросы на этот маршрут без CSRF токена. Так как запрос на этот маршрут будет сделан Nexmo, у которого нет токена, нам необходимо отключить CSRF для этого маршрута. Добавьте в App/Http/Middleware/VerifyCsrfToken.php следующее:
protected $except = [
    '/sms/receive'
];

И, наконец, давайте сообщим Nexmo, по какому маршруту сделать вызов вебхука, когда будет получено SMS. Мы можем сделать это с помощью Nexmo CLI. При выполнении следующей команды вы должны использовать номер телефона, который вы арендовали, а так же ваш поддомен ngrok:
› nexmo link:sms 14155550111 https://814882e9.ngrok.io/sms/receive
Number updated

При выполнении этой команды, служба Nexmo попытается вызвать ваш маршрут /sms/receive, и вы должны увидеть запрос в терминале ngrok:
HTTP Requests
-------------

POST /sms/receive              200 OK


Клиентская библиотека Nexmo PHP предоставляет возможность с легкостью захватывать параметры HTTP, которые были отправлены от Nexmo приложению Laravel и создавать объект входящего сообщения InboundMessage, с которым мы можем работать. Обновите код маршрута /sms/receive следующим образом:
Route::post('/sms/receive', function(\Nexmo\Client $nexmo){
    $message = \Nexmo\Message\InboundMessage::createFromGlobals();
    Log::info('got text: ' . $message->getBody());
});

После этого отправьте SMS на арендованный номер и проверьте storage/logs/laravel.log, в логе должно находиться отправленное вами сообщение.
[2016-08-02 13:45:01] local.INFO: sent message: 03000000068F5D97  
[2016-08-02 14:20:50] local.INFO: sent message: 0300000006917797  
[2016-08-02 14:21:17] local.INFO: got text: Sending one back.


image



Автоматический ответ на входящее SMS


И, наконец, давайте создадим автоответчик для входящего сообщения. Клиент Nexmo PHP обеспечивает хороший способ сделать это с помощью функции InboundMessage->createReply:
Route::post('/sms/receive', function(\Nexmo\Client $nexmo){
    $message = \Nexmo\Message\InboundMessage::createFromGlobals();
    Log::info('got text: ' . $message->getBody());
    $reply =$nexmo->message()->send($message->createReply('Laravel Auto-Reply FTW!'));
    Log::info('sent reply: ' . $reply['message-id']);
});

Отправьте сообщение на арендованный номер и вы получите автоматический ответ. Это ведь почти магия!

image



Заключение


В этом уроке мы рассмотрели все, что вам нужно знать, чтобы реализовать отправку и получение SMS, и даже автоматический ответ на SMS, в приложении Laravel с использованием платформы облачных коммуникаций Nexmo.

Вы можете найти код этого урока на github.com/nexmo-community/laravel-sms.