Skip to content

Commit 901b06a

Browse files
port: [#4527][#6655] Implementation of Teams batch APIs (#4535)
* add teams batch operations * update teamsInfo logic * add unit tests for batch operations * fix retry logic * apply code feedback * Fix lint issue --------- Co-authored-by: JhontSouth <jhonatan.sandoval@southworks.com>
1 parent 843c847 commit 901b06a

File tree

12 files changed

+1568
-6
lines changed

12 files changed

+1568
-6
lines changed

libraries/botbuilder/etc/botbuilder.api.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@ import { AppBasedLinkQuery } from 'botbuilder-core';
1111
import { AppCredentials } from 'botframework-connector';
1212
import { AttachmentData } from 'botbuilder-core';
1313
import { AuthenticationConfiguration } from 'botframework-connector';
14+
import { BatchFailedEntriesResponse } from 'botbuilder-core';
15+
import { BatchOperationResponse } from 'botbuilder-core';
16+
import { BatchOperationStateResponse } from 'botbuilder-core';
1417
import { BotAdapter } from 'botbuilder-core';
1518
import { BotConfigAuth } from 'botbuilder-core';
1619
import { BotFrameworkAuthentication } from 'botframework-connector';
1720
import { BotFrameworkClient } from 'botbuilder-core';
1821
import { BotFrameworkSkill } from 'botbuilder-core';
1922
import { BotState } from 'botbuilder-core';
23+
import { CancelOperationResponse } from 'botframework-connector';
2024
import { ChannelAccount } from 'botbuilder-core';
2125
import { ChannelInfo } from 'botbuilder-core';
2226
import { ClaimsIdentity } from 'botframework-connector';
@@ -78,6 +82,7 @@ import { TeamInfo } from 'botbuilder-core';
7882
import { TeamsChannelAccount } from 'botbuilder-core';
7983
import { TeamsMeetingInfo } from 'botbuilder-core';
8084
import { TeamsMeetingParticipant } from 'botbuilder-core';
85+
import { TeamsMember } from 'botbuilder-core';
8186
import { TeamsPagedMembersResult } from 'botbuilder-core';
8287
import { TenantInfo } from 'botbuilder-core';
8388
import { TokenApiClient } from 'botframework-connector';
@@ -460,11 +465,14 @@ export function teamsGetTenant(activity: Activity): TenantInfo | null;
460465

461466
// @public
462467
export class TeamsInfo {
468+
static cancelOperation(context: TurnContext, operationId: string): Promise<CancelOperationResponse>;
469+
static getFailedEntries(context: TurnContext, operationId: string): Promise<BatchFailedEntriesResponse>;
463470
static getMeetingInfo(context: TurnContext, meetingId?: string): Promise<TeamsMeetingInfo>;
464471
static getMeetingParticipant(context: TurnContext, meetingId?: string, participantId?: string, tenantId?: string): Promise<TeamsMeetingParticipant>;
465472
static getMember(context: TurnContext, userId: string): Promise<TeamsChannelAccount>;
466473
// @deprecated
467474
static getMembers(context: TurnContext): Promise<TeamsChannelAccount[]>;
475+
static getOperationState(context: TurnContext, operationId: string): Promise<BatchOperationStateResponse>;
468476
static getPagedMembers(context: TurnContext, pageSize?: number, continuationToken?: string): Promise<TeamsPagedMembersResult>;
469477
static getPagedTeamMembers(context: TurnContext, teamId?: string, pageSize?: number, continuationToken?: string): Promise<TeamsPagedMembersResult>;
470478
static getTeamChannels(context: TurnContext, teamId?: string): Promise<ChannelInfo[]>;
@@ -473,6 +481,10 @@ export class TeamsInfo {
473481
// @deprecated
474482
static getTeamMembers(context: TurnContext, teamId?: string): Promise<TeamsChannelAccount[]>;
475483
static sendMeetingNotification(context: TurnContext, notification: MeetingNotification, meetingId?: string): Promise<MeetingNotificationResponse>;
484+
static sendMessageToAllUsersInTeam(context: TurnContext, activity: Activity, tenantId: string, teamId: string): Promise<BatchOperationResponse>;
485+
static sendMessageToAllUsersInTenant(context: TurnContext, activity: Activity, tenantId: string): Promise<BatchOperationResponse>;
486+
static sendMessageToListOfChannels(context: TurnContext, activity: Activity, tenantId: string, members: TeamsMember[]): Promise<BatchOperationResponse>;
487+
static sendMessageToListOfUsers(context: TurnContext, activity: Activity, tenantId: string, members: TeamsMember[]): Promise<BatchOperationResponse>;
476488
static sendMessageToTeamsChannel(context: TurnContext, activity: Activity, teamsChannelId: string, botAppId?: string): Promise<[ConversationReference, string]>;
477489
}
478490

libraries/botbuilder/src/teamsInfo.ts

Lines changed: 170 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,17 @@ import {
2424
Channels,
2525
MeetingNotification,
2626
MeetingNotificationResponse,
27+
TeamsMember,
28+
BatchOperationResponse,
29+
BatchOperationStateResponse,
30+
BatchFailedEntriesResponse,
2731
} from 'botbuilder-core';
28-
import { ConnectorClient, TeamsConnectorClient, TeamsConnectorModels } from 'botframework-connector';
32+
import {
33+
CancelOperationResponse,
34+
ConnectorClient,
35+
TeamsConnectorClient,
36+
TeamsConnectorModels,
37+
} from 'botframework-connector';
2938

3039
import { BotFrameworkAdapter } from './botFrameworkAdapter';
3140
import { CloudAdapter } from './cloudAdapter';
@@ -364,6 +373,166 @@ export class TeamsInfo {
364373
return await this.getTeamsConnectorClient(context).teams.sendMeetingNotification(meetingId, notification);
365374
}
366375

376+
/**
377+
* Sends a message to the provided users in the list of Teams members.
378+
*
379+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
380+
* @param activity The activity to send.
381+
* @param tenantId The tenant ID.
382+
* @param members The list of users recipients for the message.
383+
* @returns Promise with operationId.
384+
*/
385+
static async sendMessageToListOfUsers(
386+
context: TurnContext,
387+
activity: Activity,
388+
tenantId: string,
389+
members: TeamsMember[]
390+
): Promise<BatchOperationResponse> {
391+
if (!activity) {
392+
throw new Error('activity is required.');
393+
}
394+
if (!tenantId) {
395+
throw new Error('tenantId is required.');
396+
}
397+
if (!members || members.length == 0) {
398+
throw new Error('members list is required.');
399+
}
400+
401+
return await this.getTeamsConnectorClient(context).teams.sendMessageToListOfUsers(activity, tenantId, members);
402+
}
403+
404+
/**
405+
* Sends a message to all the users in a tenant.
406+
*
407+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
408+
* @param activity The activity to send.
409+
* @param tenantId The tenant ID.
410+
* @returns Promise with operationId.
411+
*/
412+
static async sendMessageToAllUsersInTenant(
413+
context: TurnContext,
414+
activity: Activity,
415+
tenantId: string
416+
): Promise<BatchOperationResponse> {
417+
if (!activity) {
418+
throw new Error('activity is required.');
419+
}
420+
if (!tenantId) {
421+
throw new Error('tenantId is required.');
422+
}
423+
424+
return await this.getTeamsConnectorClient(context).teams.sendMessageToAllUsersInTenant(activity, tenantId);
425+
}
426+
427+
/**
428+
* Sends a message to all the users in a team.
429+
*
430+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
431+
* @param activity The activity to send.
432+
* @param tenantId The tenant ID.
433+
* @param teamId The team ID.
434+
* @returns Promise with operationId.
435+
*/
436+
static async sendMessageToAllUsersInTeam(
437+
context: TurnContext,
438+
activity: Activity,
439+
tenantId: string,
440+
teamId: string
441+
): Promise<BatchOperationResponse> {
442+
if (!activity) {
443+
throw new Error('activity is required.');
444+
}
445+
if (!tenantId) {
446+
throw new Error('tenantId is required.');
447+
}
448+
if (!teamId) {
449+
throw new Error('teamId is required.');
450+
}
451+
452+
return await this.getTeamsConnectorClient(context).teams.sendMessageToAllUsersInTeam(
453+
activity,
454+
tenantId,
455+
teamId
456+
);
457+
}
458+
459+
/**
460+
* Sends a message to the provided list of Teams channels.
461+
*
462+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
463+
* @param activity The activity to send.
464+
* @param tenantId The tenant ID.
465+
* @param members The list of channels recipients for the message.
466+
* @returns Promise with operationId.
467+
*/
468+
static async sendMessageToListOfChannels(
469+
context: TurnContext,
470+
activity: Activity,
471+
tenantId: string,
472+
members: TeamsMember[]
473+
): Promise<BatchOperationResponse> {
474+
if (!activity) {
475+
throw new Error('activity is required.');
476+
}
477+
if (!tenantId) {
478+
throw new Error('tenantId is required.');
479+
}
480+
if (!members || members.length == 0) {
481+
throw new Error('members list is required.');
482+
}
483+
484+
return await this.getTeamsConnectorClient(context).teams.sendMessageToListOfChannels(
485+
activity,
486+
tenantId,
487+
members
488+
);
489+
}
490+
491+
/**
492+
* Gets the operation state.
493+
*
494+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
495+
* @param operationId The operationId to get the state of.
496+
* @returns Promise with The state and responses of the operation.
497+
*/
498+
static async getOperationState(context: TurnContext, operationId: string): Promise<BatchOperationStateResponse> {
499+
if (!operationId) {
500+
throw new Error('operationId is required.');
501+
}
502+
503+
return await this.getTeamsConnectorClient(context).teams.getOperationState(operationId);
504+
}
505+
506+
/**
507+
* Gets the failed entries of an executed operation.
508+
*
509+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
510+
* @param operationId The operationId to get the failed entries of.
511+
* @returns Promise with the list of failed entries of the operation.
512+
*/
513+
static async getFailedEntries(context: TurnContext, operationId: string): Promise<BatchFailedEntriesResponse> {
514+
if (!operationId) {
515+
throw new Error('operationId is required.');
516+
}
517+
518+
return await this.getTeamsConnectorClient(context).teams.getOperationFailedEntries(operationId);
519+
}
520+
521+
/**
522+
* Cancels a pending operation.
523+
*
524+
* @param context The [TurnContext](xref:botbuilder-core.TurnContext) for this turn.
525+
* @param operationId The id of the operation to cancel.
526+
* @returns Promise representing the asynchronous operation.
527+
*/
528+
static async cancelOperation(context: TurnContext, operationId: string): Promise<CancelOperationResponse> {
529+
if (!operationId) {
530+
throw new Error('operationId is required.');
531+
}
532+
533+
return await this.getTeamsConnectorClient(context).teams.cancelOperation(operationId);
534+
}
535+
367536
/**
368537
* @private
369538
*/

0 commit comments

Comments
 (0)