Создайте собственный трекер зарплат для ежедневных фэнтези-футбольных турниров с помощью Ruby и Twilio MMS

Автор: | 07.08.2026

Наступил сентябрь, НФЛ стартовала, и сезон фэнтези в самом разгаре. Карим Хант — настоящая машина, Зик получит шестинедельную дисквалификацию, столько всего происходит! В этой статье мы покажем, как создать трекер цен для вашего любимого сайта ежедневных фэнтези-спортивных турниров с помощью Ruby. Это поможет вам оставаться впереди конкурентов и получать уведомления об изменениях цен сразу, как только они происходят.

С технической точки зрения, мы будем использовать SQLite — встраиваемую базу данных, и Sequel — легковесный инструментарий для работы с базами данных на Ruby, чтобы хранить все загруженные данные для удобного доступа и запросов. Затем мы настроим повторяющуюся задачу, которая будет загружать CSV-файл каждые «x» часов, например, каждые два часа, и сравнивать записи с теми, что были получены в предыдущем обновлении. После этого вы получите сводку всех изменений через MMS на свой телефон, что может выглядеть так:

Весь код доступен в этом репозитории GitHub, чтобы вы могли следовать за нами.

Начните с подготовки вашего компьютера для запуска Ruby-кода. Вам понадобится Bundler для управления зависимостями этого проекта. Если вы уже использовали Ruby, вероятно, он у вас уже установлен. Если нет, просто введите `gem install bundler` в командной строке (неважно, в какой директории, так как он устанавливается глобально).

Теперь вам нужно установить SQLite и ImageMagick. Способ установки зависит от вашей операционной системы и пакетного менеджера. На Mac с помощью brew можно использовать команды `brew install sqlite` и `brew install imagemagick`. Если вы используете Ubuntu, выполните `sudo apt-get install sqlite` и `sudo apt-get install imagemagick libmagickwand-dev` или эквивалентные команды для вашего дистрибутива.

Создайте папку проекта в любом удобном месте на вашем компьютере и перейдите в неё. Теперь мы будем называть её корневой папкой проекта. Создайте файл с именем «Gemfile» в корневой папке и добавьте в него все необходимые зависимости:

Не беспокойтесь сейчас о том, что делает каждая из них, мы рассмотрим их по мере продвижения. Сохраните файл и выполните команду `bundle install` в командной строке в директории вашего проекта, чтобы установить зависимости.

Наша среда разработки готова, так что давайте перейдём к настройке базы данных. Создайте новый файл `database.rb` в корневой папке. Сначала мы подключим Sequel и инициализируем базу данных:

Использование SQLite в качестве базы данных позволяет избежать дополнительных шагов конфигурации, которые потребовались бы с другими базами данных, такими как PostgreSQL.

Давайте обернём настройку базы данных в модуль, чтобы затем запускать всё из основного скрипта:

Это создаст таблицу Players при первом запуске нашей программы. Таблица будет использоваться для хранения имени игрока, зарплаты, команды, команды соперника, позиции и среднего количества очков за игру. Готовый файл `database.rb` можно найти здесь. Первый даун, 1-я и 10 на подходе к разделу «Получение данных» (для тех, кто не следит за футболом, это означает, что мы близки к следующему этапу).

Используя стандартные библиотеки `csv` и `open-uri`, мы можем создать новый файл `data.csv` и скопировать в него всю информацию, предоставленную по URL, который мы передадим в качестве аргумента.

Теперь мы можем получить URL для CSV-файла. Откройте турнир, который хотите отслеживать, на сайте DFS, затем просто выполните *правый клик* -> *Копировать адрес ссылки* на кнопке *Export To CSV* на DraftKings или FanDuel.

*Вот где она расположена в DraftKings*

Теперь у нас есть два разных фрагмента кода, поэтому самое время создать модуль, который объединит их все, под названием `Tracker`, который будет находиться в файле `tracker.rb`. Он будет хранить наш URL в качестве константы и предоставит простой интерфейс для запуска всех наших скриптов одновременно.

Где значение `URL` — это ссылка, которую вы получили, следуя шагам выше. Затем выполните `ruby tracker.rb` в вашем терминале. Это создаст новый файл data.csv в вашей директории со всей необходимой информацией! Если вы видите ошибку, дважды проверьте, что введённый вами URL корректен и действительно указывает на CSV-файл.

Данные полезны только тогда, когда вы можете извлечь из них информацию, а сейчас это не так просто. Чтобы облегчить запросы, мы сохраним информацию в нашей базе данных SQLite, которую настроили ранее. Мы добавим новый метод в файл `CsvAnalysis` под методом `scrape`, который мы определили ранее:

Это получит все данные из CSV и вернёт игроков в виде массива Ruby-хешей с теми же ключами, что и в таблице базы данных, чтобы мы могли быстро вставить их. Чтобы убедиться, что всё работает как ожидалось, мы можем добавить это в наш Tracker и вывести результат на экран следующим образом:

Теперь вы можете снова выполнить `ruby tracker.rb`, и все данные об игроках должны быть выведены в окно вашего терминала.

Что нам нужно сделать теперь, так это простое условие *if*: если игрока нет в базе данных, мы добавляем его туда. Если он уже существует, проверяем его зарплату. Если она отличается от той, что мы записали ранее, добавляем его в массив. Если нет, переходим к следующему игроку с помощью `next`. Это реализовано в строках 15–20 следующего кода:

Давайте снова выполним `ruby tracker.rb` и проверим, что всё корректно сохранилось в базе данных. Также изменим зарплату игрока, чтобы убедиться, что наш код работает правильно. Перейдите в корневую папку вашего проекта, если вы ещё не там, и выполните `sequel sqlite://dfs.db` в терминале. Это откроет сессию IRB с уже загруженной базой данных в переменной `DB`. Теперь мы можем выполнить `DB[:players].first`, чтобы найти первого игрока в нашей базе данных; круто! Давайте изменим его зарплату на 0 с помощью `DB[:players].first.update(salary: 0)`. Теперь закройте сессию с помощью `quit` и снова запустите Tracker. Если вы повторите шаги выше, то увидите, что цена снова обновилась до той, что указана в CSV, и больше не равна 0. Это означает, что всё работает правильно!

Теперь всё, что нам осталось сделать, — это поместить все эти данные на изображение и отправить его на ваш номер телефона.

Пришло время получить ключ Imgur и учётные данные Twilio.

Для Imgur перейдите на их страницу добавления клиента и заполните все поля. Поскольку нам не нужно предоставлять OAuth-авторизацию, вы можете выбрать «Анонимное использование без авторизации пользователя» и оставить поле обратного вызова пустым. Запишите где-нибудь свой ключ клиента.

Чтобы убедиться, что всё работает правильно, давайте попробуем! Перейдите в терминал и текущую директорию и выполните `irb`; это запустит интерактивную оболочку Ruby. Теперь подключите библиотеку imgur с помощью `require ‘imgur’` и выполните:

Если ваш идентификатор клиента работает правильно, это выведет URL загруженного вами изображения на Imgur. Это довольно круто!

Теперь перейдём в консоль Twilio, чтобы получить учётные данные. После входа в систему и настройки аккаунта вам будут показаны ваш `Account SID` и `Auth token`. Запишите их, а также номер телефона, предоставленный вам Twilio, так как эта информация понадобится позже. Чтобы убедиться, что ваш аккаунт работает, перейдите в панель управления Twilio Build и отправьте тестовое SMS на свой номер телефона. Как фанат Giants, я обычно отправляю «Тайри открыт, ОН ЛОВИТ!», чтобы напомнить о лучших временах, но это на ваше усмотрение.

Поскольку мы будем работать с API-ключами, теперь настроим Dotenv: всегда хорошая практика держать секретные ключи вне вашего кодовой базы. Создайте новый файл `.env` в корне проекта и добавьте туда ключи, которые мы получили ранее, вот так:

Теперь создадим новый файл `notification.rb`, в котором мы будем использовать большинство наших зависимостей.

Что делает весь этот код? Сначала нам нужно отформатировать информацию об игроках. Мы используем формат «ИМЯ_ИГРОКА (КОМАНДА) теперь стоит ЗАРПЛАТА», но вы можете изменить его по своему усмотрению. Затем мы используем эти строки для генерации изображения с помощью RMagick. API не очень удобен для пользователя, поэтому с ним может быть сложно работать; если хотите попробовать, рекомендую ознакомиться с официальной документацией. Первые два аргумента `Magick::Image.new` — это ширина и высота файла. Чтобы рассчитать высоту, мы смотрим, сколько строк нужно напечатать, и умножаем это на тридцать пикселей; размер шрифта — двадцать пикселей, поэтому тридцать пикселей на строку обеспечат хороший интервал. Также можно передать цвет фона в качестве дополнительной опции. Затем мы перебираем строки игроков, чтобы добавить их на изображение.

После создания изображения мы загружаем его на Imgur. Метод `upload_image` вернёт ссылку на него. Я добавил строку `puts up.link`, чтобы вы могли найти URL в своих логах на случай, если захотите поделиться изображением, опубликовать его на форуме и т.д.

Теперь мы наконец можем отправить это себе через MMS с помощью API Twilio. Нам просто нужно добавить это в трекер следующим образом:

В качестве последнего шага мы настроим crontab для запуска этого скрипта каждые x часов; двух часов должно быть достаточно, чтобы получить преимущество перед остальными игроками. Если вы используете Windows, это не сработает, поэтому вам нужно будет найти альтернативное решение (например, Планировщик задач Windows). Создайте новую папку `config` и поместите в неё файл `schedule.rb`. Теперь вам просто нужно указать интервал времени, через который вы хотите запускать скрипт:

После того как вы закончите, просто сохраните файл и выполните `whenever —update-crontab` в терминале. Это будет запускать трекер через каждый указанный интервал, пока ваш компьютер включён. Если вы планируете не держать компьютер включённым большую часть времени, стоит рассмотреть возможность размещения этого на бесплатном Heroku Dyno и использования Heroku Scheduler для периодического запуска трекера. Другой вариант — запуск кода на виртуальной машине DigitalOcean вместо локального компьютера.

Вот и всё! Всякий раз, когда зарплата изменится, вы будете получать это изображение через MMS на свой номер телефона, чтобы всегда быть в курсе последних изменений в ваших фэнтези-футбольных командах!

Если у вас возникнут какие-либо проблемы, не стесняйтесь оставлять комментарии, открывать issue в репозитории GitHub или обращаться ко мне напрямую @FanaHOVA в Twitter или по электронной почте fana@alessiofanelli.com. Всегда рад помочь или просто поговорить о спорте!