Прослушивание песен Spotify по звонку с помощью Elixir, Phoenix, Twilio и API Spotify

Автор: | 05.08.2026

После нескольких переписок по электронной почте с Натаном Лейнцем стало очевидно одно: у нас, то есть у всех нас, нет оправданий, чтобы не завершить этот сторонний проект.

Когда Натан не занят обезвреживанием и утилизацией бомб в составе армейского подразделения по обезвреживанию взрывоопасных предметов, он работает над хакерскими проектами с чётким пониманием их цели. «Я твёрдо верю, что нужно принимать своё текущее положение, стремиться к лучшему и не жалеть о прошлом», — говорит Натан.

Натан самостоятельно научился программировать во время службы в Ираке. Он быстро продвинулся от создания алгоритма оптимизации муравьиной колонии на 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 и получить звонок с превью песни!