Обходите очереди на эксклюзивные скидки в Twitter с помощью Node.js и Twilio SMS

Автор: | 08.08.2026

Я просто не мог зайти в сеть достаточно быстро. Возможно, вы знаете это чувство: кто-то или какая-то компания, на которую вы подписаны, публикует распродажу в Twitter, и к тому времени, как вы заходите в сеть, вы либо пропустили твит, либо распродажа уже закончилась. Вы могли бы включить SMS-уведомления и получать каждый твит в виде сообщения своевременно, но это не особо помогает, так как вы начинаете игнорировать сообщения, когда их количество превышает несколько твитов за короткий промежуток времени. Что, если бы вы могли создать приложение, которое отправляет SMS-уведомление только тогда, когда твит соответствует той распродаже, которую вы действительно ищете?

Именно здесь на помощь приходит Twilio SMS API.

В моем случае я большой поклонник Уэса Боса (@wesbos). Уэс — разработчик, который создает качественные и увлекательные онлайн-курсы по веб-разработке, особенно в среде JavaScript. Мистер Босс постоянно пишет в твиттере и очень хорошо взаимодействует лично со своими подписчиками. Но он также выпускает кастомные, качественные наклейки для ноутбуков по низкой цене. Проблема в том, что, хотя он увеличил размер партии с каждой распродажи, мне так и не удалось зайти в сеть вовремя, чтобы купить их до того, как они были распроданы. Учитывая его высокую активность в твиттере и огромное количество подписчиков, я понял, что должен использовать свои навыки программирования, чтобы опередить всех.

Слушая его ленту в Twitter на наличие определенного ключевого слова через Twitter REST API, я придумал хак, который проверяет его ленту каждые несколько минут и отправляет мне SMS, если за этот период он написал о наклейках.

Давайте создадим это вместе.

Для того чтобы следовать этому руководству, вам потребуется следующее:

— учетная запись Twilio (зарегистрируйтесь бесплатно) и телефонный номер Twilio с поддержкой SMS;

— учетная запись разработчика Twitter (войдите в Twitter через apps.twitter.com);

— последняя стабильная версия Node.js (скачайте здесь) и установленный git (здесь);

— учетная запись mLab (бесплатно 500 МБ) для MongoDB;

— учетная запись Heroku для деплоя (зарегистрируйтесь здесь).

Настройка Twilio не так дорога. На самом деле, вы можете зарегистрироваться и получить свой API-ключ бесплатно, а также получить небольшой пробный баланс для тестирования. Если вы израсходуете пробный баланс, переход на платный тариф будет очень недорогим для небольших проектов. Для местного номера в США это всего $1 в месяц, а SMS-сообщения стоят дешево. В моем случае, так как я израсходовал пробный баланс, я обновил свой аккаунт и загрузил $20 еще в июле 2017 года, и к середине ноября у меня все еще оставалось $15.71 на счету. Я знал, что это будет очень недорогой способ заняться старомодным сталкингом в Twitter.

Давайте начнем с приложения.

#### Создание проекта и установка Twilio

В командной строке создайте новую папку и перейдите в нее:

Чтобы установить все необходимые пакеты, нужно инициализировать папку для npm.

Из командной строки выполните команду `npm init`, указав `server.js` в качестве значения параметра ‘main’ при запросе. После завершения этого процесса установите пакет Twilio для Node.js.

#### Установка дополнительных зависимостей

Этот проект требует дополнительных зависимостей для обеспечения сохранности данных с помощью MongoDB, форматирования даты и времени с помощью Moment.js, доступа к Twitter API и хранения переменных окружения с помощью `dotenv`. Обратите внимание, что можно установить несколько npm-пакетов одновременно.

Пока вы находитесь в командной строке, создайте следующие файлы: `.gitignore`, `.env`, `Procfile` и `server.js`.

Нам нужно убедиться, что мы не добавляем определенные файлы в систему контроля версий, поэтому добавьте следующее в `.gitignore`.

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

Наконец, `Procfile` используется Heroku после деплоя для запуска этого приложения как воркера, то есть без веб-интерфейса.

Просто добавьте эту единственную строку в ваш `Procfile`:

Мы будем использовать переменные окружения для безопасной передачи наших API-ключей и других секретов в приложение. Опять же, мы не хотим, чтобы эта информация была общедоступной, чтобы кто-то не украл наши ключи для своих недобросовестных целей. В данном случае мы будем хранить наши ключи в `.env` для импорта в `server.js`. При деплое мы можем использовать либо панель управления Heroku, либо пакет `heroku-cli` для хранения этих переменных для вашего приложения. Подробнее о переменных окружения можно прочитать в этой отличной статье Доминика Кунделя.

После покупки номера в Twilio вы сможете увидеть как свой Account SID, так и Auth Token в консоли Twilio. Внутри файла `.env` добавьте следующие строки, конечно, опуская угловые скобки, которые я привел в примере ниже:

Примечание: как для вашего личного, так и для номера Twilio в США используйте 1, за которым следуют 10 цифр номера. Без пробелов, скобок, тире или других знаков препинания — только знак плюс и 11 цифр.

Для Twitter перейдите на https://apps.twitter.com/, войдите в систему и создайте новое приложение. Дайте ему имя и описание. Поскольку у этого приложения нет фронтенда, используйте заглушку для поля «Website», например, ‘https://www.twilio.com’, и оставьте пустым поле «Callback URL». После создания приложения нажмите на вкладку «Keys and Access Tokens». Затем нажмите «Generate a Token», и теперь у вас есть доступ к тому, что нужно добавить в `.env`:

Наконец, для MongoDB давайте настроим бесплатный сервер разработки через MLAB.

Если вы еще этого не сделали, перейдите на http://www.mlab.com и создайте учетную запись.

После создания учетной записи и подтверждения вашего адреса электронной почты вы можете получить доступ к бесплатному серверу на 500 МБ, нажав на кнопку «Create New» под заголовком «MongoDB Deployments».

Затем выберите облачного провайдера «AWS» и тип плана «Sandbox», что позволит вам выбрать географический регион после нажатия кнопки «Continue». На этом этапе введите имя вашей базы данных как `twitter-stalk`. Вы находитесь в нескольких секундах от бесплатной облачной базы данных MongoDB объемом 500 ГБ.

После создания базы данных вы увидите зеленую галочку рядом с вашим экземпляром базы данных.

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

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

Вторая вкладка в середине страницы — это вкладка `Users`. Нажмите здесь, и вы увидите опцию `Add database user` в правом нижнем углу.

Установите имя пользователя как `admin` и введите надежный пароль по вашему выбору. Он понадобится вам через минуту.

Обратите внимание на URI для доступа к вашей базе данных. Создайте пользователя ‘admin’ и дайте этому пользователю надежный пароль. Как только вы вернетесь на страницу базы данных, прокрутите страницу вверх, и вы увидите следующую инструкцию: `To connect using a driver via the standard MongoDB URI`.

Скопируйте пример URI ниже этой подсказки и добавьте следующее в `.env`:

Мы создадим три функции: одну для вызова Twitter API и добавления новых твитов в базу данных, другую для получения последнего твита из базы данных и, наконец, одну для отправки SMS-сообщения. Для этого руководства мы будем использовать Twitter REST API, так как нам нужно проверять твиты только время от времени.

Откройте `server.js` в вашем редакторе кода и давайте начнем!

#### Импорт переменных окружения

Пакет `dotenv` импортирует любые переменные, которые мы сохранили в нашем файле `.env`. Мы хотим импортировать эти переменные только в том случае, если мы находимся в среде разработки. Мы исключили наш файл `.env` из системы контроля версий git, поэтому для продакшена мы будем импортировать переменные окружения другим способом, о котором поговорим позже.

На первой строке `server.js` добавьте следующий блок кода:

#### Инициализация клиентов Twilio, Twitter и MongoDB

Загрузив наши переменные окружения, теперь мы можем использовать их в нашем приложении. Добавьте следующее в `server.js` для инициализации наших клиентов Twilio, Twitter и MongoDB:

Для пакетов `twilio` и `twitter` вы импортируете функцию, которую можно вызвать напрямую, передав ваши ключи в качестве параметров. Twilio принимает два параметра: ваш Account SID и ваш Auth Token. Twitter принимает один объект, содержащий все четыре ключа, которые вы сохранили ранее.

Для MongoDB нам нужно сделать немного больше. Пока установите URI для подключения:

#### Добавление пакета Moment и модуля Assert

Moment позволяет форматировать временные метки согласованно в разных средах. Мы будем использовать его здесь для хранения временной метки Unix. Assert позволит нам выполнять проверку ошибок при подключении к MongoDB и завершать работу приложения, если мы не можем подключиться к базе данных.

#### Написание наших функций

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

Мне нравится простота Twilio. Twilio предоставляет нам метод на основе промисов для отправки SMS-сообщений, базовая структура которого выглядит следующим образом: `client.messages.create({}).then().catch()`.

Все, что нам нужно сделать, это заполнить детали в соответствии с нашим приложением:

*Что делает эта функция?*

Метод `messages.create` принимает один аргумент — объект с нашими текстовыми данными. Twilio выполняет всю магию для отправки SMS-сообщения на любой номер, который вы передадите, при условии, что оно отправляется с действующего номера Twilio (с доступным балансом).

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

*Давайте протестируем это!*

После добавления вышеуказанного блока кода сохраните `server.js`. Затем из командной строки выполните команду `node server`. Вскоре вы должны получить SMS-сообщение с текстом «Уэс Бос только что написал о наклейках».

После тестирования вызова Twilio SMS API мы можем начать создавать движок, который соединит все три сервиса: MongoDB, Twitter и Twilio.

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

#### Подключение к MongoDB

После тестирования кода снова откройте `server.js` в текстовом редакторе и добавьте следующее на последней строке:

Метод `connect` принимает URI, который мы создали ранее, и возвращает нам базу данных, на которую мы будем ссылаться в нашем приложении. Мы назовем нашу коллекцию твитов просто `tweets`. Нам нужно передать нашу коллекцию в нашу (пока еще не написанную) функцию appEngine, чтобы мы могли хранить и извлекать данные твитов.

#### Создание движка приложения

Что должен делать движок приложения? Он должен вызывать Twitter API, определять, написал ли @wesbos о наклейках, и отправлять нам эту информацию по SMS. Мы вызываем Twitter REST API, поэтому каждый раз при вызове возможно получение дублирующихся результатов от одного вызова к другому. Как мы можем избежать получения дублирующихся результатов?

У каждого объекта твита есть `id_str`. Значение `0` (ноль) представляет самый ранний возможный идентификатор твита. И это число только увеличивается со временем и твитами, оно никогда не уменьшается. Это означает, что если мы сохраним самые последние твиты, мы сможем искать твиты, которые появились с того времени. Когда мы получаем результат от вызова API, мы сохраняем твиты в нашей базе данных и отправляем SMS с текстом твита.

Эта функция принимает только один аргумент — `collection`. Для коллекции я собираюсь использовать функцию MongoDB `findOne`, сортировать в порядке убывания по `id_str` твита и ограничивать результаты до 1. `id_str` похож на временную метку в том смысле, что чем выше число, тем новее твит.

Обратите внимание на тернарный оператор, используемый для определения значения `lastTweetId`. Если значение `tweet` равно `null` или у твита отсутствует `id_str`, мы не сможем прочитать `tweet.id_str` без возникновения ошибки типа. Тернарный оператор возвращает значение `0`, если возвращается любое недопустимое значение.

Как только мы нашли последний идентификатор твита, если таковой имеется, мы используем его для вызова Twitter Search API. Мы вызываем `get` на `twitterClient`, передавая путь к API поиска и объект опций для поиска. Мы укажем, что хотим искать твиты от @wesbos, исключая ретвиты, и искать по одному термину «stickers». Мы также ограничим наш поиск твитами, опубликованными после последнего идентификатора твита, который мы получили из нашей базы данных.

Если есть какие-либо статусы, мы отправим текст первого полученного твита с помощью вызова Twilio API, который мы тестировали ранее, а затем вставим все статусы в нашу базу данных.

Теперь мы готовы скопировать блок кода Twilio сверху и вставить его в нашу функцию `appEngine`. Нам нужно немного изменить функцию, чтобы отправлять текст твита вместе с текстом нашего сообщения. Нам просто нужно убедиться, что вызов API успешен и что он возвращает новые твиты.

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

##### Как мы к этому пришли?

Внутри блока кода функции обратного вызова `twitterClient.get()` мы используем два условных оператора: один для перехвата любых ошибок подключения к Twitter, и второй условный оператор для проверки того, что ответ содержит новые твиты.

Затем мы вырезаем и вставляем функцию `twilioClient.messages.create` внутри второго условного блока кода, но меняем `body` так, чтобы он включал текст твита. (Убедитесь, что вы удалили оригинальный вызов `twilioClient.messages.create`, иначе вы будете получать SMS каждый раз при запуске скрипта.)

Таким образом, мы получаем:

Мы используем `moment.now()` для отслеживания временной метки Unix в наших логах каждый раз, когда отправляем сообщение, чтобы у нас был журнал, который мы можем проверить позже.

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

Мы делаем это с помощью функции MongoDB `insertMany()`. Нам не нужно беспокоиться о схемах данных в таком масштабе, поэтому мы просто вставим все полученные статусы.

Теперь давайте запустим приложение. Сначала откройте второй терминал или командную строку, чтобы запустить вашу базу данных MongoDB, выполнив команду `mongod`, затем в папке вашего проекта запустите уведомитель с помощью `node server`. Вы должны увидеть сообщение об успешном подключении к MongoDB и получить SMS от Twilio, когда @wesbos напишет о наклейках, пока приложение работает.

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

Скачайте и установите Heroku CLI.

Внутри папки вашего проекта инициализируйте Git из командной строки, выполнив команду `git init`.

#### Подключение к Heroku

После установки Heroku CLI и инициализации вашего репозитория выполните следующие команды:

Вас попросят ввести ваш адрес электронной почты и пароль, который вы указали при регистрации в Heroku.

Heroku создаст случайное имя для вашего приложения, которое вы сможете изменить позже в панели управления Heroku. Он также добавит удаленный источник для вашего приложения.

#### Добавление переменных окружения в продакшен

Для каждой из переменных окружения, которые мы сохранили в `.env` для нашей среды разработки, мы должны добавить в нашу продакшен-среду в Heroku.

Из командной строки выполните следующую команду, заменяя ключи и значения на те, которые мы сохранили ранее. Вы можете добавить все переменные окружения одной командой, разделяя пары ключ/значение пробелом. Также опустите любые кавычки до или после ваших значений:

#### Проверка переменных окружения

Убедитесь, что все ваши переменные сохранены, используя команду:

#### Добавление, коммит и пуш

Выполните следующие команды git последовательно:

Это подготовит все ваши файлы для коммита в систему контроля версий.

Это зафиксирует ваши изменения на данный момент. Вы всегда сможете откатить ваш код до этой точки разработки в будущем, если потребуется. Опция `-m` позволяет добавить комментарий к этому коммиту. Поскольку это наш первый коммит, мы просто добавим комментарий ‘initial commit’.

Эта команда будет выполняться несколько секунд. На вашем экране вы увидите процесс создания вашего Node.js приложения на Heroku, и в конце концов вам сообщат, что процесс `Done!`. На этом этапе ваше приложение работает в сети, и вы будете периодически получать SMS-сообщения всякий раз, когда Уэс Бос напишет о наклейках.

Если вы хотите увидеть это в действии прямо сейчас, вместо использования учетной записи Уэса Боса в Twitter используйте свою собственную и напишите твит с упоминанием слова `stickers`. Вы получите SMS-сообщение через несколько секунд. Только не забудьте позже изменить его обратно, чтобы вы могли получить свою пачку наклеек для ноутбука от Уэса Боса.

Мое приложение хорошо мне послужило. Я наконец-то получил наклейки от человека, мифа, легенды — Уэса Боса. Я получал SMS время от времени, когда заходила речь о наклейках, но почти сразу же получал уведомление о том, что наклейки поступили в продажу, и купил одну из первых 100 пачек. Теперь, когда у меня есть пара классных пачек наклеек, я рад поделиться своей техникой с вами -> https://github.com/wesleylhandy/bos-stalker

Помогло ли вам это получить свои собственные наклейки? Мне бы хотелось услышать от вас!

Twitter: @wesleylhandy

Github: https://github.com/wesleylhandy

LinkedIn: https://www.linkedin.com/in/wesleylhandy/

Email: wesleylhandy@gmail.com