SKILL.md

  1---
  2name: exo-teams
  3description: CLI tool for Microsoft Teams internal API - no admin consent required. Use when working with Teams messages, DMs, assignments, class materials, file uploads, calendar, or deadlines. Trigger on "teams", "exo-teams", "microsoft teams", "assignments", "class materials", "send message teams", "teams files", "uni automation", "deadlines", or "submit assignment".
  4argument-hint: "[command or 'help']"
  5---
  6
  7# exo-teams
  8
  9Go CLI for Microsoft Teams using the internal (desktop app) API. No admin consent, no Graph API registration, no IT department. Tokens stored at `~/.exo-teams/`.
 10
 11## Auth
 12
 13Five token scopes, all acquired via device code OAuth (`exo-teams auth`):
 14
 15| Token | Used for |
 16|-------|----------|
 17| skype | messaging, activity feed, read receipts |
 18| chatsvcagg | teams/channels/chats listing |
 19| teams | middle tier ops |
 20| graph | calendar, files, search, user profiles |
 21| assignments | education assignments via `assignments.onenote.com` (bypasses admin consent) |
 22
 23Tokens auto-refresh. Check status with `exo-teams whoami`.
 24
 25**Skypetoken quirk**: messaging uses `Authentication: skypetoken=<value>` header, NOT `Authorization: Bearer`. The skypetoken is derived from the raw skype JWT via an authz exchange endpoint.
 26
 27## Quick Start
 28
 29```bash
 30exo-teams auth                              # device code login
 31exo-teams whoami                            # token status + account info
 32exo-teams list-teams                        # see all teams, channels, and channel IDs
 33exo-teams list-chats                        # all DMs and group chats with IDs
 34```
 35
 36## Command Reference
 37
 38See `references/commands.md` for full flag docs. Quick map:
 39
 40| Command | What it does |
 41|---------|-------------|
 42| `auth [--import\|--refresh]` | login, import from fossteams, or force refresh |
 43| `whoami` | account info + per-token expiry |
 44| `list-teams` | all teams + channels with IDs |
 45| `list-chats` | all DMs + group chats with IDs |
 46| `get-messages <search>` | channel messages by name search or ID |
 47| `get-chat <search>` | DM/group chat messages |
 48| `send <conv-id> <message>` | send text to any conversation |
 49| `send-file <conv-id> --file <path>` | upload file to OneDrive, send share link |
 50| `new-dm <name> <message>` | find user by name, open DM, send message |
 51| `files <team-search>` | list SharePoint files |
 52| `upload <team-search> --path --file` | upload to SharePoint |
 53| `download <team-search> --path` | download from SharePoint |
 54| `calendar [--days N]` | upcoming calendar events (default 7 days) |
 55| `assignments [--classes]` | all assignments with submission status |
 56| `submit <class> <assignment> --file` | submit a file to an assignment |
 57| `deadlines` | pending assignments sorted by due date |
 58| `unread` | unread conversations at a glance |
 59| `activity` | activity feed (mentions, replies, reactions) |
 60| `search <query>` | search messages + files |
 61| `mark-read <conv-id>` | mark conversation as read |
 62
 63All commands accept `--json` for machine-readable output.
 64
 65## Data Discovery Guide
 66
 67See `references/data-discovery.md` for full patterns. Critical ones:
 68
 69**Find team/channel IDs:**
 70```bash
 71exo-teams list-teams
 72# Output: == Team Name == / #channel-name   19:abc123@thread.tacv2
 73```
 74
 75**Find chat/DM IDs:**
 76```bash
 77exo-teams list-chats
 78# Output: * [DM]  Person Name   19:abc@unq.gbl.spaces
 79```
 80
 81**Find your user ID:**
 82```bash
 83exo-teams whoami --json
 84# or: exo-teams new-dm "their name" "" (prints found user ID to stderr)
 85```
 86
 87**Find assignment IDs:**
 88```bash
 89exo-teams assignments --classes     # list class IDs
 90exo-teams assignments --json        # includes classId, id, submissionId
 91```
 92
 93## Key Gotchas
 94
 95- Conversation IDs contain `:` and `@` - they are always URL-encoded internally, but pass them raw to CLI args
 96- `chat.hidden` is unreliable - most active DMs have `hidden=true`, use `list-chats` not hidden filter
 97- `annotationsSummary.emotions` returns either `[]any` or `map[string]any` depending on message
 98- File upload to DMs uses OneDrive ("Microsoft Teams Chat Files" folder) + share link, not AMS
 99- SharePoint upload (team files) uses Graph PUT to `/groups/{id}/drive/root:/{path}:/content`
100- 423 on OneDrive upload means file is locked - tool auto-retries with deduped name up to 5 times
101- Activity feed reads from a special conversation ID `48:notifications`
102- Unread status comes from `isRead` field on Chat which can be bool or null - null means read
103- Search uses Graph `/search/query` with `message` + `driveItem` entity types (no Chat.Read needed)
104- `assignments` command uses `assignments.onenote.com` API not Graph `/education/` (bypasses admin consent)
105
106## Common Patterns
107
108```bash
109# Check what needs submitting today
110exo-teams deadlines
111
112# Read a specific channel
113exo-teams get-messages "Academic Writing" --replies --count 50
114
115# Read all messages ever (paginated)
116exo-teams get-messages "General" --all
117
118# Messages after a date
119exo-teams get-messages "General" --since 2026-03-01
120
121# Send a file to a DM
122exo-teams send-file "19:abc@unq.gbl.spaces" --file report.pdf --message "here it is"
123
124# Multi-file send
125exo-teams send-file "19:abc@unq.gbl.spaces" --file a.pdf --file b.docx
126
127# Download class material
128exo-teams files "Academic Writing" --drive "Class Materials"
129exo-teams download "Academic Writing" --path "Class Materials/week1.pdf" --drive "Class Materials"
130
131# Submit assignment
132exo-teams submit "Academic Writing" "Essay 1" --file essay.docx
133
134# Export channel to JSON
135exo-teams get-messages "General" --all --json > general.json
136```
137
138## Scripting Patterns
139
140See `references/scripting.md` for full automation examples including:
141- Fetch all pending assignments + download class materials
142- Monitor channel for new messages (poll loop)
143- Export full conversation to markdown
144- Bulk-send files across multiple conversations