import { TeamsClient } from '@/platforms/teams/client' import { TeamsListener } from '@/platforms/teams/listener' import type { AuthHint, AuthIO, PlatformAdapter, UnifiedChannel, UnifiedMessage, Workspace } from './types' export class TeamsAdapter implements PlatformAdapter { readonly name = 'Teams' private client: TeamsClient | null = null private listener: TeamsListener | null = null private teamId: string | null = null private teamName: string | null = null private teams: Workspace[] = [] async login(): Promise { this.client = new TeamsClient() await this.client.login() const teams = await this.client.listTeams() if (!teams.length) throw new Error('No Teams found') this.teams = teams.map((t) => ({ id: t.id, name: t.name })) this.teamId = teams[0].id this.teamName = teams[0].name } async getChannels(): Promise { this.ensureClient() const channels = await this.client!.listChannels(this.teamId!) return channels.map((ch) => ({ id: ch.id, name: ch.name, parentId: this.teamId!, })) } async getMessages(channelId: string, limit = 50): Promise { this.ensureClient() const messages = await this.client!.getMessages(this.teamId!, channelId, limit) return messages .map((msg) => ({ id: msg.id, channelId, author: msg.author.displayName || 'unknown', content: this.stripHtml(msg.content), timestamp: msg.timestamp, })) .reverse() } async sendMessage(channelId: string, text: string): Promise { this.ensureClient() await this.client!.sendMessage(this.teamId!, channelId, text) } async startListening(onMessage: (msg: UnifiedMessage) => void): Promise { this.ensureClient() const listener = new TeamsListener(this.client!) listener.on('message', (message) => { onMessage({ id: message.id, channelId: message.chatId, author: message.author.displayName, content: message.content, timestamp: message.timestamp, }) }) await listener.start() this.listener = listener } stopListening(): void { this.listener?.stop() this.listener = null } async getWorkspaces(): Promise { return this.teams } async switchWorkspace(teamId: string): Promise { const team = this.teams.find((t) => t.id === teamId) if (!team) throw new Error(`Team ${teamId} not found`) this.teamId = team.id this.teamName = team.name } getCurrentWorkspace(): Workspace | null { if (!this.teamId || !this.teamName) return null return { id: this.teamId, name: this.teamName } } getAuthHint(): AuthHint { return { command: 'agent-teams auth extract', description: 'Log in to the Microsoft Teams desktop app, then run the command below to extract credentials.', } } async authenticate(io: AuthIO): Promise { io.print('Extracting credentials from Microsoft Teams desktop app...') await this.login() } private ensureClient(): void { if (!this.client || !this.teamId) throw new Error('Not logged in') } private stripHtml(html: string): string { return html .replace(/<[^>]*>/g, '') .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, "'") .replace(/\s+/g, ' ') .trim() } }