1 | /**
|
2 | * @module botkit
|
3 | */
|
4 | /**
|
5 | * Copyright (c) Microsoft Corporation. All rights reserved.
|
6 | * Licensed under the MIT License.
|
7 | */
|
8 | import { BotkitMessage } from './core';
|
9 | import { BotWorker } from './botworker';
|
10 | import { TeamsInfo, MiddlewareSet, TurnContext } from 'botbuilder';
|
11 |
|
12 | /**
|
13 | * This is a specialized version of [Botkit's core BotWorker class](core.md#BotWorker) that includes additional methods for interacting with Microsoft Teams.
|
14 | * It includes all functionality from the base class, as well as the extension methods below.
|
15 | * This BotWorker is used with the built-in Bot Framework adapter.
|
16 | * @noInheritDoc
|
17 | */
|
18 | export class TeamsBotWorker extends BotWorker {
|
19 | /**
|
20 | * Grants access to the TeamsInfo helper class
|
21 | * See: https://docs.microsoft.com/en-us/javascript/api/botbuilder/teamsinfo?view=botbuilder-ts-latest
|
22 | */
|
23 | public teams: TeamsInfo = TeamsInfo;
|
24 |
|
25 | /**
|
26 | * Reply to a Teams task module task/fetch or task/submit with a task module response.
|
27 | * See https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/task-modules/task-modules-bots
|
28 | * @param message
|
29 | * @param taskInfo an object in the form {type, value}
|
30 | */
|
31 | public async replyWithTaskInfo(message: BotkitMessage, taskInfo: any): Promise<any> {
|
32 | if (!taskInfo || taskInfo === {}) {
|
33 | // send a null response back
|
34 | taskInfo = {
|
35 | type: 'message',
|
36 | value: ''
|
37 | };
|
38 | }
|
39 | return new Promise((resolve, reject) => {
|
40 | this.controller.middleware.send.run(this, taskInfo, async (err, bot, taskInfo) => {
|
41 | if (err) {
|
42 | return reject(err);
|
43 | }
|
44 | resolve(await this.getConfig('context').sendActivity({
|
45 | type: 'invokeResponse',
|
46 | value: {
|
47 | status: 200,
|
48 | body: {
|
49 | task: taskInfo
|
50 | }
|
51 | }
|
52 | }));
|
53 | });
|
54 | });
|
55 | }
|
56 | }
|
57 |
|
58 | /**
|
59 | * When used, causes Botkit to emit special events for teams "invokes"
|
60 | * Based on https://github.com/microsoft/botbuilder-js/blob/master/libraries/botbuilder/src/teamsActivityHandler.ts
|
61 | * This allows Botkit bots to respond directly to task/fetch or task/submit events, as an example.
|
62 | * To use this, bind it to the adapter before creating the Botkit controller:
|
63 | * ```javascript
|
64 | * const Botkit = new Botkit({...});
|
65 | * botkit.adapter.use(new TeamsInvokeMiddleware());
|
66 | *
|
67 | * // can bind directly to task/fetch, task/submit and other invoke types used by teams
|
68 | * controller.on('task/fetch', async(bot, message) => {
|
69 | * await bot.replyWithTaskInfo(message, taskInfo);
|
70 | * });
|
71 | * ```
|
72 | */
|
73 | export class TeamsInvokeMiddleware extends MiddlewareSet {
|
74 | /**
|
75 | * Not for direct use - implements the MiddlewareSet's required onTurn function used to process the event
|
76 | * @param context
|
77 | * @param next
|
78 | */
|
79 | public async onTurn(context: TurnContext, next: () => Promise<any>): Promise<void> {
|
80 | if (context.activity.type === 'invoke') {
|
81 | if (!context.activity.name && context.activity.channelId === 'msteams') {
|
82 | context.activity.channelData.botkitEventType = 'cardAction';
|
83 | } else {
|
84 | switch (context.activity.name) {
|
85 | case 'fileConsent/invoke':
|
86 | case 'actionableMessage/executeAction':
|
87 | case 'composeExtension/queryLink':
|
88 | case 'composeExtension/query':
|
89 | case 'composeExtension/selectItem':
|
90 | case 'composeExtension/submitAction':
|
91 | case 'composeExtension/fetchTask':
|
92 | case 'composeExtension/querySettingUrl':
|
93 | case 'composeExtension/setting':
|
94 | case 'composeExtension/onCardButtonClicked':
|
95 | case 'task/fetch':
|
96 | case 'task/submit':
|
97 | context.activity.channelData.botkitEventType = context.activity.name;
|
98 | break;
|
99 | }
|
100 | }
|
101 | }
|
102 | await next();
|
103 | }
|
104 | }
|