Developer and self-hosted

Mattermost

Статус: загружаемый плагин (токен бота + события WebSocket). Поддерживаются каналы, приватные каналы, групповые и личные сообщения. Mattermost — самостоятельно размещаемая платформа для обмена сообщениями в командах (mattermost.com).

Установка

Реестр npm

bash
openclaw plugins install @openclaw/mattermost

Локальная рабочая копия

bash
openclaw plugins install ./path/to/local/mattermost-plugin

Подробности: Плагины

Быстрая настройка

  • Убедитесь, что плагин доступен

    Установите @openclaw/mattermost с помощью приведённой выше команды, затем перезапустите Gateway, если он уже запущен.

  • Создайте бота Mattermost

    Создайте учётную запись бота Mattermost, скопируйте токен бота и добавьте бота в команды и каналы, которые он должен читать.

  • Скопируйте базовый URL

    Скопируйте базовый URL Mattermost (например, https://chat.example.com). Завершающий /api/v4 удаляется автоматически.

  • Настройте OpenClaw и запустите Gateway

    Минимальная конфигурация:

    json5
    {  channels: {    mattermost: {      enabled: true,      botToken: "mm-token",      baseUrl: "https://chat.example.com",      dmPolicy: "pairing",    },  },}

    Неинтерактивный вариант:

    bash
    openclaw channels add --channel mattermost --bot-token <token> --http-url https://chat.example.com
  • Нативные слеш-команды

    Нативные слеш-команды включаются явно. Когда они включены, OpenClaw регистрирует слеш-команды oc_* во всех командах, в которых состоит бот, и получает обратные вызовы POST на HTTP-сервере Gateway.

    json5
    {  channels: {    mattermost: {      commands: {        native: true,        nativeSkills: true,        callbackPath: "/api/channels/mattermost/command",        // Используйте, если Mattermost не может напрямую подключиться к Gateway (обратный прокси/публичный URL).        callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",      },    },  },}

    Регистрируемые команды: /oc_status, /oc_model, /oc_models, /oc_new, /oc_help, /oc_think, /oc_reasoning, /oc_verbose, /oc_queue. При использовании nativeSkills: true команды Skills также регистрируются как /oc_<skill>.

    Примечания о поведении
    • native и nativeSkills по умолчанию имеют значение "auto", при котором они отключены для Mattermost. Явно задайте для них значение true.
    • callbackPath по умолчанию имеет значение /api/channels/mattermost/command.
    • Если callbackUrl не указан, OpenClaw определяет http://<gateway.customBindHost or localhost>:<gateway.port, default 18789><callbackPath>. Для адресов привязки с подстановочным знаком (0.0.0.0, ::) используется резервное значение localhost.
    • При настройке нескольких учётных записей commands можно задать на верхнем уровне или в channels.mattermost.accounts.<id>.commands (значения учётной записи переопределяют поля верхнего уровня).
    • Существующие слеш-команды с таким же триггером, созданные другими интеграциями, остаются без изменений (при регистрации они пропускаются); команды, созданные ботом, обновляются или создаются заново при изменении URL обратного вызова.
    • Обратные вызовы команд проверяются с помощью отдельных токенов команд, возвращаемых Mattermost при регистрации команд oc_* в OpenClaw.
    • Перед принятием каждого обратного вызова OpenClaw обновляет текущие данные регистрации команд Mattermost, поэтому устаревшие токены удалённых или повторно созданных слеш-команд перестают приниматься без перезапуска Gateway.
    • Проверка обратного вызова завершается отказом, если API Mattermost не может подтвердить, что команда по-прежнему актуальна; неудачные проверки ненадолго кэшируются, параллельные запросы объединяются, а запуск новых запросов ограничивается по частоте отдельно для каждой команды, чтобы ограничить нагрузку от повторного воспроизведения.
    • Обратные вызовы слеш-команд завершаются отказом, если регистрация не удалась, запуск был частичным или токен обратного вызова не совпадает с зарегистрированным токеном определённой команды (токен, действительный для одной команды, не может пройти вышестоящую проверку для другой команды).
    • Принятые обратные вызовы подтверждаются эфемерным ответом «Обработка...»; фактический ответ поступает обычным сообщением.
    Требование доступности

    Конечная точка обратного вызова должна быть доступна с сервера Mattermost.

    • Не задавайте для callbackUrl значение localhost, если Mattermost не работает на том же хосте или в том же сетевом пространстве имён, что и OpenClaw.
    • Не задавайте для callbackUrl базовый URL Mattermost, если этот URL не перенаправляет /api/channels/mattermost/command в OpenClaw через обратный прокси.
    • Для быстрой проверки используйте curl https://<gateway-host>/api/channels/mattermost/command; запрос GET должен вернуть 405 Method Not Allowed от OpenClaw, а не 404.
    Список разрешённых исходящих адресов Mattermost

    Если обратные вызовы направляются на приватные, внутренние адреса или адреса tailnet, настройте ServiceSettings.AllowedUntrustedInternalConnections в Mattermost, включив в него хост или домен обратного вызова.

    Используйте записи хостов или доменов, а не полные URL.

    • Правильно: gateway.tailnet-name.ts.net
    • Неправильно: https://gateway.tailnet-name.ts.net

    Переменные среды (учётная запись по умолчанию)

    Если вы предпочитаете переменные среды, задайте их на хосте Gateway:

    • MATTERMOST_BOT_TOKEN=...
    • MATTERMOST_URL=https://chat.example.com

    Режимы чата

    Mattermost автоматически отвечает на личные сообщения. Поведение в каналах управляется параметром chatmode:

    oncall (по умолчанию)

    Отвечать в каналах только при @упоминании.

    onmessage

    Отвечать на каждое сообщение в канале.

    onchar

    Отвечать, когда сообщение начинается с префикса-триггера.

    Пример конфигурации:

    json5
    {  channels: {    mattermost: {      chatmode: "onchar",      oncharPrefixes: [">", "!"], // по умолчанию    },  },}

    Примечания:

    • onchar по-прежнему отвечает на явные @упоминания.
    • channels.mattermost.requireMention по-прежнему учитывается, но предпочтителен chatmode. Настройки groups.<channelId>.requireMention для отдельных каналов имеют приоритет над обоими параметрами.
    • После отправки ботом видимого ответа в ветке канала последующие сообщения в той же ветке получают ответы без нового @упоминания или префикса onchar, поэтому многоходовые разговоры в ветке могут продолжаться непрерывно. Участие запоминается на 7 дней после последнего ответа бота в этой ветке и сохраняется после перезапусков Gateway. Это не затрагивает ветки, которые бот только просматривал; чтобы снова требовалось явное упоминание, начните новое сообщение верхнего уровня.

    Ветки и сеансы

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

    • off (по умолчанию): отвечать в ветке, только если входящее сообщение уже находится в ней.
    • first: для сообщений верхнего уровня в каналах или группах начинать ветку под таким сообщением и направлять разговор в сеанс, привязанный к ветке.
    • all и batched: сейчас в Mattermost ведут себя так же, как first, поскольку после создания корневого сообщения ветки последующие фрагменты и медиафайлы продолжают отправляться в ту же ветку.
    • Для личных сообщений по умолчанию используется off, даже если задан replyToMode.

    Используйте channels.mattermost.replyToModeByChatType, чтобы переопределить режим для чатов direct, group или channel. Задайте direct, чтобы включить ветки для личных сообщений:

    • off (по умолчанию): личные сообщения остаются без веток в одном непрерывном сеансе.
    • first, all или batched: каждое личное сообщение верхнего уровня начинает ветку Mattermost, связанную с новым независимым сеансом.
    json5
    {  channels: {    mattermost: {      replyToMode: "all",      replyToModeByChatType: {        direct: "first",      },    },  },}

    Примечания:

    • Сеансы, привязанные к ветке, используют идентификатор исходного сообщения в качестве корня ветки.
    • first и all в настоящее время эквивалентны, поскольку после создания корневого сообщения ветки последующие фрагменты и медиафайлы продолжают отправляться в ту же ветку.
    • Переопределения для типов чатов имеют приоритет над replyToMode. Без переопределения direct существующие развёртывания сохраняют плоские личные сообщения без веток.

    Управление доступом (личные сообщения)

    • По умолчанию: channels.mattermost.dmPolicy = "pairing" (неизвестные отправители получают код сопряжения). Другие значения: allowlist, open, disabled.
    • Способы одобрения:
      • openclaw pairing list mattermost
      • openclaw pairing approve mattermost &lt;CODE&gt;
    • Открытые личные сообщения: channels.mattermost.dmPolicy="open" вместе с channels.mattermost.allowFrom=["*"] (схема конфигурации требует подстановочный знак).
    • channels.mattermost.allowFrom принимает идентификаторы пользователей (рекомендуется) и записи accessGroup:<name>. См. Группы доступа.

    Каналы (группы)

    • По умолчанию: channels.mattermost.groupPolicy = "allowlist" (требуется упоминание).
    • Разрешите отправителей с помощью channels.mattermost.groupAllowFrom (рекомендуются идентификаторы пользователей).
    • channels.mattermost.groupAllowFrom принимает записи accessGroup:<name>. См. Группы доступа.
    • Переопределения требований к упоминаниям для отдельных каналов находятся в channels.mattermost.groups.<channelId>.requireMention, а значение по умолчанию — в channels.mattermost.groups["*"].requireMention.
    • Сопоставление @username изменяемо и включается только при channels.mattermost.dangerouslyAllowNameMatching: true.
    • Открытые каналы: channels.mattermost.groupPolicy="open" (требуется упоминание).
    • Порядок разрешения: channels.mattermost.groupPolicy, затем channels.defaults.groupPolicy, затем "allowlist".
    • Примечание о среде выполнения: если раздел channels.mattermost полностью отсутствует, при проверках групп среда выполнения безопасно отклоняет доступ согласно groupPolicy="allowlist" (даже если задан channels.defaults.groupPolicy) и однократно записывает предупреждение в журнал.

    Пример:

    json5
    {  channels: {    mattermost: {      groupPolicy: "open",      groups: {        "*": { requireMention: true },        "team-channel-id": { requireMention: false },      },    },  },}

    Цели исходящей доставки

    Используйте следующие форматы целей с openclaw message send или Cron/Webhook:

    Цель Куда доставляется
    channel:<id> В канал по идентификатору
    channel:<name> или #channel-name В канал по имени с поиском среди команд, в которых состоит бот
    user:<id> или mattermost:<id> В личные сообщения с этим пользователем
    @username В личные сообщения (имя пользователя определяется через API Mattermost)

    Исходящие сообщения поддерживают не более одного вложения на сообщение; отправляйте несколько файлов отдельными сообщениями.

    Повторная попытка для канала личных сообщений

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

    Используйте channels.mattermost.dmChannelRetry, чтобы настроить это поведение глобально для плагина Mattermost, или channels.mattermost.accounts.<id>.dmChannelRetry для одной учётной записи. Значения по умолчанию:

    json5
    {  channels: {    mattermost: {      dmChannelRetry: {        maxRetries: 3,        initialDelayMs: 1000,        maxDelayMs: 10000,        timeoutMs: 30000,      },    },  },}

    Примечания:

    • Это относится только к созданию канала личной переписки (/api/v4/channels/direct), а не к каждому вызову API Mattermost.
    • Повторные попытки используют экспоненциальную задержку с внесением случайности и применяются при временных сбоях, таких как ограничения частоты запросов, ответы 5xx, а также сетевые ошибки или ошибки тайм-аута.
    • Клиентские ошибки 4xx, кроме 429, считаются постоянными и не вызывают повторных попыток.

    Потоковая передача предпросмотра

    Mattermost передаёт рассуждения, действия инструментов и частичный текст ответа в черновую публикацию предпросмотра, которая окончательно обновляется на месте, когда итоговый ответ можно безопасно отправить. В режиме partial предпросмотр обновляется в публикации с тем же идентификатором, а не засоряет канал отдельными сообщениями для каждого фрагмента. В режиме block предпросмотр переключается между завершённым текстом и блоками действий инструментов, поэтому предыдущие блоки остаются видимыми как отдельные публикации, а не перезаписываются следующим блоком. Итоговые сообщения с медиафайлами или ошибками отменяют ожидающие изменения предпросмотра и используют обычную доставку вместо отправки ненужной публикации предпросмотра.

    Потоковая передача предпросмотра включена по умолчанию в режиме partial. Настраивается через channels.mattermost.streaming.mode (устаревшие скалярные/логические значения streaming переносятся командой openclaw doctor --fix):

    json5
    {  channels: {    mattermost: {      streaming: { mode: "partial" }, // отключено | частично | блоками | прогресс    },  },}
    Режимы потоковой передачи
    • partial (по умолчанию): одна публикация предпросмотра, которая редактируется по мере формирования ответа, а затем окончательно обновляется полным ответом.
    • block переключает предпросмотр между завершённым текстом и блоками действий инструментов, поэтому каждый блок остаётся видимым как отдельная публикация, а не перезаписывается на месте. Параллельные и последовательные обновления инструментов используют текущую публикацию с действиями инструментов.
    • progress показывает предпросмотр состояния во время формирования и публикует итоговый ответ только после завершения.
    • off отключает потоковую передачу предпросмотра. При streaming.block.enabled: true завершённые блоки ассистента всё равно доставляются как обычные блочные ответы (отдельные публикации), а не как одна объединённая итоговая публикация.
    Примечания о поведении потоковой передачи
    • Если поток невозможно окончательно обновить на месте (например, публикация была удалена во время передачи), OpenClaw в качестве запасного варианта отправляет новую итоговую публикацию, чтобы ответ не потерялся.
    • Данные, содержащие только рассуждения, не публикуются в канале, включая текст, поступающий как цитата > Thinking. Установите /reasoning on, чтобы видеть рассуждения в других интерфейсах; итоговая публикация Mattermost содержит только ответ.
    • Матрицу сопоставления каналов см. в разделе Потоковая передача.

    Реакции (инструмент сообщений)

    • Используйте message action=react с channel=mattermost.
    • messageId — идентификатор публикации Mattermost.
    • emoji принимает такие названия, как thumbsup или :+1: (двоеточия необязательны).
    • Установите remove=true (логическое значение), чтобы удалить реакцию.
    • События добавления и удаления реакций передаются как системные события в соответствующий сеанс агента с применением тех же проверок политик личных переписок и групп, что и для сообщений.

    Примеры:

    text
    message action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsupmessage action=react channel=mattermost target=channel:<channelId> messageId=<postId> emoji=thumbsup remove=true

    Конфигурация:

    • channels.mattermost.actions.reactions: включение или отключение действий с реакциями (по умолчанию true).
    • Переопределение для отдельной учётной записи: channels.mattermost.accounts.<id>.actions.reactions.

    Интерактивные кнопки (инструмент сообщений)

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

    Кнопки поступают из семантических данных presentation (в обычных ответах агента и в message action=send). OpenClaw отображает кнопки со значениями как интерактивные кнопки Mattermost, сохраняет URL-кнопки видимыми в тексте сообщения и преобразует меню выбора в удобочитаемый текст.

    text
    message action=send channel=mattermost target=channel:<channelId> presentation={"blocks":[{"type":"buttons","buttons":[{"label":"Да","value":"yes"},{"label":"Нет","value":"no"}]}]}

    Поля кнопок представления:

    labelstringrequired

    Отображаемая метка (псевдоним: text).

    valuestring

    Значение, возвращаемое при нажатии и используемое как идентификатор действия (псевдонимы: callback_data, callbackData). Обязательно для нажимаемой кнопки, если не задано url.

    urlstring

    Кнопка-ссылка; отображается в теле сообщения как текст label: url, а не как интерактивная кнопка.

    style"primary" | "secondary" | "success" | "danger"

    Стиль кнопки. Для неподдерживаемых значений Mattermost применяет стандартное оформление.

    Чтобы сообщить о поддержке кнопок в системном промпте агента, добавьте inlineButtons в возможности канала:

    json5
    {  channels: {    mattermost: {      capabilities: ["inlineButtons"],    },  },}

    Когда пользователь нажимает кнопку:

  • Проверка доступа

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

  • Замена кнопок подтверждением

    Все кнопки заменяются строкой подтверждения (например, «✓ Да выбрано пользователем @user»).

  • Агент получает выбранное значение

    Агент получает выбранное значение как входящее сообщение (а также системное событие) и отвечает.

  • Примечания по реализации
    • Обратные вызовы кнопок используют проверку HMAC-SHA256 (автоматически, настройка не требуется).
    • При нажатии заменяется весь блок вложения, поэтому все кнопки удаляются одновременно — частичное удаление невозможно.
    • Идентификаторы действий, содержащие дефисы или символы подчёркивания, автоматически очищаются (ограничение маршрутизации Mattermost).
    • Нажатия, в которых action_id не соответствует действию в исходной публикации, отклоняются с 403 («Неизвестное действие»).
    Конфигурация и доступность
    • channels.mattermost.capabilities: массив строк возможностей. Добавьте "inlineButtons", чтобы включить описание инструмента кнопок в системном промпте агента.
    • channels.mattermost.interactions.callbackBaseUrl: необязательный внешний базовый URL для обратных вызовов кнопок (например, https://gateway.example.com). Используйте его, если Mattermost не может напрямую обратиться к Gateway по адресу привязки.
    • В конфигурациях с несколькими учётными записями это же поле можно задать в channels.mattermost.accounts.<id>.interactions.callbackBaseUrl.
    • Если interactions.callbackBaseUrl не указан, OpenClaw формирует URL обратного вызова из gateway.customBindHost + gateway.port (по умолчанию 18789), а затем использует http://localhost:<port> как запасной вариант. Путь обратного вызова: /mattermost/interactions/<accountId>.
    • Правило доступности: URL обратного вызова кнопки должен быть доступен с сервера Mattermost. localhost работает только тогда, когда Mattermost и OpenClaw запущены на одном хосте или в одном сетевом пространстве имён.
    • channels.mattermost.interactions.allowedSourceIps: список разрешённых исходных IP-адресов для обратных вызовов кнопок. Если он не задан, принимаются только источники с адресами обратной петли (127.0.0.1, ::1), поэтому удалённый сервер Mattermost необходимо добавить в этот список, иначе его нажатия будут отклоняться с 403. При работе за обратным прокси также задайте gateway.trustedProxies, чтобы реальный IP-адрес клиента определялся по перенаправленным заголовкам.
    • Если адрес обратного вызова является частным, находится в tailnet или во внутренней сети, добавьте его хост или домен в ServiceSettings.AllowedUntrustedInternalConnections Mattermost.

    Прямая интеграция с API (внешние скрипты)

    Внешние скрипты и Webhook могут публиковать кнопки напрямую через REST API Mattermost, не используя инструмент агента message. По возможности используйте buildButtonAttachments() из плагина; при отправке необработанного JSON соблюдайте следующие правила:

    Структура данных:

    json5
    {  channel_id: "<channelId>",  message: "Выберите вариант:",  props: {    attachments: [      {        actions: [          {            id: "mybutton01", // только буквы и цифры — см. ниже            type: "button", // обязательно, иначе нажатия молча игнорируются            name: "Одобрить", // отображаемая метка            style: "primary", // необязательно: "default", "primary", "danger"            integration: {              url: "https://gateway.example.com/mattermost/interactions/default",              context: {                action_id: "mybutton01", // должен совпадать с идентификатором кнопки                action: "approve",                // ... любые пользовательские поля ...                _token: "<hmac>", // см. раздел HMAC ниже              },            },          },        ],      },    ],  },}

    Создание токена HMAC

    Gateway проверяет нажатия кнопок с помощью HMAC-SHA256. Внешние скрипты должны создавать токены, соответствующие логике проверки Gateway:

  • Получите секрет из токена бота

    HMAC-SHA256(key="openclaw-mattermost-interactions", data=botToken), в шестнадцатеричном представлении.

  • Создайте объект контекста

    Создайте объект контекста со всеми полями, кроме _token.

  • Сериализуйте с отсортированными ключами

    Выполните сериализацию с рекурсивно отсортированными ключами и без пробелов (Gateway также канонизирует вложенные объекты и создаёт компактный JSON).

  • Подпишите данные

    HMAC-SHA256(key=secret, data=serializedContext)

  • Добавьте токен

    Добавьте полученный шестнадцатеричный дайджест в контекст как _token.

  • Пример на Python:

    python
     secret = hmac.new(    b"openclaw-mattermost-interactions",    bot_token.encode(), hashlib.sha256).hexdigest() ctx = {"action_id": "mybutton01", "action": "approve"}payload = json.dumps(ctx, sort_keys=True, separators=(",", ":"))token = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest() context = {**ctx, "_token": token}
    Распространенные ошибки HMAC
    • json.dumps в Python по умолчанию добавляет пробелы ({"key": "val"}). Используйте separators=(",", ":"), чтобы результат соответствовал компактному выводу JavaScript ({"key":"val"}).
    • Всегда подписывайте все поля контекста (кроме _token). Gateway удаляет _token, а затем подписывает все оставшиеся данные. Подписание только части полей приводит к незаметному сбою проверки.
    • Используйте sort_keys=True: Gateway сортирует ключи перед подписанием, а Mattermost может изменить порядок полей контекста при сохранении полезной нагрузки.
    • Создавайте секрет на основе токена бота (детерминированно), а не из случайных байтов. Секрет должен совпадать в процессе, создающем кнопки, и в Gateway, выполняющем проверку.

    Адаптер каталога

    Плагин Mattermost включает адаптер каталога, который разрешает имена каналов и пользователей через API Mattermost. Это позволяет использовать цели #channel-name и @username в openclaw message send, а также при доставке через Cron/Webhook.

    Настройка не требуется: адаптер использует токен бота из конфигурации учетной записи.

    Несколько учетных записей

    Mattermost поддерживает несколько учетных записей в channels.mattermost.accounts:

    json5
    {  channels: {    mattermost: {      accounts: {        default: { name: "Primary", botToken: "mm-token", baseUrl: "https://chat.example.com" },        alerts: { name: "Alerts", botToken: "mm-token-2", baseUrl: "https://alerts.example.com" },      },    },  },}

    Значения учетной записи переопределяют поля верхнего уровня; channels.mattermost.defaultAccount определяет, какая учетная запись используется, если она не указана.

    Устранение неполадок

    Нет ответов в каналах

    Убедитесь, что бот добавлен в канал, и упомяните его (oncall), используйте префикс-триггер (onchar) или задайте chatmode: "onmessage".

    Ошибки аутентификации или нескольких учетных записей
    • Проверьте токен бота, базовый URL-адрес и убедитесь, что учетная запись включена.
    • При использовании нескольких учетных записей переменные среды применяются только к учетной записи default.
    • Для частных Mattermost-хостов и хостов в локальной сети требуется network.dangerouslyAllowPrivateNetwork: true (защита от SSRF по умолчанию блокирует частные IP-адреса).
    Нативные слеш-команды не работают
    • Unauthorized: invalid command token.: OpenClaw не принял токен обратного вызова. Типичные причины:
      • регистрация слеш-команды завершилась с ошибкой или при запуске была выполнена лишь частично
      • обратный вызов направляется не в тот Gateway или не в ту учетную запись
      • в Mattermost остались старые команды, указывающие на предыдущую цель обратного вызова
      • Gateway был перезапущен без повторной активации слеш-команд
    • Если нативные слеш-команды перестали работать, проверьте журналы на наличие mattermost: failed to register slash commands или mattermost: native slash commands enabled but no commands could be registered.
    • Если callbackUrl не указан, а в журналах появляется предупреждение о том, что обратный вызов разрешился в адрес обратной петли, например http://localhost:18789/..., этот URL-адрес, вероятно, доступен только тогда, когда Mattermost работает на том же хосте или в том же сетевом пространстве имен, что и OpenClaw. Вместо него явно задайте доступный извне commands.callbackUrl.
    Проблемы с кнопками
    • Кнопки отображаются как белые прямоугольники или не отображаются вовсе: данные кнопок имеют неверный формат. Для каждой кнопки представления требуются label и value (кнопки без одного из этих значений отбрасываются).
    • Кнопки отображаются, но нажатия не срабатывают: убедитесь, что Gateway доступен с сервера Mattermost, IP-адрес сервера Mattermost включен в channels.mattermost.interactions.allowedSourceIps (без этого принимается только адрес обратной петли), а ServiceSettings.AllowedUntrustedInternalConnections включает хост обратного вызова для частных целей.
    • При нажатии кнопки возвращается ошибка 404: значение id кнопки, вероятно, содержит дефисы или символы подчеркивания. Маршрутизатор действий Mattermost не работает с идентификаторами, содержащими неалфавитно-цифровые символы. Используйте только [a-zA-Z0-9].
    • Gateway регистрирует rejected callback source: нажатие поступило с IP-адреса, не входящего в interactions.allowedSourceIps. Добавьте сервер Mattermost или входной прокси в список разрешенных адресов и задайте gateway.trustedProxies при работе за обратным прокси.
    • Gateway регистрирует invalid _token: HMAC не совпадает. Убедитесь, что подписываются все поля контекста (а не только их часть), ключи сортируются и используется компактный JSON (без пробелов). См. раздел о HMAC выше.
    • Gateway регистрирует missing _token in context: поле _token отсутствует в контексте кнопки. Убедитесь, что оно включено при формировании полезной нагрузки интеграции.
    • Gateway отклоняет нажатие с ошибкой Unknown action: context.action_id не соответствует ни одному значению id действия в публикации. Задайте для обоих одинаковое нормализованное значение.
    • Агент не предлагает кнопки: добавьте capabilities: ["inlineButtons"] в конфигурацию канала Mattermost.

    Связанные материалы

    Was this useful?
    On this page

    On this page