7 мин чтенияИнтеграции

Slack-бот для сокращения URL: укорачивайте ссылки и маршрутизируйте алерты

Установите приложение Elido для Slack, используйте slash-команду /shorten и направляйте пороговые алерты в любой канал без написания обработчиков webhook.

Marius Voß
DevRel · edge infra
Диаграмма Slack-бота для сокращения URL: slash-команда слева, Elido edge в центре, сообщения алертов канала справа с бейджами критичности.

Slack уже занял весь чат-интерфейс вашей команды - пусть заодно сокращает и ссылки. Приложение Elido для Slack делает две вещи: даёт каждому участнику slash-команду /shorten и направляет алерты о событиях со ссылками в нужные каналы. Установка занимает около 90 секунд. Никакого кода обработчиков webhook, никакого Bolt SDK, никакого ngrok-туннеля.

В этой статье разберём три составляющих: путь slash-команды, матрицу маршрутизации алертов и механизм подписи HMAC, который не даёт случайным POST-запросам выдавать себя за Slack. Если вас интересует более широкая webhook-поверхность, которая питает эти алерты, в статье вебхуки для событий со ссылками задокументирован каждый payload, который выдаёт Elido. Slack-приложение - одна из готовых интеграций, которые обрабатывают эти события за вас.

Slash-команда /shorten

Пользователь вводит это в любом канале:

/shorten https://blog.elido.app/post/launch-2026?utm_source=announce

Slack отправляет подписанный POST на https://api.elido.app/integrations/slack/commands. Тело запроса имеет формат application/x-www-form-urlencoded (Slack по-прежнему использует form-encoding для slash-команд, а не JSON - это удивляет всех в первый раз). Релевантные поля:

team_id=T01ABCD2EF
channel_id=C01234ABCDE
user_id=U01HJKLMNOP
command=/shorten
text=https://blog.elido.app/post/launch-2026?utm_source=announce
response_url=https://hooks.slack.com/commands/T01ABCD2EF/...

Elido ищет OAuth-запись по team_id, находит ID воркспейса, для которого было произведено подключение, создаёт shortlink в домене по умолчанию воркспейса и возвращает эфемерное сообщение менее чем за 200 мс при p95. По умолчанию ответ эфемерный, чтобы канал не забивался каждый раз, когда кто-то сокращает URL во время встречи.

Если вызывающий хочет публичное сообщение, он передаёт --public последним токеном:

/shorten --public https://launch.elido.app

При установке требуются три OAuth-разрешения: commands (чтобы slash-команду можно было вызвать), chat:write (чтобы Elido мог публиковать дополнительные сообщения с кнопками копирования) и incoming-webhook (чтобы алерты попадали в канал, выбранный установщиком). В справочнике по Slash Commands Slack перечислен полный набор, но этих трёх достаточно для всего, что делает Elido. Кастомные домены поддерживаются: если в вашем воркспейсе настроен домен go.acme.com через кастомные домены, /shorten создаёт shortlink'и на этом хосте.

Трёхэтапная диаграмма slash-команды /shorten Elido: пользователь вводит команду, Slack отправляет подписанный запрос на api.elido.app, Elido отвечает эфемерным сообщением с короткой ссылкой за 200 мс p95.

Несколько слов о бюджетах задержки. Slack даёт slash-командам 3000 мс реального времени на ответ. Elido отвечает за 180-220 мс p95 через edge-POPы в ЕС и США, потому что обработчик slash-команды использует тот же hot-path кеш, что и edge-редирект. Если ваша команда в регионе APAC и вы наблюдаете значения выше 350 мс, проверьте региональную маршрутизацию POP в /docs/guides/observability.

Канальные алерты на основе триггеров событий

Вторая половина Slack-приложения - маршрутизация алертов. Вы выбираете тип события, выбираете канал и получаете уведомление. Четыре типа событий, доступные сегодня:

  • broken-link: при последнем обходе сканера ссылок цель вернула 4xx или 5xx
  • click-threshold: клики превысили сохранённый порог (по умолчанию: 100 в скользящем 5-минутном окне)
  • scan-failure: URL-сканер пометил цель как фишинг, вредоносное ПО или как присутствующую в публичном блок-листе
  • new-conversion: сработало отслеживаемое конверсионное событие (требует отслеживания конверсий)

Payload алерта, который Elido перенаправляет в Slack, использует Block Kit - потому что простой текст в оживлённом канале игнорируется. Вот как выглядит алерт click-threshold в транспорте, когда Elido делает POST на URL incoming-webhook Slack:

{
  "text": "click-threshold crossed on go.acme.com/launch",
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": ":chart_with_upwards_trend: Click threshold crossed"
      }
    },
    {
      "type": "section",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "*Link:*\n<https://go.acme.com/launch|go.acme.com/launch>"
        },
        { "type": "mrkdwn", "text": "*Window:*\n5m" },
        { "type": "mrkdwn", "text": "*Clicks:*\n412" },
        { "type": "mrkdwn", "text": "*Threshold:*\n100" }
      ]
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": { "type": "plain_text", "text": "Open dashboard" },
          "url": "https://app.elido.app/links/abc123"
        }
      ]
    }
  ]
}

Алерт scan-failure выглядит аналогично, но использует :rotating_light: и содержит категорию угрозы от сканера: phishing, malware, spam или blocklist. Алерт broken-link включает HTTP-статус и временную метку последнего успешного состояния - именно это дежурный спрашивает первым делом.

Матрица маршрутизации алертов: строки показывают типы событий broken-link, click-threshold, scan-failure, new-conversion; столбцы показывают целевой канал Slack, эмодзи, цель ping, цвет критичности.

Маршрутизация настраивается на уровне воркспейса и отдельного события. Типичная конфигурация для команды роста из 30 человек:

СобытиеКаналЭмодзиПинги
broken-link#ops-alerts:rotating_light:@oncall
click-threshold#growth:chart_with_upwards_trend:(нет)
scan-failure#security:rotating_light:@sec-oncall
new-conversion#wins:tada:(нет)

Всё это настраивается в панели настроек интеграции Slack. Каждое правило - одна строка в Postgres. Без YAML, без JSON-конфигов, без повторного деплоя. Тот же движок маршрутизации работает в интеграциях Linear и Pipedrive, поэтому ментальная модель переносится, если вы используете оба инструмента.

Если алерты нужно доставлять в несколько мест, продублируйте то же событие в универсальную подписку на webhook и направьте JSON туда, куда нужно. Этот паттерн задокументирован в статье автоматизация сокращения URL через Zapier для no-code аудитории.

Проверка HMAC и ловушка переустановки

Slack подписывает каждый входящий запрос к вашему endpoint'у slash-команды. Подпись - это HMAC SHA256 по строке, которую Slack составляет из версии, временной метки и сырого тела запроса. Алгоритм описан в руководстве Slack по проверке запросов. Верификатор Elido на Go выглядит примерно так:

func verifySlackSignature(secret, ts, body, sig string) error {
    // Reject anything older than 5 minutes to block replays.
    age := time.Since(parseTs(ts))
    if age > 5*time.Minute || age < -1*time.Minute {
        return errReplay
    }
    base := fmt.Sprintf("v0:%s:%s", ts, body)
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write([]byte(base))
    expected := "v0=" + hex.EncodeToString(mac.Sum(nil))
    if !hmac.Equal([]byte(expected), []byte(sig)) {
        return errBadSig
    }
    return nil
}

Здесь три вещи идут не так - в порядке убывания частоты:

1. Тело парсится до подписания. Если ваш HTTP-фреймворк вызывает r.ParseForm() до того, как вы прочитаете сырое тело, тело исчезает и подпись никогда не совпадёт. Сначала читайте r.Body, потом парсите. Обработчик slash-команды Elido считывает тело в буфер и перепарсивает - это стоит одной аллокации и экономит неделю отладки.

2. Расхождение часов при проверке timestamp. Рекомендованное Slack окно защиты от replay-атак составляет 5 минут. Если часы вашего сервера отстают или спешат более чем на это значение (такое часто бывает на bare-metal без chrony), каждый подписанный запрос будет выглядеть как replay. Запустите chronyc tracking на сервере и убедитесь в Leap status: Normal.

3. Переустановка с ротированным signing secret. Именно это будит вас среди ночи. Если вы ротируете signing secret в панели Slack (Basic Information > Signing Secret > Regenerate), все существующие OAuth-установки во всех воркспейсах немедленно начинают проваливать проверку подписи. Администратор воркспейса должен переустановить приложение, чтобы получить новый handshake. Тихой ротации нет - Slack не пушит новый секрет в существующие установки.

Радиус поражения зависит от модели дистрибуции. Если ваше Slack-приложение обслуживает один воркспейс (внутреннее приложение компании), ротация - это переустановка за 90 секунд одним администратором. Если приложение находится в публичном каталоге Slack и установлено в 4000 воркспейсах, вы только что сломали их все. Выбирайте окна ротации соответственно и объявляйте о них в changelog минимум за 48 часов.

Связанный сценарий отказа: установка того же Slack-приложения в другом воркспейсе при той же браузерной сессии. Если cookies не очищены, Slack иногда возвращает токен, привязанный к неправильному команде. Выход - приватное окно или ?ignore_session=1 в URL установки. Установочный флоу Elido по адресу /dashboard/integrations/slack уже передаёт этот флаг - мы обожглись на этом в ранней Бете.

Когда Slack-бот - не лучший выбор

Slack отлично подходит для алертов с участием человека. Это не то место для высокочастотных программных событий. Если вы генерируете более ~20 событий в минуту, Slack ограничивает incoming-webhook endpoint примерно до 1 сообщения в секунду на канал, и вы начнёте терять алерты. Направляйте такие события в метрику Datadog или в обычный webhook-консьюмер, а в Slack отправляйте только сводку о превышении порога.

Второй случай, когда Slack не подходит: аудиторские следы для соответствия требованиям. Сообщения Slack изменяемы (их можно редактировать и удалять), а политика хранения управляется на уровне воркспейса. Если аудитор требует неизменяемый журнал того, кто, какую ссылку и когда сократил, - передавайте события slash-команды в хранилище данных через экспорт ClickHouse и используйте Slack только как слой уведомлений.

Для команд роста, маршрутизирующих алерты о кликах в кампаниях, Slack-бот покрывает 95% того, о чём спрашивают в /solutions/marketers. Для платформенных команд, работающих с нашим API + SDK, это один из нескольких выходов для fan-out.

Тарифы и ограничения

Интеграция с Slack доступна на любом тарифе, включая бесплатный. Оплаты за сообщения нет - лимит распространяется на сами shortlink'и и клики, которые можно посмотреть на странице тарифов. В каждом воркспейсе можно настроить до 32 правил маршрутизации (комбинации тип события x канал) - это больше, чем любая команда, с которой я общался, реально использовала.

Self-hosted установки Elido тоже работают. Вы указываете request URL Slack-приложения на свой домен, устанавливаете signing secret в окружении api-core - и всё остальное идентично. Документация по self-host описывает переменные окружения; руководство по наблюдаемости - имена метрик, чтобы вы могли строить графики задержки slash-команд и успешности доставки алертов в Grafana или Datadog.

Следующие шаги

Если вы уже пользуетесь Elido, откройте /dashboard/integrations/slack, нажмите «Подключить», выберите канал по умолчанию для каждого типа события - и готово. Установка действительно занимает 90 секунд. Если вы только оцениваете продукт, в каталоге интеграций перечислены все коннекторы и тарифы, на которых они доступны, а сравнение с Bitly показывает, как возможности Slack соотносятся с возможностями конкурентов (спойлер: у Bitly нет slash-команды).

Если вы создаёте собственного бота - скопируйте паттерн HMAC выше и соблюдайте 3000 мс тайм-аута. UX slash-команд Slack безжалостен к медленным ботам, а быстрый отклик - половина причины, по которой люди вообще их устанавливают.

Частые вопросы

Как установить Slack-бот Elido для сокращения URL?

Откройте /dashboard/integrations/slack в Elido и нажмите «Подключить». Вас перенаправят на OAuth-экран Slack - выберите воркспейс, одобрите разрешения (commands, chat:write, incoming-webhook) и примерно через 90 секунд вернётесь в Elido. При установке записывается строка токена с ключом team_id, поэтому каждый воркспейс получает собственные учётные данные.

Работает ли /shorten в приватных каналах и личных сообщениях?

Да. Slash-команды выполняются в том канале, где пользователь их вводит, включая приватные каналы и личные сообщения: Slack передаёт channel_id в подписанном payload. Elido отвечает эфемерным сообщением, видимым только вызвавшему, так что канал не засоряется при разовых сокращениях.

Как подписываются payload'ы алертов Slack?

Исходящие алерты из Elido в Slack используют URL incoming-webhook Slack, который сам по себе является bearer-секретом, привязанным к одному каналу. Входящие slash-команды из Slack в Elido проверяются с помощью HMAC SHA256 по сырому телу запроса и заголовку X-Slack-Request-Timestamp согласно схеме signing-secret Slack.

Что происходит с Slack-ботом при переустановке OAuth-приложения?

Переустановка генерирует новый bot-токен и делает старый недействительным. Signing secret ротируется только при его регенерации в панели приложения Slack - в этом случае каждый воркспейс, использующий ваш дистрибутив, должен переустановить приложение. Планируйте ротации в период низкого трафика и заранее объявляйте в #ops.

Какие типы алертов можно направлять в каналы Slack?

Сегодня доступны четыре типа событий: broken-link (на целевой странице shortlink обнаружены 4xx или 5xx), click-threshold (сохранённый порог превышен в 5-минутном окне), scan-failure (URL-сканер пометил цель как фишинг или вредоносное ПО) и new-conversion (сработало отслеживаемое конверсионное событие). Каждый алерт может направляться в отдельный канал.

Попробуйте Elido

Вставьте URL - получите короткую ссылку

Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.

Бесплатно, без регистрации · 2 в день

Попробуйте Elido

URL-сокращатель с хостингом в ЕС: собственные домены, глубокая аналитика, открытый API. Бесплатный тариф - без банковской карты.

Теги
slack url shortener
slack link shortening bot
slack short links
slack /shorten command
slack channel alerts

Читать дальше