UNPKG

@microsoft/agents-hosting-extensions-teams

Version:

Microsoft 365 Agents SDK for JavaScript. Teams extensions

345 lines (324 loc) 12.4 kB
/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' import { Activity, ChannelAccount } from '@microsoft/agents-activity' import { TeamsChannelAccount } from '../activity-extensions/teamsChannelAccount' import { MeetingInfo } from '../meeting/meetingInfo' import { MeetingNotification } from '../meeting/meetingNotification' import { MeetingNotificationResponse } from '../meeting/meetingNotificationResponse' import { ChannelInfo } from '../activity-extensions/channelInfo' import { TeamsChannelData } from '../activity-extensions' import { BatchFailedEntriesResponse, BatchOperationStateResponse, CancelOperationResponse, TeamDetails, TeamsBatchOperationResponse, TeamsMember, TeamsPagedMembersResult } from './teamsConnectorClient.types' import { ConnectorClient } from '@microsoft/agents-hosting' interface ConversationList { conversations?: ChannelInfo[] } /** * A client for interacting with Microsoft Teams APIs. * Extends the ConnectorClient class to provide Teams-specific functionalities. */ export class TeamsConnectorClient { private axiosInstance: AxiosInstance constructor (private client: ConnectorClient) { this.axiosInstance = client.axiosInstance } /** * Retrieves a member from a conversation or team. * @param activity - The activity containing the context. * @param userId - The ID of the user to retrieve. * @returns A TeamsChannelAccount representing the member. */ static async getMember (activity: Activity, userId: string): Promise<TeamsChannelAccount> { const teamsChannelData = activity.channelData as TeamsChannelData const teamId = teamsChannelData.team?.id if (teamId) { return await this.getTeamMember(activity, teamId, userId) } else { const conversationId = (activity.conversation != null) && activity.conversation.id ? activity.conversation.id : undefined return await this.getMemberInternal(activity, conversationId, userId) } } /** * Retrieves the team ID from an activity. * @param activity - The activity containing the context. * @returns The team ID as a string. * @throws Error if the activity is missing or invalid. */ private static getTeamId (activity: any): string { if (!activity) { throw new Error('Missing activity parameter') } const channelData = activity.channelData as TeamsChannelData const team = channelData && (channelData.team != null) ? channelData.team : undefined const teamId = (team != null) && typeof team.id === 'string' ? team.id : undefined return teamId as string } /** * Retrieves a member from a team. * @param activity - The activity containing the context. * @param teamId - The ID of the team. * @param userId - The ID of the user to retrieve. * @returns A TeamsChannelAccount representing the team member. * @throws Error if the teamId or userId is missing. */ static async getTeamMember (activity: any, teamId?: string, userId?: string) { const t = teamId || this.getTeamId(activity) if (!t) { throw new Error('This method is only valid within the scope of a MS Teams Team.') } if (!userId) { throw new Error('userId is required') } return await this.getMemberInternal(activity, t, userId) } /** * Retrieves a member from a conversation. * @param conversationId - The ID of the conversation. * @param userId - The ID of the user to retrieve. * @returns A ChannelAccount representing the conversation member. */ public async getConversationMember (conversationId: string, userId: string): Promise<ChannelAccount> { const config: AxiosRequestConfig = { method: 'get', url: `/v3/conversations/${conversationId}/members/${userId}`, headers: { 'Content-Type': 'application/json' } } const response: AxiosResponse = await this.axiosInstance(config) return response.data } /** * Retrieves a member from a conversation or team internally. * @param activity - The activity containing the context. * @param conversationId - The ID of the conversation. * @param userId - The ID of the user to retrieve. * @returns A ChannelAccount representing the member. * @throws Error if the conversationId is missing or the client is unavailable. */ static async getMemberInternal ( activity: any, conversationId: string | undefined, userId: string ): Promise<ChannelAccount> { if (!conversationId) { throw new Error('conversationId is required') } const client : ConnectorClient = activity.turnState?.get(activity.adapter.ConnectorClientKey) if (!client) { throw new Error('Client is not available in the context.') } const teamMember: ChannelAccount = await client.getConversationMember(conversationId, userId) return teamMember } /** * Retrieves paged members of a conversation. * @param conversationId - The ID of the conversation. * @param pageSize - The number of members per page. * @param continuationToken - The token for pagination. * @returns A TeamsPagedMembersResult containing the paged members. */ public async getConversationPagedMember (conversationId: string, pageSize: number, continuationToken: string): Promise<TeamsPagedMembersResult> { const config: AxiosRequestConfig = { method: 'get', url: `v3/conversations/${conversationId}/pagedMembers`, params: { pageSize, continuationToken } } const response = await this.axiosInstance(config) return response.data } /** * Fetches the list of channels in a team. * @param teamId - The ID of the team. * @returns An array of ChannelInfo objects representing the channels. */ public async fetchChannelList (teamId: string): Promise<ChannelInfo[]> { const config: AxiosRequestConfig = { method: 'get', url: `v3/teams/${teamId}/conversations` } const response = await this.axiosInstance(config) const convList: ConversationList = response.data return convList.conversations || [] } /** * Fetches the details of a team. * @param teamId - The ID of the team. * @returns A TeamDetails object containing the team details. */ public async fetchTeamDetails (teamId: string): Promise<TeamDetails> { const config: AxiosRequestConfig = { method: 'get', url: `v3/teams/${teamId}` } const response = await this.axiosInstance(config) return response.data } /** * Fetches information about a meeting participant. * @param meetingId - The ID of the meeting. * @param participantId - The ID of the participant. * @param tenantId - The tenant ID. * @returns A string containing participant information. */ public async fetchMeetingParticipant (meetingId: string, participantId: string, tenantId: string): Promise<string> { const config: AxiosRequestConfig = { method: 'get', url: `v1/meetings/${meetingId}/participants/${participantId}`, params: { tenantId } } const response = await this.axiosInstance(config) return response.data } /** * Fetches information about a meeting. * @param meetingId - The ID of the meeting. * @returns A MeetingInfo object containing the meeting information. */ public async fetchMeetingInfo (meetingId: string): Promise<MeetingInfo> { const config: AxiosRequestConfig = { method: 'get', url: `v1/meetings/${meetingId}` } const response = await this.axiosInstance(config) return response.data } /** * Sends a notification to a meeting. * @param meetingId - The ID of the meeting. * @param notification - The notification to send. * @returns A MeetingNotificationResponse object containing the response. */ public async sendMeetingNotification (meetingId: string, notification: MeetingNotification): Promise<MeetingNotificationResponse> { const config: AxiosRequestConfig = { method: 'post', url: `v1/meetings/${meetingId}/notification`, data: notification } const response = await this.axiosInstance(config) return response.data } /** * Sends a message to a list of users. * @param activity - The activity to send. * @param tenantId - The tenant ID. * @param members - The list of members to send the message to. * @returns A TeamsBatchOperationResponse object containing the response. */ public async sendMessageToListOfUsers (activity: Activity, tenantId: string, members: TeamsMember[]): Promise<TeamsBatchOperationResponse> { const content = { activity, members, tenantId } const config: AxiosRequestConfig = { method: 'post', url: 'v3/batch/conversation/users', data: content } const response = await this.axiosInstance(config) return response.data } /** * Sends a message to all users in a tenant. * @param activity - The activity to send. * @param tenantId - The tenant ID. * @returns A TeamsBatchOperationResponse object containing the response. */ public async sendMessageToAllUsersInTenant (activity: Activity, tenantId: string): Promise<TeamsBatchOperationResponse> { const content = { activity, tenantId } const config: AxiosRequestConfig = { method: 'post', url: 'v3/batch/conversation/tenant', data: content } const response = await this.axiosInstance(config) return response.data } /** * Sends a message to all users in a team. * @param activity - The activity to send. * @param tenantId - The tenant ID. * @param teamId - The team ID. * @returns A TeamsBatchOperationResponse object containing the response. */ public async sendMessageToAllUsersInTeam (activity: Activity, tenantId: string, teamId: string): Promise<TeamsBatchOperationResponse> { const content = { activity, tenantId, teamId } const config: AxiosRequestConfig = { method: 'post', url: 'v3/batch/conversation/team', data: content } const response = await this.axiosInstance(config) return response.data } /** * Sends a message to a list of channels. * @param activity - The activity to send. * @param tenantId - The tenant ID. * @param members - The list of members to send the message to. * @returns A TeamsBatchOperationResponse object containing the response. */ public async sendMessageToListOfChannels (activity: Activity, tenantId: string, members: TeamsMember[]): Promise<TeamsBatchOperationResponse> { const content = { activity, tenantId, members } const config: AxiosRequestConfig = { method: 'post', url: 'v3/batch/conversation/channels', data: content } const response = await this.axiosInstance(config) return response.data } /** * Retrieves the state of a batch operation. * @param operationId - The ID of the operation. * @returns A BatchOperationStateResponse object containing the operation state. */ public async getOperationState (operationId: string): Promise<BatchOperationStateResponse> { const config: AxiosRequestConfig = { method: 'get', url: `v3/batch/conversation/${operationId}` } const response = await this.axiosInstance(config) return response.data } /** * Retrieves the failed entries of a batch operation. * @param operationId - The ID of the operation. * @returns A BatchFailedEntriesResponse object containing the failed entries. */ public async getFailedEntries (operationId: string): Promise<BatchFailedEntriesResponse> { const config: AxiosRequestConfig = { method: 'get', url: `v3/batch/conversation/failedentries/${operationId}` } const response = await this.axiosInstance(config) return response.data } /** * Cancels a batch operation. * @param operationId - The ID of the operation. * @returns A CancelOperationResponse object containing the response. */ public async cancelOperation (operationId: string): Promise<CancelOperationResponse> { const config: AxiosRequestConfig = { method: 'delete', url: `v3/batch/conversation/${operationId}` } const response = await this.axiosInstance(config) return response.data } }