Статьи

Создание службы котировок акций на основе SMS с Twilio

С появлением облачных служб телефонии, таких как Twilio , написание приложения, которое работает с SMS-сообщениями и телефонными звонками, стало еще проще. Помимо возможности отправлять SMS-сообщения через их простой API, Twilio также позволяет обрабатывать входящие сообщения, что открывает целый мир возможных приложений.

В этой статье я покажу вам, как вы можете использовать Twilio для создания простой службы котировок акций на основе SMS, которая обрабатывает как входящие SMS-сообщения, так и отправку ответов. Приложение позволит пользователю запрашивать цену акций для данной компании с помощью SMS и получать ее через несколько секунд тем же способом.

Прежде чем ты начнешь

Во-первых, если вы еще этого не сделали, вам необходимо создать учетную запись в Twilio.

Как только вы зарегистрируетесь, вам нужно будет реквизировать (нанять, по сути) номер телефона, на который люди будут отправлять сообщения, чтобы воспользоваться услугой. Перейдите по адресу twilio.com/user/account/phone-numbers/incoming и нажмите «Купить номер», чтобы выбрать доступный номер. Вы можете выбрать один конкретный для вашего региона, но вы можете выбрать любой из доступных номеров — единственной переменной является стоимость.

Затем перейдите на выбранный вами номер, установите флажок SMS и введите URL, который вы собираетесь использовать для своего приложения (он должен быть где-то общедоступным), а затем /callback . Например:

  http://example.com/callback 

Запишите SID вашей учетной записи и соответствующий токен авторизации (они отображаются в верхней части страницы вашей учетной записи) — они понадобятся вам позже.

Приложение

Пользователь запросит цену акций с помощью SMS, и приложение обработает входящее сообщение, извлечет соответствующие данные, использует внешний веб-сервис для сбора запрошенной информации и отправит ответ пользователю во втором SMS.

Процесс будет следующим:

  • пользователь отправляет команду через SMS на указанный номер
  • SMS обрабатывается Twilio, который «пингует» настроенную конечную точку (наше приложение)
  • наше приложение анализирует команду и извлекает балансовую единицу
  • приложение проверяет внешний веб-сервис, передавая балансовую единицу в качестве параметра
  • этот веб-сервис возвращает цену
  • приложение отправляет Twilio API ответ и номер, на который отправляется SMS
  • пользователь получает SMS с запрашиваемой ценой акции

Этот процесс иллюстрируется следующей диаграммой:

Twilio накопления 01

Звучит сложно? Не волнуйтесь, это действительно не так! Давайте начнем.

Строим фундамент

Самый простой способ начать работу — использовать composer. Создайте файл composer.json в корне вашего проекта со следующим:

 { "require": { "slim/slim": "2.3.0", "slim/extras": "dev-develop", "twilio/sdk": "dev-master" } } 

Я использую Slim Framework; тем не менее, большая часть кода будет многократно использоваться в любой фреймворке, который вы предпочитаете (если вы действительно хотите использовать фреймворк вообще).

Теперь запустите:

  php composer.phar установить 

Вы обнаружите, что платформа Slim теперь находится в недавно созданной папке vendor , вместе с официальным Twilio SDK и некоторыми дополнительными полезностями (позже мы собираемся использовать некоторые функции ведения журналов в Slim Extras).

Создайте includes папку, и в этом файл с именем config.php :

 return array( 'twilio' => array( 'account_sid' => 'YOUR-ACCOUNT-SID', 'auth_token' => 'YOUR-AUTH-TOKEN', 'phone_number' => 'YOUR-PHONE-NUMBER', ), ); 

Конечно, вам нужно заменить эти значения на те, которые вы получили от Twilio ранее.

Создайте public каталог в корне проекта и укажите свою конфигурацию Apache для обслуживания файлов из этой папки.

Теперь создайте файл .htaccess в общей папке:

  RewriteEngine On
 RewriteCond% {REQUEST_FILENAME}! -F
 RewriteRule ^ index.php [QSA, L] 

Это перенаправит все запросы на несуществующие файлы в файл центрального контроллера index.php .

Теперь для файла index.php :

 <?php require '../vendor/autoload.php'; $config = require '../includes/config.php'; $app = new SlimSlim(); $app->get('/', function () use ($app) { print 'Installation successful'; }); $app->run(); 

Попробуйте перейти к приложению — вы должны увидеть сообщение «Установка прошла успешно».

Поскольку мы создаем приложение, которое не будет отображать контент для браузера, будет очень полезно реализовать некоторую регистрацию. Slim по умолчанию регистрирует в STDERR, но библиотека Slim Extras, упоминаемая в файле composer.json содержит средство записи журналов на основе файлов.

Измените создание нового объекта Slim на:

 $app = new SlimSlim(array( 'log.writer' => new SlimExtrasLogDateTimeFileWriter(array( 'path' => '../logs', 'name_format' => 'Ym-d', 'message_format' => '%label% - %date% - %message%' )) )); 

Затем создайте папку logs в корне проекта и сделайте ее доступной для записи веб-сервером.

Теперь вы можете получить доступ к регистратору следующим образом:

 $log = $app->getLog(); 

И регистрируйте сообщения как это:

 $log->info('This is a message'); 

Обработка входящих SMS

Мы указали наш обратный вызов, который проверяется при получении входящего SMS. В частности, под «pinged» я подразумеваю, что запрос POST выполняется на указанный URL с двумя ключевыми частями информации:

  • номер отправителя
  • содержание смс

Номер отправителя и сообщение отправляются как переменные POST — From и Body соответственно.

Итак, давайте создадим обратный вызов — я пока оставлю это простым и запишу информацию:

 $app->post('/callback', function () use ($app) { $log = $app->getLog(); $sender = $app->request()->post('From'); $message = $app->request()->post('Body'); $log->info(sprintf('Message received from %s: %s', $sender, $message)); }); 

Попробуйте отправить SMS на настроенный номер, а затем проверьте журналы — запись журнала должна появиться в течение нескольких минут. Если вы ничего не видите, Twilio ведет учет активности, поэтому вы сможете отлаживать процесс оттуда.

Формат сообщения, которое будет принимать приложение: COMMAND ARGUMENT . Он примет только одну команду — PRICE — например, «дайте мне цену за акцию …» и один аргумент — балансовую единицу.

Вот пример:

  ЦЕНА AAPL 

Эта команда означает «Пришлите мне текущую цену акций Apple, Inc.».

Включая команду, мы оставляем открытой возможность добавления дополнительных функций позже. Например, возможно, вы захотите предложить услугу SUBSCRIBE на регулярные обновления.

Для разбора входящего сообщения нам просто нужно извлечь команду и аргумент — мы можем использовать простое регулярное выражение для этого:

 $pattern = '/^([AZ]+) ([AZ]+)/'; preg_match($pattern, $subject, $matches); print_r($matches); 

Если вы попробуете это с примером ранее, вы должны увидеть это:

  массив
 (
     [0] => ЦЕНА AAPL
     [1] => ЦЕНА
     [2] => AAPL
 ) 

Соответствующие части находятся в позициях 1 и 2.

 $command = $matches[1]; $argument = $matches[2]; 

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

 switch ($command) { case 'PRICE': // perform action break; default: print 'Invalid command!'; } 

Получение цены акций

Я собираюсь использовать веб-сервис, чтобы получить последнюю цену акций для данной компании. Бесплатные стоковые услуги очень редки — и даже тогда часто бывают задержки, но здесь есть одна.

Создайте каталог с именем src в корне проекта, и в этом каталоге с именем SitePoint , и в этом файле с именем StockService.php :

 <?php namespace SitePoint; class StockService { } 

Чтобы автозагрузчик мог определить местоположение этого класса, добавьте объявление автозагрузчика в ваш composer.json :

 "autoload": { "psr-0": {"SitePoint\": "src/"} } 

Теперь запустите:

  обновление php composer.phar 

Чтобы реализовать метод получения котировки акций для данной компании, создайте открытый метод в классе StockService например:

 public static function GetQuote($symbol) { $client = new SoapClient('http://www.webservicex.net/stockquote.asmx?WSDL'); $params = array( 'symbol' => $symbol, ); $response = $client->__soapCall('GetQuote', array($params)); $quotes = simplexml_load_string($response->GetQuoteResult); return $quotes->Stock[0]; } 

Все, что я сделал, это создал экземпляр SoapClient и передал ему URL-адрес в файл WSDL службы, а затем GetQuote метод GetQuote , обработал XML и возвратил первый (и единственный) элемент Stock .

Вы можете добавить новый маршрут для его проверки:

 $app->get('/quote', function () use ($app) { $symbol = $app->request()->get('symbol'); $quote = SitePointStockService::GetQuote($symbol); var_dump($quote); }); 

Если вы вызываете http: // localhost / quote? Symbol = AAPL , вы должны увидеть что-то вроде этого:

  object (SimpleXMLElement) # 39 (16) {
   [ "Символ"] =>
   Строка (4) "AAPL"
   [ "Last"] =>
   Строка (6) "431,31"
   [ "Дата"] =>
   Строка (9) "18.07.2013"
   [ "Время"] =>
   Строка (6) "1:03 вечера"
   [ "Изменить"] =>
   строка (5) "+1,00"
   [ "Открыть"] =>
   Строка (6) "433,55"
   [ "Высокий"] =>
   Строка (6) "434,87"
   [ "Low"] =>
   Строка (6) "430.61"
   [ "Объем"] =>
   Строка (7) "4878034"
   [ "Рыночная капитализация"] =>
   строка (6) "404.8B"
   [ "PreviousClose"] =>
   Строка (6) "430,31"
   [ "PercentageChange"] =>
   строка (6) "+ 0,23%"
   [ "AnnRange"] =>
   строка (15) "385.10 - 705.07"
   [ "Зарабатывает"] =>
   Строка (6) "41,896"
   [ "ЧП"] =>
   строка (5) "10,27"
   [ "Name"] =>
   Строка (10) "Apple Inc."
 } 

В следующем разделе мы закончим, собрав эту информацию в SMS-сообщении и отправив ее на мобильный телефон запрашивающего пользователя.

Отвечая через SMS

Первое, что нужно сделать здесь, это создать сообщение, на которое приложение будет отвечать:

 // construct the response $response = sprintf('%s: %s (%s) [Hi: %s Lo: %s]', $quote->Name, $quote->Last, $quote->Change, $quote->High, $quote->Low ); 

Основываясь на ранее полученной информации, вы получите следующее сообщение:

  Apple Inc .: 431,31 (+1,000) [Привет: 434,87 Lo: 430,61] 

Чтобы отправить его в виде SMS, Twilio экземпляр класса Twilio и вызовите метод, который соответствует требуемой конечной точке REST:

 // instantiate the Twilio client $twilio = new Services_Twilio( $config['twilio']['account_sid'], $config['twilio']['auth_token'] ); // send the SMS $sms = $twilio->account->sms_messages->create( $config['twilio']['phone_number'], // the number to send from $sender, $response ); 

… вот и все!

Еще предстоит проделать определенную работу, например, выполнить правильную обработку ошибок, а синтаксический анализ команды немного не простит. Не стесняйтесь скачать код с GitHub и поиграть!

Резюме

В этой статье я продемонстрировал, как вы можете использовать Twilio как для получения, так и для отправки SMS-сообщений, и как вы можете с нуля создать простое приложение для доставки части запрашиваемой информации непосредственно на чей-либо мобильный телефон. На практике наш пример не очень полезен; цены на акции колеблются гораздо быстрее, чем вы можете отправить SMS — но, возможно, вы можете подумать о других целях?

Вы также можете поиграть с добавлением новых команд. Возможно, вместо сервиса с мгновенным ответом вы подписываетесь на регулярные обновления? Или даже установите некоторые пороговые значения, например «отправьте мне SMS, если цена акции упадет ниже x»). Не стесняйтесь высказать любые другие идеи в комментариях ниже!

Изображение через Fotolia