После нескольких переписок по электронной почте с Натаном Лейнцем стало очевидно одно: у нас, то есть у всех нас, нет оправданий, чтобы не завершить этот сторонний проект.
Когда Натан не занят обезвреживанием и утилизацией бомб в составе армейского подразделения по обезвреживанию взрывоопасных предметов, он работает над хакерскими проектами с чётким пониманием их цели. «Я твёрдо верю, что нужно принимать своё текущее положение, стремиться к лучшему и не жалеть о прошлом», — говорит Натан.
Натан самостоятельно научился программировать во время службы в Ираке. Он быстро продвинулся от создания алгоритма оптимизации муравьиной колонии на Java до приложения для решения судоку на iOS, а затем разработал систему доставки заданий и трекер прогресса для FreeCodeCamp, в котором тогда учился.
Его последняя работа — интеграция Twilio и Spotify, позволяющая отправлять превью песен по телефонному звонку. Натан хотел больше экспериментировать с Node.js и Express.js, и так родился его «маленький счастливый проект». Вы можете прочитать его пост, изначально опубликованный на Medium, с множеством отличных GIF-анимаций и удачной отсылкой к Бобу Россу, здесь.
Недавно я наткнулся на идею проекта с хорошим темпом реализации: базовое приложение на Node.js и Express.js с использованием API Spotify и Twilio.
Если вы хотите повторить за JavaScript-версией, посмотрите это видео. Если предпочитаете построить его на Gradle и Spark, вот оригинальный пост от Twilio.
В этой статье мы создадим это приложение с использованием Elixir и Phoenix. Давайте начнём.
Вот общий поток работы приложения:
— Вы отправляете название песни на номер Twilio в SMS
— Twilio делает HTTP POST-запрос на предварительно настроенный URL с информацией, включая название песни и данные о запросившем
— Приложение ищет песню через API Spotify и извлекает URL превью
— Приложение отправляет сообщение в API Twilio, включая номер для звонка и URL для получения TwiML (язык разметки Twilio)
— Twilio получает TwiML от нашего приложения, звонит получателю и воспроизводит превью песни.
Я прошёл большую часть учебной программы на Free Code Camp. Я помогал разрабатывать и создавать основные системы Free Code Camp, поэтому хорошо разбираюсь в JavaScript. Следовать презентации было легко, и я быстро воссоздал проект. Вопрос был в том, смогу ли я сделать это на языке и фреймворке, в которых у меня не было достаточного опыта?
Если хотите узнать, как выглядит готовый продукт, отправьте название песни на номер +1 (334) 721–2652. Не беспокойтесь, мы не сохраняем ваш номер телефона или название песни. Запрашивайте ABBA сколько угодно!
ПРИМЕЧАНИЕ: Приложение размещено на Heroku, поэтому может потребоваться время, чтобы оно «проснулось» и ответило.
Я хотел бросить себе вызов и поработать с языком, который меня заинтересовал с момента первого знакомства. Elixir — это великолепный язык с синтаксисом, вдохновлённым Ruby. Он работает на BEAM (виртуальной машине Erlang) и совместим с Erlang. Да, тем самым Erlang, который прославился благодаря WhatsApp. Мне нравится идея использовать такую мощь и надёжность. Я также обожаю функциональное программирование.
Помимо Elixir, мне нравится веб-фреймворк Phoenix. С ним легко начать работу и быстро добиться результатов. Сообщения об ошибках отличные и обычно подсказывают, как их исправить. Поверьте, я видел их достаточно.
Первая задача — создать новое приложение на Phoenix. Я назвал своё Philter, поэтому ввёл:
С помощью этой команды мы создаём новое приложение Phoenix под названием Philter без слоя базы данных и системы сборки JavaScript. В этом проекте мы не будем использовать JavaScript!
Следуйте инструкциям на экране, чтобы завершить настройку приложения. Теперь мы готовы приступить к выполнению наших задач.
Twilio значительно упрощает создание аккаунта. К слову, их документация и консоль — одни из лучших. Это один из моих любимых веб-сервисов.
Зарегистрируйтесь в Twilio здесь. Если хотите следовать этому руководству, вам нужно будет пополнить счёт. $5 будет более чем достаточно для нескольких дней экспериментов. Если решите продолжить, купите номер телефона и оставьте вкладку браузера открытой.
Следующий сервис, который вам понадобится, — ngrok. Этот удобный инструмент создаёт туннель к указанному порту на вашем компьютере и предоставляет публичный URL. Сервис полностью бесплатный, но я оформил подписку за $5 в месяц, чтобы получить зарезервированный поддомен. Это мелочи, но они радуют.
Откройте новую вкладку терминала и установите ngrok через npm. Затем используйте ngrok, чтобы создать HTTP-туннель к порту 4000 на вашем компьютере. Ознакомьтесь с документацией здесь.
Первый вариант запускает сервер в интерактивной оболочке, позволяющей взаимодействовать с ним. Независимо от способа запуска, вы увидите лог, что он слушает на вашем локальном компьютере на порту 4000.
Теперь откройте новую вкладку браузера и перейдите на localhost:4000, чтобы убедиться, что всё работает. Затем вставьте URL из строки Forwarding в терминале ngrok.
Вернитесь на вкладку с открытой консолью Twilio и найдите свой номер телефона. Кликните на него, и вы увидите информацию о конфигурации. В разделе «Когда приходит сообщение» введите URL из ngrok, добавив «api/sms». Убедитесь, что HTTP-метод установлен как POST. Для справки: во время разработки этого приложения мой URL был http://tkb.ngrok.com/api/sms.
Пока консоль Twilio открыта, получите свои учётные данные ACCOUNT SID и AUTH TOKEN. Их можно найти, кликнув на имя вашего аккаунта в правом верхнем углу окна и перейдя в раздел «API Credentials». Создайте две переменные окружения: TWILIO_ACCOUNT_SID и TWILIO_AUTH_TOKEN. Я использую расширение для панели настроек на Mac под названием EnvPane. Вы также можете поискать в Google, если нужна помощь в настройке.
Имея всю эту информацию под рукой, мы почти готовы связать всё воедино. Осталось настроить последнюю деталь. Мы будем использовать ExTwilio — библиотеку, которая поможет нашему приложению на Phoenix взаимодействовать с Twilio.
Откройте config/config.exs и добавьте следующее перед последним оператором import:
Здесь мы указываем приложению считывать эти две переменные окружения, чтобы мы могли отправлять сообщения и совершать звонки через API Twilio.
В вашем любимом редакторе кода (мой — Spacemacs) откройте директорию приложения Phoenix. Давайте приступим к делу.
Откройте web/router.ex и удалите всё, что связано с scope. Замените на:
Замените все упоминания Philter на название вашего приложения.
Приведённый выше код делает несколько вещей. Мы создали маршрут, который будет обрабатывать POST-запросы к http://yourngrokurl/twiml и направлять их к функции index контроллера TwimlController. То же самое сделано для маршрута http://yourngrokurl/api/sms, который передаётся функции index контроллера SmsController. Узнайте больше о маршрутизации в Phoenix, ознакомившись с отличной документацией.
Теперь создайте два файла в директории web/controllers/: sms_controller.ex и twiml_controller.ex. Сделайте содержимое sms_controller.ex следующим:
Уважаемые эликсиристы, пожалуйста, имейте в виду, что я всё ещё учусь. С этой оговоркой перейдём к краткому объяснению.
Twilio отправляет номер телефона запрашивающего в поле From, наш номер Twilio в поле To, а текст сообщения — в поле Body. Мы извлекаем эти данные, затем запускаем задачу для поиска в API Spotify.
Запуск задачи выполняет долгую функцию в сверхлёгком процессе BEAM. Если с процессом что-то случится — он упадёт, загорится или будет поражён космическими лучами, — наше приложение продолжит принимать соединения, предотвращая панику разработчика.
Полное обсуждение задач и OTP в целом выходит за рамки этой статьи. Пожалуйста, обратитесь к ссылкам на Elixir в этом посте, если хотите узнать больше об этом удивительном инструменте.
Теперь обратитесь к репозиторию этого проекта на GitHub. Файлы, которые вам нужно скопировать: lib/philter/spotify.ex и вся директория lib/philter/spotify/. Убедитесь, что вы прошли по файлам и заменили все упоминания Philter на название вашего приложения. В файле spotify.ex на строке 55 замените «tkb» в URL на ваш ngrok URL.
Теперь сделайте содержимое twiml_controller.ex следующим:
Здесь мы просто извлекаем песню и передаём её как переменную в наш шаблон.
Откройте app.html.eex в директории web/templates/ и удалите всё, кроме:
<%= render @view_module, @view_template, assigns %>
Нам не нужна остальная разметка!
Далее создайте файл в директории web/views/ под названием twiml_view.ex. Мы могли бы добавить сюда вспомогательные функции, но они не нужны, поэтому файл останется пустым. Содержимое должно быть:
defmodule Philter.TwimlView do
use Philter.Web, :view
end
Теперь создайте новую директорию web/templates/twiml/ и внутри неё файл index.html.eex. Содержимое простое:
Это ответ, который мы отправим Twilio, когда они запросят TwiML в ответ на наше взаимодействие с API внутри задачи, о которой я едва упомянул. Поиграйте с этим и обратитесь к отличной документации по TwiML.
После перезапуска Phoenix вы сможете отправить SMS на номер Twilio и получить звонок с превью песни!