Skip to content

feat(channels): add Mattermost channel support#1288

Closed
lmorchard wants to merge 1 commit intosipeed:mainfrom
lmorchard:lmorchard/mattermost
Closed

feat(channels): add Mattermost channel support#1288
lmorchard wants to merge 1 commit intosipeed:mainfrom
lmorchard:lmorchard/mattermost

Conversation

@lmorchard
Copy link
Copy Markdown

📝 Description

Add Mattermost channel using WebSocket API v4 for receiving events and REST API v4 for sending. No external SDK — uses gorilla/websocket (existing dependency) and net/http.

Features:

  • Thread-aware replies: channel messages auto-thread, DMs stay flat
  • Auto-reconnect with exponential backoff (5s-60s)
  • Message splitting at 4000 chars via channels.SplitMessage
  • Bot @mention stripping via configurable username field
  • Proper error classification using ClassifySendError/ClassifyNetError
  • MediaSender: file uploads via /api/v4/files
  • TypingCapable: typing indicator support
  • MessageEditor: edit existing posts
  • PlaceholderCapable: "Thinking..." placeholder that gets edited

Config:

  • channels.mattermost.enabled: bool
  • channels.mattermost.url: server URL
  • channels.mattermost.token: bot access token
  • channels.mattermost.username: bot username for mention stripping
  • channels.mattermost.reply_in_thread: auto-thread in channels (default true)
  • channels.mattermost.allow_from: user ID allowlist
  • channels.mattermost.group_trigger: group chat trigger config

Includes:

  • Unit tests (TestNewMattermostChannel, TestParseChatID, TestBuildWSURL, TestStripBotMention)
  • README.md updates (chat apps table, collapsible setup guide)
  • Chinese docs at docs/channels/mattermost/README.zh.md (AI-generated, may need native speaker review)

🗣️ Type of Change

  • ✨ New feature (non-breaking change which adds functionality)

🤖 AI Code Generation

  • 🛠️ Mostly AI-generated (AI draft, Human verified/modified)

🔗 Related Issue

  • No existing issue. Mattermost was the most-requested missing channel in our evaluation of picoclaw vs openclaw/nanobot (both of which support it).

📚 Technical Context (Skip for Docs)

  • Reference URL: feat(channels): add Mattermost channel support evolv3ai/nanobot#1 (nanobot Mattermost implementation, similar approach)
  • Reasoning: Mattermost is a popular open-source team chat platform (self-hosted Slack alternative) with no current picoclaw support. Implementation uses raw WebSocket + REST API to avoid adding dependencies, following the same pattern as the existing Slack channel.

🧪 Test Environment

  • Hardware: GCE e2-standard-2 (2 vCPU, 8GB RAM), Proxmox VM (2 vCPU, 512MB RAM)
  • OS: Debian 13
  • Model/Provider: Gemini 2.5 Pro via LiteLLM/Vertex AI
  • Channels: Mattermost (self-hosted, v10+)

☑️ Checklist

  • My code/docs follow the style of this project.
  • I have performed a self-review of my own changes.
  • I have updated the documentation accordingly.
  • make check passes locally.
  • AI-generated code has been reviewed line-by-line and tested in a real environment.

Copilot AI review requested due to automatic review settings March 9, 2026 22:20
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 9, 2026

CLA assistant check
All committers have signed the CLA.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Mattermost chat channel to PicoClaw, integrating with Mattermost’s WebSocket API v4 (inbound events) and REST API v4 (sending messages, editing posts, typing indicators, and file uploads), plus associated configuration and documentation updates.

Changes:

  • Introduces pkg/channels/mattermost with WS receive loop, REST send/edit/upload, and unit tests.
  • Extends configuration (MattermostConfig + defaults) and wires channel registration/initialization.
  • Updates README and adds Chinese setup documentation for the new channel.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pkg/config/defaults.go Adds default values for channels.mattermost config.
pkg/config/config.go Adds MattermostConfig and integrates it into ChannelsConfig.
pkg/channels/mattermost/mattermost.go Implements Mattermost channel (WS receive, REST send/edit/upload, typing, placeholder).
pkg/channels/mattermost/mattermost_test.go Adds unit tests for config validation and helper functions.
pkg/channels/mattermost/init.go Registers the Mattermost channel factory.
pkg/channels/manager.go Enables Mattermost channel initialization based on config.
cmd/picoclaw/internal/gateway/helpers.go Ensures the Mattermost channel package is imported for registration.
README.md Adds Mattermost to supported chat apps list and setup guide.
docs/channels/mattermost/README.zh.md Adds Chinese documentation for Mattermost channel setup/config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from 55dc987 to 76137ba Compare March 10, 2026 16:55
Copilot AI review requested due to automatic review settings March 10, 2026 16:59
@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from 76137ba to 3d19097 Compare March 10, 2026 16:59
Copilot AI review requested due to automatic review settings March 10, 2026 17:19
@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from 23f5351 to 560df1a Compare March 10, 2026 17:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alexhoshina
Copy link
Copy Markdown
Collaborator

make lintplz

Copilot AI review requested due to automatic review settings March 11, 2026 04:34
@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from e54385e to b68efbd Compare March 11, 2026 04:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from b68efbd to e45c73c Compare March 11, 2026 04:48
Copilot AI review requested due to automatic review settings March 11, 2026 16:59
@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from e45c73c to b43efcb Compare March 11, 2026 16:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from b43efcb to b148285 Compare March 11, 2026 17:26

// "D" = direct message, "G" = group direct message; both bypass group-trigger
// filtering and threading, matching the intended "DMs stay flat" behavior.
isDM := d.ChannelType == "D" || d.ChannelType == "G"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why set group direct messages as direct messages as well? What is the purpose behind this design?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, this is how other channels handle this too - group DMs are the same as single-user DMs with regard to when threading and addressing are used. But, I think that's because Slack & Discord don't distinguish between types of DMs

https://github.com/sipeed/picoclaw/blob/main/pkg/channels/slack/slack.go#L313-L314
https://github.com/sipeed/picoclaw/blob/main/pkg/channels/discord/discord.go#L347-L349

But, since Mattermost does distinguish between single-user DM and group DM - we could treat a group DM as an ad-hoc channel and switch over to threading and requiring addressing there. Would just be inconsistent with other channels

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see~ Thank you for your answer~

Copilot AI review requested due to automatic review settings March 12, 2026 17:12
@lmorchard lmorchard force-pushed the lmorchard/mattermost branch from b148285 to f5a307a Compare March 12, 2026 17:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Add Mattermost channel using WebSocket API v4 for receiving events and
REST API v4 for sending. No external SDK — uses gorilla/websocket
(existing dependency) and net/http.

Features:
- Thread-aware replies: channel messages auto-thread, DMs stay flat
- Auto-reconnect with exponential backoff (5s-60s)
- Message splitting at 4000 chars via channels.SplitMessage
- Bot @mention stripping via configurable username field
- Proper error classification using ClassifySendError/ClassifyNetError
- MediaSender: file uploads via /api/v4/files
- TypingCapable: typing indicator support
- MessageEditor: edit existing posts
- PlaceholderCapable: "Thinking..." placeholder that gets edited

Config:
  channels.mattermost.enabled: bool
  channels.mattermost.url: server URL
  channels.mattermost.token: bot access token
  channels.mattermost.username: bot username for mention stripping
  channels.mattermost.reply_in_thread: auto-thread in channels (default true)
  channels.mattermost.allow_from: user ID allowlist
  channels.mattermost.group_trigger: group chat trigger config

Includes:
- Unit tests (TestNewMattermostChannel, TestParseChatID, TestBuildWSURL,
  TestStripBotMention)
- README.md updates (chat apps table, collapsible setup guide)
- Chinese docs at docs/channels/mattermost/README.zh.md (AI-generated,
  may need native speaker review)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sipeed-bot
Copy link
Copy Markdown

sipeed-bot bot commented Mar 28, 2026

@lmorchard Hi! This PR has had no activity for over 2 weeks, so I'm closing it for now to keep things tidy. If it's still relevant, feel free to reopen it anytime and we'll pick it back up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: channel domain: config go Pull requests that update go code type: enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants