The Adaptive Card surfaces Apus sends to Teams, the Graph-backed roster lookup, and the target formats that address them.
Member info action
Apus exposes a Graph-backed member-info action for Microsoft Teams so agents and automations can resolve verified roster details for a configured conversation.
Requirements:
ChannelSettings.Read.GroupandTeamMember.Read.GroupRSC permissions (already in the recommended manifest).
The action is available whenever Graph credentials are configured; there is no separate channels.msteams.actions.memberInfo toggle.
Standard-channel lookups return the matching team-roster identity, display name, email, and roles.
In the current DM or group chat, the action can return the trusted sender's stable user ID.
Private/shared-channel and non-current chat member lookups require additional roster permissions
and are rejected by the default permission baseline.
For member-info and search in the message tool, use channelId to select the
conversation. The Graph <team-id>/<channel-id> form identifies a Teams channel:
{
action: "member-info",
channel: "msteams",
channelId: "<team-id>/<channel-id>",
userId: "<user-id>",
}
search uses the same channelId filter with a query instead of userId.
Omitting the filter uses the current conversation when its Graph route is
available. For the current channel, its bare 19:...@thread.tacv2 ID and
conversation:19:...@thread.tacv2 form reuse that same Graph route. Use the full
Graph form to select another channel. The selected conversation must still
satisfy the configured access policy and the action's membership requirements.
Native approval cards
Microsoft Teams can deliver exec and plugin approval requests as Adaptive Cards in the originating conversation. Each card describes the requested command or plugin action and provides only the decisions allowed for that request, such as Approve once, Always allow, and Deny. After a decision or expiration, Apus updates the original card with its final status.
Enable the existing top-level approval forwarding settings for each approval type you want to receive:
{
approvals: {
exec: { enabled: true, mode: "session" },
plugin: { enabled: true, mode: "session" },
},
channels: {
msteams: {
allowFrom: ["00000000-0000-0000-0000-000000000000"],
},
},
}
approvals.exec and approvals.plugin are independent; enabling one does not enable the other. Native card delivery also requires a configured Teams bot and at least one approver resolved from channels.msteams.allowFrom or channels.msteams.defaultTo. Approvers must be stable AAD object IDs; display names, email addresses, group entries, and conversation IDs do not grant approval access. Apus checks the clicking user's AAD object ID before resolving the request.
No Teams-specific approval configuration is required. The existing /approve <id> <decision> command remains available as a text fallback when native delivery is unavailable. For forwarding modes and supported decisions, see Approval forwarding to chat channels.
Polls (Adaptive Cards)
Apus sends Teams polls as Adaptive Cards (there is no native Teams poll API).
- CLI:
apus message poll --channel msteams --target conversation:<id> --poll-question "..." --poll-option "..." --poll-option "...". - Votes are recorded by the gateway in Apus plugin-state SQLite under
state/apus.sqlite. - For existing
msteams-polls.jsonfiles, runapus doctor --fixon 2026.9.5 before upgrading to latest. See Upgrading very old versions. - The gateway must stay online to record votes.
- Polls do not auto-post result summaries, and there is no poll-results CLI.
Revoking a scheduled job's message permission stops a poll that has not yet been submitted. A poll already submitted to Teams retains its accepted ID and normal vote tracking while the run finishes.
Presentation cards
Send semantic presentation payloads to Teams users or conversations using the message tool, CLI, or normal reply delivery. Apus renders them as Teams Adaptive Cards from the generic presentation contract.
The presentation parameter accepts semantic blocks. When presentation is provided, the message text is optional. Buttons render as Adaptive Card submit or URL actions. Select menus are not native in the Teams renderer, so Apus downgrades them to readable text before delivery.
Agent tool:
{
action: "send",
channel: "msteams",
target: "user:<id>",
presentation: {
title: "Hello",
blocks: [{ type: "text", text: "Hello!" }],
},
}
CLI:
apus message send --channel msteams \
--target "conversation:19:abc...@thread.tacv2" \
--presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}'
For target format details, see Target formats below.
Target formats
MSTeams targets use prefixes to distinguish between users and conversations:
| Target type | Format | Example |
|---|---|---|
| User (by ID) | user:<aad-object-id> |
user:40a1a0ed-4ff2-4164-a219-55518990c197 |
| User (by name) | user:<display-name> |
user:John Smith (requires Graph API) |
| Group/channel | conversation:<conversation-id> |
conversation:19:abc123...@thread.tacv2 |
| Group/channel (raw) | <conversation-id> |
19:abc123...@thread.tacv2, 19:...@unq.gbl.spaces, or a bare a:/8:orgid:/29: Bot Framework id |
CLI examples:
# Send to a user by ID
apus message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
# Send to a user by display name (triggers Graph API lookup)
apus message send --channel msteams --target "user:John Smith" --message "Hello"
# Send to a group chat or channel
apus message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"
# Send a presentation card to a conversation
apus message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
--presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello"}]}'
Agent tool examples:
{
action: "send",
channel: "msteams",
target: "user:John Smith",
message: "Hello!",
}
{
action: "send",
channel: "msteams",
target: "conversation:19:abc...@thread.tacv2",
presentation: {
title: "Hello",
blocks: [{ type: "text", text: "Hello" }],
},
}
Without the user: prefix, names default to group or team resolution. Always use user: when targeting people by display name.
Proactive messaging
- Proactive messages are only possible after a user has interacted, because Apus stores conversation references at that point.
- See /gateway/configuration for
dmPolicyand allowlist gating.