Как отправить 10 000 звонков в Конгресс США с помощью Node.js и Twilio

Автор: | 07.08.2026

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

Политическое адвокатирование может принимать различные формы: оно может быть пассивным или активным, партийным или непартийным, личным или масштабным. Как инженеры, мы обладаем уникальной возможностью применять свои навыки для важных дел. В этой статье рассказывается, как я создал простое приложение с открытым исходным кодом, используя голосовой API Twilio, которое обработало более 10 000 звонков сенаторам и представителям Конгресса (или сразу перейдите к готовому коду). Вы также можете посмотреть, как я программировал это приложение в видео моего выступления на SIGNAL 2017.

Наш стек технологий: Node/Express, Twilio и API от Sunlight Foundation, который позволяет находить представителей по почтовому индексу.

Вот как это работает:

— Пользователь звонит на наш номер Twilio.

— Номер запрашивает у него почтовый индекс.

— Пользователь вводит свой почтовый индекс.

— Номер соединяет его с его представителями.

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

Чтобы создать такой поток звонков, простое приложение на Node.js использует API Twilio для выполнения следующих действий:

— Определяет маршрут Express для обработки входящих сообщений от Twilio.

— Запрашивает у пользователя почтовый индекс.

— Получает ввод почтового индекса от Twilio.

— Находит представителей по этому почтовому индексу и перенаправляет звонок на их номера.

Начнем с создания базового приложения Express в файле index.js:

Обратите внимание, что вам нужно выполнить команду `npm init -y`, а затем `npm install —save express body-parser request twilio`. Это создаст файл `package.json` с параметрами по умолчанию и запишет в него зависимости.

Мы ожидаем, что Twilio запросит маршрут `new_phone_call`, когда пользователь сделает новый звонок (чтобы узнать больше о том, как работает Twilio, см. статью «Ответ на телефонные звонки в Node.js»). Теперь нужно сформировать ответ на запрос Twilio.

На этом этапе мы будем использовать объект `twilio.TwimlResponse` для построения ответа. Объект `TwilioResponse` предоставляет удобный способ генерации TwiML — инструкций, которые Twilio использует для создания опыта пользователя, позвонившего на наш номер.

Функция `gather()` выполняет несколько важных задач. Чтобы найти представителей по почтовому индексу, нам нужен обычный пятизначный индекс, поэтому мы указываем Twilio ждать ввода пользователем пяти цифр с помощью атрибута `numDigits`. Атрибут `timeout` указывает Twilio ждать не более 30 секунд ввода этих пяти цифр, прежде чем прекратить ожидание.

Атрибуты `action` и `method` сообщают Twilio, как уведомить нас после завершения ввода пользователем. В данном случае мы указываем Twilio отправить новый HTTP-запрос POST на конечную точку нашего сервера под названием `redirect_to_congress`. Мы еще не создали эту конечную точку, но скоро это сделаем.

Для этого нового запроса от Twilio настроим новый маршрут с новым ответом. Почтовый индекс, введенный пользователем, будет передан в HTTP-запросе как параметр Digits. Мы можем попросить Express передать этот параметр с помощью `req.body.Digits`.

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

API можно вызвать с помощью HTTP-запроса GET:

API Sunlight вернет список объектов, по одному для каждого конгрессмена, связанного с введенным почтовым индексом. Теперь добавим логику звонков, которая будет перебирать список конгрессменов и звонить им по очереди:

Вот и всё! Код написан.

Теперь запустим приложение.

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

Для этого сначала установите LocalTunnel. Мы сделаем глобальную установку для простоты, но вы также можете добавить это в ваш package.json:

`npm install -g localtunnel`

Теперь запустите приложение с помощью:

`node index.js`

Это запустит приложение на порту 3000. В отдельном окне терминала введите:

`lt —port 3000`

LocalTunnel сгенерирует случайный публичный URL, который будет перенаправлять HTTP-запросы на приложение, работающее на вашем локальном хосте. Команда `lt` выдаст результат, похожий на:

`your url is: https://nhycchbacp.localtunnel.me`

Запомните этот URL. Мы собираемся настроить Twilio для связи с ним.

Теперь пришло время соединить все части. Нам нужно настроить номер телефона Twilio и указать Twilio, где найти наше приложение.

Перейдите в панель управления Phone Numbers и добавьте новый номер телефона.

После создания номера телефона щелкните по нему, чтобы настроить его.

Сейчас мы работаем только с голосовыми вызовами, поэтому нужно изменить только голосовую конфигурацию номера. Введите URL вашего сервера или LocalTunnel, добавив к нему точку входа `/new_phone_call`.

Когда на ваш номер Twilio поступит новый звонок, Twilio отправит HTTP-запрос POST на настроенный вами URL.

Готово! Позвоните на свой номер телефона, введите почтовый индекс, и вы будете соединены со своими представителями в Конгрессе.

Оглядываясь назад, мы создали невероятно мощный инструмент всего в 46 строках кода.

За последние шесть месяцев простое приложение на основе этого кода обработало более 10 000 звонков в Конгресс. Полезные инструменты политического адвокатирования не обязательно должны быть сложными или продвинутыми — на самом деле, лучшие инструменты часто самые простые. Мобилизация тысяч людей — это немалое достижение, и оказывается, что API Twilio — отличный способ начать.

Ознакомьтесь с полным исходным кодом этого руководства на GitHub.

Подумайте, что еще можно сделать для расширения этого приложения:

— Роботизированные голоса безличны. Запишите реальные аудиоподсказки для приветствия звонящих, запроса почтового индекса и т.д.

— Зависимость от API Sunlight Foundation создает задержку и дополнительную точку отказа. Мы могли бы кэшировать поиск по почтовым индексам или просто хранить поиск номеров телефонов на сервере.

— Добавьте коммутатор, чтобы пользователь мог слушать и выбирать различные опции («нажмите 1 для X, нажмите 2 для Y…»).

— Расширьте это приложение, включив в него представителей штатов.

Мы реализовали все это и даже больше в проекте General Congress Hotline, который основан на этом 46-строчном примере Call Congress.

Свяжитесь со мной, если у вас есть вопросы или вы хотите узнать больше!