feat(platform): add Mattermost bot support#7369
Conversation
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
MattermostMessageEvent.send_streaming, thegeneratoris fully consumed to build and send buffered output, then passed tosuper().send_streaming(...)even though it is already exhausted; consider either not forwarding tosuper()or restructuring so the base implementation processes the original stream. - The adapter attaches
temporary_file_pathstoAstrBotMessageviasetattr; if this pattern is expected long-term, it may be more robust to add an explicit field or helper on the message/event type rather than relying on a dynamic attribute.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `MattermostMessageEvent.send_streaming`, the `generator` is fully consumed to build and send buffered output, then passed to `super().send_streaming(...)` even though it is already exhausted; consider either not forwarding to `super()` or restructuring so the base implementation processes the original stream.
- The adapter attaches `temporary_file_paths` to `AstrBotMessage` via `setattr`; if this pattern is expected long-term, it may be more robust to add an explicit field or helper on the message/event type rather than relying on a dynamic attribute.
## Individual Comments
### Comment 1
<location path="astrbot/core/platform/sources/mattermost/mattermost_event.py" line_range="30-39" />
<code_context>
+ await self.client.send_message_chain(self.get_session_id(), message)
+ await super().send(message)
+
+ async def send_streaming(
+ self,
+ generator: AsyncGenerator,
+ use_fallback: bool = False,
+ ):
+ if not use_fallback:
+ buffer = None
+ async for chain in generator:
+ if not buffer:
+ buffer = chain
+ else:
+ buffer.chain.extend(chain.chain)
+ if not buffer:
+ return None
+ buffer.squash_plain()
+ await self.send(buffer)
+ return await super().send_streaming(generator, use_fallback)
+
</code_context>
<issue_to_address>
**issue (bug_risk):** The non-fallback streaming branch buffers all chunks and then calls `super().send_streaming` on an exhausted generator, which adds complexity without effect.
In the `not use_fallback` branch you fully consume `generator` into a single buffered `MessageChain`, send that once, and then call `super().send_streaming(generator, use_fallback)` on an already-exhausted async generator. That call won’t stream anything and only obscures the control flow. Consider either (1) buffering and sending once, then returning, or (2) delegating directly to `super().send_streaming` without buffering, depending on the behavior you want.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
There was a problem hiding this comment.
Code Review
This pull request introduces a Mattermost platform adapter, enabling AstrBot to integrate with Mattermost via its API and WebSocket. The implementation includes a new client for handling authentication, file operations, and message delivery, as well as an adapter for processing events and converting messages. Review feedback focuses on performance enhancements, such as offloading blocking file I/O to separate threads using asyncio.to_thread, pre-compiling regex for bot mentions, and optimizing the duplicate message detection logic. Additionally, adding return type hints was suggested to improve code quality.
7101ab0 to
0349ada
Compare
There was a problem hiding this comment.
Pull request overview
Adds a native Mattermost platform adapter (REST + WebSocket) so AstrBot can receive posts, wake on mentions, reply in-session, and upload/download attachments.
Changes:
- Introduces a Mattermost adapter, event wrapper, and API client to handle inbound/outbound messaging and attachments.
- Registers the new platform in the platform manager and default config template/metadata.
- Updates README platform list to include Mattermost.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds Mattermost to the supported platforms list. |
| astrbot/core/platform/sources/mattermost/mattermost_event.py | Adds Mattermost-specific AstrMessageEvent for sending + fallback streaming behavior + group lookup. |
| astrbot/core/platform/sources/mattermost/mattermost_adapter.py | Implements the Mattermost Platform adapter (WS listen loop, message conversion, mention parsing, de-dup). |
| astrbot/core/platform/sources/mattermost/client.py | Implements REST/WS client helpers and attachment upload/download + chain sending. |
| astrbot/core/platform/sources/mattermost/init.py | Adds the package module for the new platform source. |
| astrbot/core/platform/manager.py | Registers Mattermost in the platform loader switch. |
| astrbot/core/config/default.py | Adds default Mattermost platform template and config metadata entries. |
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Resolve #6009
Modifications / 改动点
This is NOT a breaking change. / 这不是一个破坏性变更。
Added a native Mattermost platform adapter using the official REST and WebSocket APIs.
Supported incoming posts, mention-based wakeup, session replies, and attachment upload/download.
Registered Mattermost in platform loading, default config metadata, and the README platform list.
Screenshots or Test Results / 运行截图或测试结果
uv run ruff format .uv run ruff check .basedpyright diagnostics on astrbot/core/platform/sources/mattermostuv run pytest tests/test_mattermost_adapter.py -q(covers Mattermost mention parsing / attachment smoke tests)Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by Sourcery
Add a native Mattermost platform adapter using Mattermost REST and WebSocket APIs and wire it into the platform system and documentation.
New Features:
Enhancements:
Documentation: