These examples use placeholder IDs. Discover real IDs with team list, channel list, chat list, and user commands before writing to Teams.
teams auth login --device-code
teams auth doctor --output json | jq .
teams auth status --output jsonPowerShell:
teams auth login --device-code
teams auth doctor --output json | ConvertFrom-JsonTEAM_ID=$(teams team list --output json | jq -r '.data[] | select(.displayName=="Engineering") | .id')
CHANNEL_ID=$(teams channel list "$TEAM_ID" --output json | jq -r '.data[] | select(.displayName=="General") | .id')PowerShell:
$teams = teams team list --output json | ConvertFrom-Json
$teamId = ($teams.data | Where-Object displayName -eq "Engineering").id
$channels = teams channel list $teamId --output json | ConvertFrom-Json
$channelId = ($channels.data | Where-Object displayName -eq "General").idteams message send \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--body "Release 2.4.1 is deployed."HTML body:
teams message send \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--content-type html \
--body "<b>Release complete</b><br/>Version: 2.4.1"git log --oneline -5 | teams message send \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--stdincat report.html | teams message send \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--stdin \
--content-type htmlCHAT_ID=$(teams chat list --output json | jq -r '.data[0].id')
teams message list --chat "$CHAT_ID" --page-size 10 --output json |
jq '.data[] | {id, createdDateTime, messageType, bodyType: .body.contentType, bodyChars: (.body.content | length)}'This pattern avoids printing real message bodies in logs.
MESSAGE_ID=$(teams message list --team "$TEAM_ID" --channel "$CHANNEL_ID" --output json | jq -r '.data[0].id')
teams message reply \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--message-id "$MESSAGE_ID" \
--body "Acknowledged."Use a dedicated test channel.
BODY="teams-cli smoke test $(date -u +%Y-%m-%dT%H:%M:%SZ)"
SENT=$(teams message send \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--body "$BODY" \
--output json)
MESSAGE_ID=$(echo "$SENT" | jq -r '.data.id')
teams message reply \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--message-id "$MESSAGE_ID" \
--body "reply smoke test" \
--output jsonCleanup only if the signed-in user and tenant policy allow deleting messages:
teams message delete \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--message "$MESSAGE_ID" \
--output jsonprintf 'smoke test\n' | teams file upload \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--stdin \
--name teams-cli-smoke.txt \
--output jsonteams file list --team "$TEAM_ID" --channel "$CHANNEL_ID" --output json
teams file download \
--team "$TEAM_ID" \
--channel "$CHANNEL_ID" \
--file-id "$FILE_ID" \
--path ./teams-cli-smoke.txtCLIENT_CHAT_ID="<chat-id>"
cat <<'TEXT' | teams message send --chat "$CLIENT_CHAT_ID" --stdin
Daily update:
- Deployment completed
- Smoke tests passed
- Follow-up items are in the project board
TEXTteams message list --chat "$CHAT_ID" --page-size 20 --output json |
jq -r '.data[] | [.id, .createdDateTime, (.body.content // "")] | @tsv' |
while IFS=$'\t' read -r id created body; do
response=$(printf '%s\n' "$body" | ./agent-decide-response)
if [ -n "$response" ]; then
teams message send --chat "$CHAT_ID" --body "$response" --output json
fi
doneAdd deduplication before using an agent loop in production. Store processed message IDs.
if ! output=$(teams message send --chat "$CHAT_ID" --body "Hello" --output json); then
code=$?
case "$code" in
3) teams auth login --device-code ;;
4) echo "Permission denied; check consent and chat membership" >&2 ;;
6) sleep 30 ;;
*) echo "$output" >&2 ;;
esac
fiPowerShell:
$env:TEAMS_CLI_TENANT_ID = "<tenant-id>"
$env:TEAMS_CLI_CLIENT_ID = "<client-id>"
teams auth login --device-codeCommand Prompt:
set TEAMS_CLI_TENANT_ID=<tenant-id>
set TEAMS_CLI_CLIENT_ID=<client-id>
teams auth login --device-code