Skip to content

feat(mattermost): Add directory adapter for channel/user name resolution #19264

@oskarmodig

Description

@oskarmodig

Problem

Agents must use 26-character Mattermost channel IDs to send messages (e.g. target: "uygoe35x3idumqo5mb5jfbqrdh"). This is error-prone and requires maintaining external ID mappings.

Solution

Add a directory adapter to the Mattermost channel plugin that enables name-based resolution. Agents can now use target: "infra" or target: "off-topic" and core's built-in resolveMessagingTarget handles the lookup.

Changes

src/mattermost/directory.ts (new, ~130 lines)

  • listMattermostDirectoryGroups — scans ALL enabled bot accounts (deduplicated by token) and returns public + private channels. Multi-account scanning is essential because private channels are only visible to bots that are members.
  • listMattermostDirectoryPeers — returns team members via first available client (all bots see the same user list).
  • Graceful error handling: invalid/expired tokens are skipped with debug logging.

src/channel.ts (+15 lines)

  • Added directory property with listGroups/listGroupsLive/listPeers/listPeersLive. Core's DirectoryCache handles caching at the resolver level.

src/normalize.ts (3 lines changed)

  • normalizeMattermostMessagingTarget: bare names (no prefix) now return undefined instead of channel:${name}, allowing fallthrough to directory lookup.
  • looksLikeMattermostTargetId: stricter regex — /^[a-z0-9]{26}$/i for standard IDs + /^[a-z0-9]{26}__[a-z0-9]{26}$/i for DM channel IDs. Previously /^[a-z0-9]{8,}$/i matched channel names like "infra" as IDs.

Known limitations

  • per_page=200 for channel/member listing — covers most instances but very large ones may see incomplete results.
  • Peers use first team only (teams[0]) — multi-team setups would need iteration.

Testing

Tested live with 19 bot accounts, successfully resolves both public and private channel names.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions