Я подписан на ProgMetal subreddit, потому что нет ничего, что мне нравится больше, чем слышать, как виртуозно играет соло на 8-струнной гитаре, в то время как разные барабанщики, басисты, клавишники, виолончелисты и валторнисты чередуют такты 19/16 и 7/4. .

Большинство постов на /r/ProgMetal — это ссылки на треки на YouTube, которыми постер хочет поделиться с сообществом. Как и во всем Reddit, эти сообщения затем голосуются за или против других пользователей, в результате чего выбираются сообщения, которые можно упорядочить по «популярности».

Я вижу, что интересные треки из этого сабвуфера появляются часто, но часто в те моменты, когда нецелесообразно открывать YouTube; и к тому времени, когда я нахожусь в состоянии слушать, этот интересный трек уже давно забыт. Я понял, что мне бы очень хотелось, чтобы треки из этого саба были собраны в еженедельный плейлист, который я мог бы слушать на досуге. Итак, это то, что я намеревался сделать.

План состоял в том, чтобы создать приложение, которое вызывало бы API Reddit для получения первых n сообщений из заданного субреддита, отфильтровывало бы все, что не является просто рекомендацией трека, а затем использовало бы API Spotify для размещения эти песни в плейлисте.

Узел — Между погребённым и мной

Я решил написать это маленькое приложение с помощью Node, потому что считаю JavaScript хорошим языком для быстрого объединения вещей, а Node — хорошей средой выполнения для легкого запуска и быстрого выполнения итераций. Также я планировал позже развернуть это как Lambda, и я знал, что Node поддерживается.

mkdir reddlist
cd reddlist
npm init

Красный (дит) — King Crimson

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

Я использовал npm-пакет reddit API-оболочки под названием snoowrap вместо того, чтобы самостоятельно отправлять http-запросы (хотя, оглядываясь назад, это не было огромным преимуществом).

npm install snoowrap

Я создал класс для инкапсуляции кода, связанного с Reddit.

Этот класс просто обертывает snoowrap и предоставляет метод для получения лучших сообщений из подписки. Затем он пытается отфильтровать их до только сообщений с песнями, убедившись, что они являются сообщениями в СМИ, а затем с помощью регулярного выражения попытается получить название группы и название песни. Эта последняя часть немного хрупкая, потому что, конечно, заголовок поста может быть любым, но многие сабвуферы, включая /r/ProgMetal, используют соглашение «название группы — название песни», так что это разумная ставка, которая уловит большинство вещей. .

Играй (список) со мной — Джефф Бек

Spotify также имеет хороший веб-API. Однако с точки зрения авторизации он, очевидно, в первую очередь предназначен для создания сторонних потоковых клиентов, а не для такой работы на стороне сервера, поэтому было немного сложнее выяснить, как именно получить правильный набор ключей доступа, секретов. и токены, чтобы иметь возможность совершать звонки, которые повлияют на мою личную учетную запись Spotify, например, редактировать список воспроизведения.

Однако в блоге Почтальона есть очень хороший путеводитель, который указал мне правильное направление. Ответ состоял в том, чтобы создать приложение на панели разработчика Spotify, чтобы получить идентификатор клиента и секрет клиента. Затем вручную вызовите конечную точку авторизации с помощью Postman, чтобы сгенерировать маркер доступа и маркер обновления. Подробнее о том, как это сделать, читайте в разделе этого поста под заголовком Настройка среды.

В данном случае оказалось проще делать HTTP-вызовы напрямую, чем использовать клиентскую библиотеку API. Я использовал axios для http-вызовов.

npm install axios

Поскольку токены доступа недолговечны, необходимо также периодически использовать токен обновления, чтобы получить новый. Этот процесс описан здесь. Я установил querystring в качестве помощника для выполнения необходимых вызовов application/x-www-form-urlencoded .

npm install querystring

Имея полный набор ключей и токенов, я создал еще один класс для инкапсуляции всего кода, связанного со Spotify.

Я решил проблему с токеном обновления, используя статический фабричный метод SpotifyApi.newApi, который заботится о создании нового токена доступа, а затем передает его в конструктор класса, поэтому каждый раз, когда вы создаете экземпляр класса, вы делаете это с новым токеном доступа. В языке, который позволял это, я мог бы сделать конструктор закрытым.

Затем у класса есть два других метода: один — searchSongUris — который берет объекты дорожки, возвращенные классом reddit, и пытается найти соответствующие URI Spotify для каждого из них, а другой — replacePlaylist — который заменяет содержимое существующего списка воспроизведения Spotify теми, которые URI.

Общая картина - Театр мечты

Нам нужен метод, чтобы склеить все это вместе.

keys.js, импортированный вверху, представляет собой (пропущенный git) файл, содержащий все мои идентификаторы, секреты, токены и т. д. Этот простой метод создает экземпляры классов Reddit и Spotify API и вызывает их методы по очереди, чтобы получить треки из Reddit и сохранить их. в плейлисте Spotify.

Наконец, нам просто нужна точка входа, которая импортирует и вызывает

createPlaylist("progmetal", "<playlist id>", 50)

Благодаря этому в index.js мы теперь можем запускать приложение из командной строки с помощью

node index.js

На прощание — Opeth

Полная версия находится в этом репозитории github. Там вы можете видеть, что я добавил несколько небольших дополнений, таких как возможность передавать параметры — сабреддит, плейлист и лимит — в качестве аргументов командной строки. Я также добавил функцию-обработчик и некоторую бессерверную конфигурацию, чтобы ее можно было развернуть как AWS Lambda и вызывать автоматически раз в неделю по расписанию.

Результирующий плейлист здесь, если вы хотите услышать музыку, которая вдохновила вас на эту, в основном, ненужную причину провести выходные за чтением документации по API.