За последний год значительные изменения в американской политике заставили многих людей почувствовать, что им следует активнее участвовать в общественной жизни.
Политическое адвокатирование может принимать различные формы: оно может быть пассивным или активным, партийным или непартийным, личным или масштабным. Как инженеры, мы обладаем уникальной возможностью применять свои навыки для важных дел. В этой статье рассказывается, как я создал простое приложение с открытым исходным кодом, используя голосовой 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.
Свяжитесь со мной, если у вас есть вопросы или вы хотите узнать больше!