Настройка SMS (Twilio)
Команды установки Python-зависимостей на этой странице рассчитаны на чекаут исходников, подготовленный через PM. После изменения зависимостей заново активируйте чекаут и перезапустите Hermes.
Hermes подключается к SMS через API Twilio. Пользователи пишут на ваш номер Twilio и получают ответы от ИИ — тот же диалоговый опыт, что в Telegram или Discord, только обычными текстовыми сообщениями.
Шлюз SMS использует те же учётные данные, что и опциональный навык телефонии. Если вы уже настроили Twilio для голосовых звонков или разовых SMS, шлюз заработает с теми же TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN и TWILIO_PHONE_NUMBER.
Что понадобится
- Аккаунт Twilio — зарегистрируйтесь на twilio.com (доступен бесплатный пробный период)
- Номер телефона Twilio с поддержкой SMS
- Сервер с публичным доступом — Twilio отправляет вебхуки на ваш сервер, когда приходит SMS
- aiohttp —
cd ~/.hermes/hermes-agent && python -c "import pm; pm.sync_venv(['sms'], explicit=True)"
Шаг 1. Получите учётные данные Twilio
- Откройте консоль Twilio
- Скопируйте Account SID и Auth Token с панели управления
- Перейдите в Phone Numbers → Manage → Active Numbers — запишите свой номер в формате E.164 (например,
+15551234567)
Шаг 2. Настройте Hermes
Интерактивная настройка (рекомендуется)
hermes gateway setup
В списке платформ выберите SMS (Twilio). Мастер запросит ваши учётные данные.
Ручная настройка
Добавьте в ~/.hermes/.env:
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token_here
TWILIO_PHONE_NUMBER=+15551234567
# Безопасность: ограничьте доступ конкретными номерами (рекомендуется)
SMS_ALLOWED_USERS=+15559876543,+15551112222
# Опционально: домашний канал для доставки сообщений из cron-задач
SMS_HOME_CHANNEL=+15559876543
Шаг 3. Настройте вебхук Twilio
Twilio нужно знать, куда отправлять входящие сообщения. В консоли Twilio:
- Откройте Phone Numbers → Manage → Active Numbers
- Кликните по своему номеру
- В разделе Messaging → A MESSAGE COMES IN задайте:
- Webhook:
https://your-server:8080/webhooks/twilio - HTTP Method:
POST
- Webhook:
Если Hermes работает локально, пробросьте вебхук через туннель:
# Через cloudflared
cloudflared tunnel --url http://localhost:8080
# Через ngrok
ngrok http 8080Полученный публичный URL укажите в качестве вебхука Twilio.
Задайте SMS_WEBHOOK_URL равным тому же URL, что вы прописали в Twilio. Без этого не пройдёт проверка подписи Twilio, и адаптер откажется запускаться:
# Должен совпадать с URL вебхука в консоли Twilio
SMS_WEBHOOK_URL=https://your-server:8080/webhooks/twilio
По умолчанию вебхук слушает порт 8080. Переопределить его можно так:
SMS_WEBHOOK_PORT=3000
Шаг 4. Запустите шлюз
hermes gateway
В логах появится:
[sms] Twilio webhook server listening on 127.0.0.1:8080, from: +1555***4567
Если видите Refusing to start: SMS_WEBHOOK_URL is required, задайте SMS_WEBHOOK_URL равным публичному URL из консоли Twilio (см. шаг 3).
Напишите на свой номер Twilio — Hermes ответит по SMS.
Переменные окружения
| Переменная | Обязательна | Описание |
|---|---|---|
TWILIO_ACCOUNT_SID | Да | Account SID в Twilio (начинается с AC) |
TWILIO_AUTH_TOKEN | Да | Auth Token в Twilio (используется и для проверки подписи вебхука) |
TWILIO_PHONE_NUMBER | Да | Ваш номер Twilio (формат E.164) |
SMS_WEBHOOK_URL | Да | Публичный URL для проверки подписи Twilio — должен совпадать с URL вебхука в консоли Twilio |
SMS_WEBHOOK_PORT | Нет | Порт прослушивания вебхука (по умолчанию 8080) |
SMS_WEBHOOK_HOST | Нет | Адрес привязки вебхука (по умолчанию 127.0.0.1) |
SMS_INSECURE_NO_SIGNATURE | Нет | Установите true, чтобы отключить проверку подписи (только для локальной разработки — не для продакшена) |
SMS_ALLOWED_USERS | Нет | Номера E.164 через запятую, которым разрешён диалог |
SMS_ALLOW_ALL_USERS | Нет | Установите true, чтобы разрешить всем (не рекомендуется) |
SMS_HOME_CHANNEL | Нет | Номер для доставки cron-задач и уведомлений |
SMS_HOME_CHANNEL_NAME | Нет | Отображаемое имя домашнего канала (по умолчанию Home) |
Особенности работы по SMS
- Только обычный текст — Markdown автоматически вырезается, ведь SMS показывает его как голые символы разметки
- Лимит 1600 символов — длинные ответы разбиваются на несколько сообщений по естественным границам: сначала по переносам строк, затем по пробелам
- Защита от эха — сообщения с вашего собственного номера Twilio игнорируются, чтобы не возникало петель
- Скрытие номеров — в логах телефонные номера затираются ради конфиденциальности
Безопасность
Проверка подписи вебхука
Hermes убеждается, что входящие вебхуки действительно пришли от Twilio: для этого проверяется заголовок X-Twilio-Signature (HMAC-SHA1). Так злоумышленник не сможет подсунуть поддельные сообщения.
Переменная SMS_WEBHOOK_URL обязательна. Укажите в ней публичный URL из консоли Twilio. Без неё адаптер не стартует.
Для локальной разработки без публичного URL проверку можно отключить:
# Только для локальной разработки — НЕ для продакшена
SMS_INSECURE_NO_SIGNATURE=true
Списки разрешённых пользователей
По умолчанию шлюз отклоняет всех. Настройте список разрешений:
# Рекомендуется: ограничить доступ конкретными номерами
SMS_ALLOWED_USERS=+15559876543,+15551112222
# Либо разрешить всем (НЕ рекомендуется для ботов с доступом к терминалу)
SMS_ALLOW_ALL_USERS=true
У SMS нет встроенного шифрования. Не используйте этот канал для чувствительных операций, если не понимаете последствий для безопасности. Для таких задач лучше подойдут Signal или Telegram.
Решение проблем
Сообщения не доходят
- Проверьте, что URL вебхука Twilio указан верно и доступен публично
- Убедитесь, что
TWILIO_ACCOUNT_SIDиTWILIO_AUTH_TOKENкорректны - Загляните в консоль Twilio → Monitor → Logs → Messaging на предмет ошибок доставки
- Проверьте, что ваш номер есть в
SMS_ALLOWED_USERS(или заданSMS_ALLOW_ALL_USERS=true)
Ответы не отправляются
- Проверьте, что
TWILIO_PHONE_NUMBERзадан правильно (формат E.164 с+) - Убедитесь, что у вашего аккаунта Twilio есть номера с поддержкой SMS
- Просмотрите логи шлюза Hermes на ошибки API Twilio
Конфликт портов вебхука
Если порт 8080 уже занят, поменяйте его:
SMS_WEBHOOK_PORT=3001
И обновите URL вебхука в консоли Twilio, чтобы он совпадал.