-
-
Notifications
You must be signed in to change notification settings - Fork 69.5k
feat(msteams): Implement read and search message actions for Teams channel #40865
Description
Summary
The message tool's read and search actions are defined in the action name enum (CHANNEL_MESSAGE_ACTION_NAMES) and fully implemented for Discord (readMessages, searchMessages in discord-actions-messaging.ts), but the Microsoft Teams channel plugin only declares ["poll"] as its supported action.
This means agents connected via Teams cannot read channel message history or search messages — they can only send and react. The agent is blind to any channel activity not directly routed as an inbound message.
Current State
What exists:
CHANNEL_MESSAGE_ACTION_NAMESincludes"read"and"search"(source)- Discord fully implements both:
readMessages— reads channel history withlimit,before,after,aroundparamssearchMessages— searches by content, author, channel with filtering- (source)
What's missing:
- MSTeams
listActionsreturns only["poll"](source) - No
readMessagesorsearchMessageshandler in the TeamshandleAction - The Graph API endpoints needed (
/teams/{teamId}/channels/{channelId}/messagesand/chats/{chatId}/messages) are well-documented and available
Proposed Implementation
1. Add read and search to Teams listActions:
```typescript
listActions: ({ cfg }) => {
// ...existing enabled check...
return ["poll", "read", "search"] satisfies ChannelMessageActionName[];
},
```
2. Implement readMessages in handleAction:
Using Microsoft Graph API:
- Channel messages:
GET /teams/{teamId}/channels/{channelId}/messages?$top={limit} - Chat messages:
GET /chats/{chatId}/messages?$top={limit} - Support
limit,before/afterpagination (Graph uses$skipTokenor@odata.nextLink)
3. Implement searchMessages in handleAction:
Using Microsoft Graph Search API:
POST /search/querywithentityTypes: ["chatMessage"]- Filter by
channelIdentity,from, date range
4. Normalize response format:
Match the Discord implementation's response shape for consistency:
```typescript
return jsonResult({
ok: true,
messages: messages.map((msg) => ({
id: msg.id,
author: msg.from?.user?.displayName,
authorId: msg.from?.user?.id,
timestamp: msg.createdDateTime,
text: msg.body?.content,
attachments: msg.attachments?.map(a => ({ name: a.name, contentType: a.contentType })),
replyTo: msg.replyToId,
})),
});
```
Graph API Permissions Required
The bot registration likely needs:
ChannelMessage.Read.All(application) — for channel messagesChat.Read(delegated) orChat.Read.All(application) — for chat messagesChatMessage.Read— for search
These may already be consented depending on the bot's existing Graph permissions. Worth documenting which are needed in the setup guide.
Why This Matters
- Parity with Discord — Discord agents can read and search; Teams agents cannot. This is the most-requested enterprise channel.
- Agent workspace integration — Teams is often the primary workspace for enterprise users. An agent that can only write but not read operates half-blind.
- Reduces webhook dependency — On-demand read eliminates the need to wire every channel with real-time event forwarding for the agent to have awareness.
- Heartbeat/monitoring workflows — Agents doing proactive monitoring sweeps need to check channels for activity without requiring every message to be individually routed.
Environment
- OpenClaw version: 2026.3.7
- Channel: msteams
- Existing actions available: send, react, poll
- Missing: read, search
Related
- Discord implementation:
src/agents/tools/discord-actions-messaging.ts(lines 220-260, 473-520) - Action names enum:
src/channels/plugins/message-action-names.ts - Teams channel plugin:
extensions/msteams/src/channel.ts