@microsoft/teamsfx 0.6.1 → 0.6.2-alpha.1f263658d.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,9 +3,12 @@ import { ConfidentialClientApplication } from '@azure/msal-node';
3
3
  import { createHash } from 'crypto';
4
4
  import { Client } from '@microsoft/microsoft-graph-client';
5
5
  import { ManagedIdentityCredential } from '@azure/identity';
6
- import { ActivityTypes, Channels, TeamsInfo, CardFactory, ActionTypes, MessageFactory, StatusCodes, verifyStateOperationName, tokenExchangeOperationName } from 'botbuilder';
6
+ import { ActivityTypes, Channels, TeamsInfo, CardFactory, ActionTypes, MessageFactory, StatusCodes, verifyStateOperationName, tokenExchangeOperationName, TurnContext } from 'botbuilder';
7
7
  import { Dialog } from 'botbuilder-dialogs';
8
8
  import { v4 } from 'uuid';
9
+ import axios from 'axios';
10
+ import * as path from 'path';
11
+ import * as fs from 'fs';
9
12
 
10
13
  // Copyright (c) Microsoft Corporation.
11
14
  // Licensed under the MIT license.
@@ -1385,6 +1388,69 @@ class TeamsBotSsoPrompt extends Dialog {
1385
1388
  }
1386
1389
  }
1387
1390
 
1391
+ // Copyright (c) Microsoft Corporation.
1392
+ /**
1393
+ * Initializes new Axios instance with specific auth provider
1394
+ *
1395
+ * @param apiEndpoint - Base url of the API
1396
+ * @param authProvider - Auth provider that injects authentication info to each request
1397
+ * @returns axios instance configured with specfic auth provider
1398
+ *
1399
+ * @example
1400
+ * ```typescript
1401
+ * const client = createApiClient("https://my-api-endpoint-base-url", new BasicAuthProvider("xxx","xxx"));
1402
+ * ```
1403
+ *
1404
+ * @beta
1405
+ */
1406
+ function createApiClient(apiEndpoint, authProvider) {
1407
+ // Add a request interceptor
1408
+ const instance = axios.create({
1409
+ baseURL: apiEndpoint,
1410
+ });
1411
+ instance.interceptors.request.use(async function (config) {
1412
+ return await authProvider.AddAuthenticationInfo(config);
1413
+ });
1414
+ return instance;
1415
+ }
1416
+
1417
+ // Copyright (c) Microsoft Corporation.
1418
+ // Licensed under the MIT license.
1419
+ /**
1420
+ * Provider that handles Bearer Token authentication
1421
+ *
1422
+ * @beta
1423
+ */
1424
+ class BearerTokenAuthProvider {
1425
+ /**
1426
+ * @param getToken Function that returns the content of bearer token used in http request
1427
+ *
1428
+ * @beta
1429
+ */
1430
+ constructor(getToken) {
1431
+ this.getToken = getToken;
1432
+ }
1433
+ /**
1434
+ * Adds authentication info to http requests
1435
+ *
1436
+ * @param config - Contains all the request information and can be updated to include extra authentication info.
1437
+ * Refer https://axios-http.com/docs/req_config for detailed document.
1438
+ *
1439
+ * @beta
1440
+ */
1441
+ async AddAuthenticationInfo(config) {
1442
+ const token = await this.getToken();
1443
+ if (!config.headers) {
1444
+ config.headers = {};
1445
+ }
1446
+ if (config.headers["Authorization"]) {
1447
+ throw new Error("Authorization header already exists!");
1448
+ }
1449
+ config.headers["Authorization"] = `Bearer ${token}`;
1450
+ return config;
1451
+ }
1452
+ }
1453
+
1388
1454
  // Copyright (c) Microsoft Corporation.
1389
1455
  /**
1390
1456
  * A class providing credential and configuration.
@@ -1567,5 +1633,876 @@ class TeamsFx {
1567
1633
  }
1568
1634
  }
1569
1635
 
1570
- export { AppCredential, ErrorCode, ErrorWithCode, IdentityType, LogLevel, MsGraphAuthProvider, OnBehalfOfUserCredential, TeamsBotSsoPrompt, TeamsFx, TeamsUserCredential, createMicrosoftGraphClient, getLogLevel, getTediousConnectionConfig, setLogFunction, setLogLevel, setLogger };
1636
+ // Copyright (c) Microsoft Corporation.
1637
+ /**
1638
+ * @internal
1639
+ */
1640
+ var ActivityType;
1641
+ (function (ActivityType) {
1642
+ ActivityType[ActivityType["CurrentBotInstalled"] = 0] = "CurrentBotInstalled";
1643
+ ActivityType[ActivityType["CurrentBotMessaged"] = 1] = "CurrentBotMessaged";
1644
+ ActivityType[ActivityType["CurrentBotUninstalled"] = 2] = "CurrentBotUninstalled";
1645
+ ActivityType[ActivityType["TeamDeleted"] = 3] = "TeamDeleted";
1646
+ ActivityType[ActivityType["TeamRestored"] = 4] = "TeamRestored";
1647
+ ActivityType[ActivityType["CommandReceived"] = 5] = "CommandReceived";
1648
+ ActivityType[ActivityType["Unknown"] = 6] = "Unknown";
1649
+ })(ActivityType || (ActivityType = {}));
1650
+ /**
1651
+ * @internal
1652
+ */
1653
+ class NotificationMiddleware {
1654
+ constructor(options) {
1655
+ this.conversationReferenceStore = options.conversationReferenceStore;
1656
+ }
1657
+ async onTurn(context, next) {
1658
+ const type = this.classifyActivity(context.activity);
1659
+ switch (type) {
1660
+ case ActivityType.CurrentBotInstalled:
1661
+ case ActivityType.TeamRestored: {
1662
+ const reference = TurnContext.getConversationReference(context.activity);
1663
+ await this.conversationReferenceStore.set(reference);
1664
+ break;
1665
+ }
1666
+ case ActivityType.CurrentBotMessaged: {
1667
+ const reference = TurnContext.getConversationReference(context.activity);
1668
+ if (!(await this.conversationReferenceStore.check(reference))) {
1669
+ await this.conversationReferenceStore.set(reference);
1670
+ }
1671
+ break;
1672
+ }
1673
+ case ActivityType.CurrentBotUninstalled:
1674
+ case ActivityType.TeamDeleted: {
1675
+ const reference = TurnContext.getConversationReference(context.activity);
1676
+ await this.conversationReferenceStore.delete(reference);
1677
+ break;
1678
+ }
1679
+ }
1680
+ await next();
1681
+ }
1682
+ classifyActivity(activity) {
1683
+ var _a, _b;
1684
+ const activityType = activity.type;
1685
+ if (activityType === "installationUpdate") {
1686
+ const action = (_a = activity.action) === null || _a === void 0 ? void 0 : _a.toLowerCase();
1687
+ if (action === "add") {
1688
+ return ActivityType.CurrentBotInstalled;
1689
+ }
1690
+ else {
1691
+ return ActivityType.CurrentBotUninstalled;
1692
+ }
1693
+ }
1694
+ else if (activityType === "message") {
1695
+ return ActivityType.CurrentBotMessaged;
1696
+ }
1697
+ else if (activityType === "conversationUpdate") {
1698
+ const eventType = (_b = activity.channelData) === null || _b === void 0 ? void 0 : _b.eventType;
1699
+ if (eventType === "teamDeleted") {
1700
+ return ActivityType.TeamDeleted;
1701
+ }
1702
+ else if (eventType === "teamRestored") {
1703
+ return ActivityType.TeamRestored;
1704
+ }
1705
+ }
1706
+ return ActivityType.Unknown;
1707
+ }
1708
+ }
1709
+ class CommandResponseMiddleware {
1710
+ constructor(handlers) {
1711
+ this.commandHandlers = [];
1712
+ if (handlers && handlers.length > 0) {
1713
+ this.commandHandlers.push(...handlers);
1714
+ }
1715
+ }
1716
+ async onTurn(context, next) {
1717
+ const type = this.classifyActivity(context.activity);
1718
+ let handlers = [];
1719
+ switch (type) {
1720
+ case ActivityType.CommandReceived:
1721
+ // Invoke corresponding command handler for the command response
1722
+ const commandText = this.getActivityText(context.activity);
1723
+ handlers = this.filterCommandHandler(commandText, this.commandHandlers);
1724
+ if (handlers.length > 0) {
1725
+ const response = await handlers[0].handleCommandReceived(context, commandText);
1726
+ await context.sendActivity(response);
1727
+ }
1728
+ break;
1729
+ }
1730
+ await next();
1731
+ }
1732
+ classifyActivity(activity) {
1733
+ if (this.isCommandReceived(activity)) {
1734
+ return ActivityType.CommandReceived;
1735
+ }
1736
+ return ActivityType.Unknown;
1737
+ }
1738
+ isCommandReceived(activity) {
1739
+ if (this.commandHandlers) {
1740
+ const commandText = this.getActivityText(activity);
1741
+ const handlers = this.filterCommandHandler(commandText, this.commandHandlers);
1742
+ return handlers.length > 0;
1743
+ }
1744
+ else {
1745
+ return false;
1746
+ }
1747
+ }
1748
+ filterCommandHandler(commandText, commandHandlers) {
1749
+ const handlers = commandHandlers.filter((handler) => {
1750
+ var _a;
1751
+ if (typeof handler.commandNameOrPattern === "string") {
1752
+ return handler.commandNameOrPattern.toLocaleLowerCase() === commandText;
1753
+ }
1754
+ else {
1755
+ return (_a = handler.commandNameOrPattern) === null || _a === void 0 ? void 0 : _a.test(commandText);
1756
+ }
1757
+ });
1758
+ return handlers;
1759
+ }
1760
+ getActivityText(activity) {
1761
+ let text = activity.text;
1762
+ const removedMentionText = TurnContext.removeRecipientMention(activity);
1763
+ if (removedMentionText) {
1764
+ text = removedMentionText
1765
+ .toLowerCase()
1766
+ .replace(/\n|\r\n/g, "")
1767
+ .trim();
1768
+ }
1769
+ return text;
1770
+ }
1771
+ }
1772
+
1773
+ // Copyright (c) Microsoft Corporation.
1774
+ /**
1775
+ * @internal
1776
+ */
1777
+ class LocalFileStorage {
1778
+ constructor(fileDir) {
1779
+ this.localFileName = ".notification.localstore.json";
1780
+ this.filePath = path.resolve(fileDir, this.localFileName);
1781
+ }
1782
+ async read(key) {
1783
+ if (!(await this.storeFileExists())) {
1784
+ return undefined;
1785
+ }
1786
+ const data = await this.readFromFile();
1787
+ return data[key];
1788
+ }
1789
+ async list() {
1790
+ if (!(await this.storeFileExists())) {
1791
+ return [];
1792
+ }
1793
+ const data = await this.readFromFile();
1794
+ return Object.entries(data).map((entry) => entry[1]);
1795
+ }
1796
+ async write(key, object) {
1797
+ if (!(await this.storeFileExists())) {
1798
+ await this.writeToFile({ [key]: object });
1799
+ return;
1800
+ }
1801
+ const data = await this.readFromFile();
1802
+ await this.writeToFile(Object.assign(data, { [key]: object }));
1803
+ }
1804
+ async delete(key) {
1805
+ if (await this.storeFileExists()) {
1806
+ const data = await this.readFromFile();
1807
+ if (data[key] !== undefined) {
1808
+ delete data[key];
1809
+ await this.writeToFile(data);
1810
+ }
1811
+ }
1812
+ }
1813
+ storeFileExists() {
1814
+ return new Promise((resolve) => {
1815
+ try {
1816
+ fs.access(this.filePath, (err) => {
1817
+ if (err) {
1818
+ resolve(false);
1819
+ }
1820
+ else {
1821
+ resolve(true);
1822
+ }
1823
+ });
1824
+ }
1825
+ catch (error) {
1826
+ resolve(false);
1827
+ }
1828
+ });
1829
+ }
1830
+ readFromFile() {
1831
+ return new Promise((resolve, reject) => {
1832
+ try {
1833
+ fs.readFile(this.filePath, { encoding: "utf-8" }, (err, rawData) => {
1834
+ if (err) {
1835
+ reject(err);
1836
+ }
1837
+ else {
1838
+ resolve(JSON.parse(rawData));
1839
+ }
1840
+ });
1841
+ }
1842
+ catch (error) {
1843
+ reject(error);
1844
+ }
1845
+ });
1846
+ }
1847
+ async writeToFile(data) {
1848
+ return new Promise((resolve, reject) => {
1849
+ try {
1850
+ const rawData = JSON.stringify(data, undefined, 2);
1851
+ fs.writeFile(this.filePath, rawData, { encoding: "utf-8" }, (err) => {
1852
+ if (err) {
1853
+ reject(err);
1854
+ }
1855
+ else {
1856
+ resolve();
1857
+ }
1858
+ });
1859
+ }
1860
+ catch (error) {
1861
+ reject(error);
1862
+ }
1863
+ });
1864
+ }
1865
+ }
1866
+ /**
1867
+ * @internal
1868
+ */
1869
+ class ConversationReferenceStore {
1870
+ constructor(storage) {
1871
+ this.storage = storage;
1872
+ }
1873
+ async check(reference) {
1874
+ const ref = await this.storage.read(this.getKey(reference));
1875
+ return ref !== undefined;
1876
+ }
1877
+ getAll() {
1878
+ return this.storage.list();
1879
+ }
1880
+ set(reference) {
1881
+ return this.storage.write(this.getKey(reference), reference);
1882
+ }
1883
+ delete(reference) {
1884
+ return this.storage.delete(this.getKey(reference));
1885
+ }
1886
+ getKey(reference) {
1887
+ var _a, _b;
1888
+ return `_${(_a = reference.conversation) === null || _a === void 0 ? void 0 : _a.tenantId}_${(_b = reference.conversation) === null || _b === void 0 ? void 0 : _b.id}`;
1889
+ }
1890
+ }
1891
+
1892
+ // Copyright (c) Microsoft Corporation.
1893
+ // Licensed under the MIT license.
1894
+ /**
1895
+ * @internal
1896
+ */
1897
+ function cloneConversation(conversation) {
1898
+ return Object.assign({}, conversation);
1899
+ }
1900
+ /**
1901
+ * @internal
1902
+ */
1903
+ function getTargetType(conversationReference) {
1904
+ var _a;
1905
+ const conversationType = (_a = conversationReference.conversation) === null || _a === void 0 ? void 0 : _a.conversationType;
1906
+ if (conversationType === "personal") {
1907
+ return "Person";
1908
+ }
1909
+ else if (conversationType === "groupChat") {
1910
+ return "Group";
1911
+ }
1912
+ else if (conversationType === "channel") {
1913
+ return "Channel";
1914
+ }
1915
+ else {
1916
+ return undefined;
1917
+ }
1918
+ }
1919
+ /**
1920
+ * @internal
1921
+ */
1922
+ function getTeamsBotInstallationId(context) {
1923
+ var _a, _b, _c, _d;
1924
+ return (_d = (_c = (_b = (_a = context.activity) === null || _a === void 0 ? void 0 : _a.channelData) === null || _b === void 0 ? void 0 : _b.team) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : context.activity.conversation.id;
1925
+ }
1926
+
1927
+ // Copyright (c) Microsoft Corporation.
1928
+ /**
1929
+ * Send a plain text message to a notification target.
1930
+ *
1931
+ * @param target - the notification target.
1932
+ * @param text - the plain text message.
1933
+ * @returns A `Promise` representing the asynchronous operation.
1934
+ *
1935
+ * @beta
1936
+ */
1937
+ function sendMessage(target, text) {
1938
+ return target.sendMessage(text);
1939
+ }
1940
+ /**
1941
+ * Send an adaptive card message to a notification target.
1942
+ *
1943
+ * @param target - the notification target.
1944
+ * @param card - the adaptive card raw JSON.
1945
+ * @returns A `Promise` representing the asynchronous operation.
1946
+ *
1947
+ * @beta
1948
+ */
1949
+ function sendAdaptiveCard(target, card) {
1950
+ return target.sendAdaptiveCard(card);
1951
+ }
1952
+ /**
1953
+ * A {@link NotificationTarget} that represents a team channel.
1954
+ *
1955
+ * @remarks
1956
+ * It's recommended to get channels from {@link TeamsBotInstallation.channels()}.
1957
+ *
1958
+ * @beta
1959
+ */
1960
+ class Channel {
1961
+ /**
1962
+ * Constuctor.
1963
+ *
1964
+ * @remarks
1965
+ * It's recommended to get channels from {@link TeamsBotInstallation.channels()}, instead of using this constructor.
1966
+ *
1967
+ * @param parent - The parent {@link TeamsBotInstallation} where this channel is created from.
1968
+ * @param info - Detailed channel information.
1969
+ *
1970
+ * @beta
1971
+ */
1972
+ constructor(parent, info) {
1973
+ /**
1974
+ * Notification target type. For channel it's always "Channel".
1975
+ *
1976
+ * @beta
1977
+ */
1978
+ this.type = "Channel";
1979
+ this.parent = parent;
1980
+ this.info = info;
1981
+ }
1982
+ /**
1983
+ * Send a plain text message.
1984
+ *
1985
+ * @param text - the plain text message.
1986
+ * @returns A `Promise` representing the asynchronous operation.
1987
+ *
1988
+ * @beta
1989
+ */
1990
+ sendMessage(text) {
1991
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
1992
+ const conversation = await this.newConversation(context);
1993
+ await this.parent.adapter.continueConversation(conversation, async (ctx) => {
1994
+ await ctx.sendActivity(text);
1995
+ });
1996
+ });
1997
+ }
1998
+ /**
1999
+ * Send an adaptive card message.
2000
+ *
2001
+ * @param card - the adaptive card raw JSON.
2002
+ * @returns A `Promise` representing the asynchronous operation.
2003
+ *
2004
+ * @beta
2005
+ */
2006
+ async sendAdaptiveCard(card) {
2007
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2008
+ const conversation = await this.newConversation(context);
2009
+ await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2010
+ await ctx.sendActivity({
2011
+ attachments: [CardFactory.adaptiveCard(card)],
2012
+ });
2013
+ });
2014
+ });
2015
+ }
2016
+ /**
2017
+ * @internal
2018
+ */
2019
+ async newConversation(context) {
2020
+ const reference = TurnContext.getConversationReference(context.activity);
2021
+ const channelConversation = cloneConversation(reference);
2022
+ channelConversation.conversation.id = this.info.id || "";
2023
+ return channelConversation;
2024
+ }
2025
+ }
2026
+ /**
2027
+ * A {@link NotificationTarget} that represents a team member.
2028
+ *
2029
+ * @remarks
2030
+ * It's recommended to get members from {@link TeamsBotInstallation.members()}.
2031
+ *
2032
+ * @beta
2033
+ */
2034
+ class Member {
2035
+ /**
2036
+ * Constuctor.
2037
+ *
2038
+ * @remarks
2039
+ * It's recommended to get members from {@link TeamsBotInstallation.members()}, instead of using this constructor.
2040
+ *
2041
+ * @param parent - The parent {@link TeamsBotInstallation} where this member is created from.
2042
+ * @param account - Detailed member account information.
2043
+ *
2044
+ * @beta
2045
+ */
2046
+ constructor(parent, account) {
2047
+ /**
2048
+ * Notification target type. For member it's always "Person".
2049
+ *
2050
+ * @beta
2051
+ */
2052
+ this.type = "Person";
2053
+ this.parent = parent;
2054
+ this.account = account;
2055
+ }
2056
+ /**
2057
+ * Send a plain text message.
2058
+ *
2059
+ * @param text - the plain text message.
2060
+ * @returns A `Promise` representing the asynchronous operation.
2061
+ *
2062
+ * @beta
2063
+ */
2064
+ sendMessage(text) {
2065
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2066
+ const conversation = await this.newConversation(context);
2067
+ await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2068
+ await ctx.sendActivity(text);
2069
+ });
2070
+ });
2071
+ }
2072
+ /**
2073
+ * Send an adaptive card message.
2074
+ *
2075
+ * @param card - the adaptive card raw JSON.
2076
+ * @returns A `Promise` representing the asynchronous operation.
2077
+ *
2078
+ * @beta
2079
+ */
2080
+ async sendAdaptiveCard(card) {
2081
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, async (context) => {
2082
+ const conversation = await this.newConversation(context);
2083
+ await this.parent.adapter.continueConversation(conversation, async (ctx) => {
2084
+ await ctx.sendActivity({
2085
+ attachments: [CardFactory.adaptiveCard(card)],
2086
+ });
2087
+ });
2088
+ });
2089
+ }
2090
+ /**
2091
+ * @internal
2092
+ */
2093
+ async newConversation(context) {
2094
+ const reference = TurnContext.getConversationReference(context.activity);
2095
+ const personalConversation = cloneConversation(reference);
2096
+ const connectorClient = context.turnState.get(this.parent.adapter.ConnectorClientKey);
2097
+ const conversation = await connectorClient.conversations.createConversation({
2098
+ isGroup: false,
2099
+ tenantId: context.activity.conversation.tenantId,
2100
+ bot: context.activity.recipient,
2101
+ members: [this.account],
2102
+ channelData: {},
2103
+ });
2104
+ personalConversation.conversation.id = conversation.id;
2105
+ return personalConversation;
2106
+ }
2107
+ }
2108
+ /**
2109
+ * A {@link NotificationTarget} that represents a bot installation. Teams Bot could be installed into
2110
+ * - Personal chat
2111
+ * - Group chat
2112
+ * - Team (by default the `General` channel)
2113
+ *
2114
+ * @remarks
2115
+ * It's recommended to get bot installations from {@link ConversationBot.installations()}.
2116
+ *
2117
+ * @beta
2118
+ */
2119
+ class TeamsBotInstallation {
2120
+ /**
2121
+ * Constructor
2122
+ *
2123
+ * @remarks
2124
+ * It's recommended to get bot installations from {@link ConversationBot.installations()}, instead of using this constructor.
2125
+ *
2126
+ * @param adapter - the bound `BotFrameworkAdapter`.
2127
+ * @param conversationReference - the bound `ConversationReference`.
2128
+ *
2129
+ * @beta
2130
+ */
2131
+ constructor(adapter, conversationReference) {
2132
+ this.adapter = adapter;
2133
+ this.conversationReference = conversationReference;
2134
+ this.type = getTargetType(conversationReference);
2135
+ }
2136
+ /**
2137
+ * Send a plain text message.
2138
+ *
2139
+ * @param text - the plain text message.
2140
+ * @returns A `Promise` representing the asynchronous operation.
2141
+ *
2142
+ * @beta
2143
+ */
2144
+ sendMessage(text) {
2145
+ return this.adapter.continueConversation(this.conversationReference, async (context) => {
2146
+ await context.sendActivity(text);
2147
+ });
2148
+ }
2149
+ /**
2150
+ * Send an adaptive card message.
2151
+ *
2152
+ * @param card - the adaptive card raw JSON.
2153
+ * @returns A `Promise` representing the asynchronous operation.
2154
+ *
2155
+ * @beta
2156
+ */
2157
+ sendAdaptiveCard(card) {
2158
+ return this.adapter.continueConversation(this.conversationReference, async (context) => {
2159
+ await context.sendActivity({
2160
+ attachments: [CardFactory.adaptiveCard(card)],
2161
+ });
2162
+ });
2163
+ }
2164
+ /**
2165
+ * Get channels from this bot installation.
2166
+ *
2167
+ * @returns an array of channels if bot is installed into a team, otherwise returns an empty array.
2168
+ *
2169
+ * @beta
2170
+ */
2171
+ async channels() {
2172
+ let teamsChannels = [];
2173
+ await this.adapter.continueConversation(this.conversationReference, async (context) => {
2174
+ const teamId = getTeamsBotInstallationId(context);
2175
+ if (teamId !== undefined) {
2176
+ teamsChannels = await TeamsInfo.getTeamChannels(context, teamId);
2177
+ }
2178
+ });
2179
+ const channels = [];
2180
+ for (const channel of teamsChannels) {
2181
+ channels.push(new Channel(this, channel));
2182
+ }
2183
+ return channels;
2184
+ }
2185
+ /**
2186
+ * Get members from this bot installation.
2187
+ *
2188
+ * @returns an array of members from where the bot is installed.
2189
+ *
2190
+ * @beta
2191
+ */
2192
+ async members() {
2193
+ const members = [];
2194
+ await this.adapter.continueConversation(this.conversationReference, async (context) => {
2195
+ let continuationToken;
2196
+ do {
2197
+ const pagedMembers = await TeamsInfo.getPagedMembers(context, undefined, continuationToken);
2198
+ continuationToken = pagedMembers.continuationToken;
2199
+ for (const member of pagedMembers.members) {
2200
+ members.push(new Member(this, member));
2201
+ }
2202
+ } while (continuationToken !== undefined);
2203
+ });
2204
+ return members;
2205
+ }
2206
+ }
2207
+ /**
2208
+ * Provide static utilities for bot conversation, including
2209
+ * - send notification to varies targets (e.g., member, channel, incoming wehbook)
2210
+ * - handle command and response.
2211
+ *
2212
+ * @example
2213
+ * Here's an example on how to send notification via Teams Bot.
2214
+ * ```typescript
2215
+ * // initialize (it's recommended to be called before handling any bot message)
2216
+ * const notificationBot = new NotificationBot(adapter);
2217
+ *
2218
+ * // get all bot installations and send message
2219
+ * for (const target of await notificationBot.installations()) {
2220
+ * await target.sendMessage("Hello Notification");
2221
+ * }
2222
+ *
2223
+ * // alternative - send message to all members
2224
+ * for (const target of await notificationBot.installations()) {
2225
+ * for (const member of await target.members()) {
2226
+ * await member.sendMessage("Hello Notification");
2227
+ * }
2228
+ * }
2229
+ * ```
2230
+ *
2231
+ * @beta
2232
+ */
2233
+ class NotificationBot {
2234
+ /**
2235
+ * constructor of the notification bot.
2236
+ *
2237
+ * @remarks
2238
+ * To ensure accuracy, it's recommended to initialize before handling any message.
2239
+ *
2240
+ * @param adapter - the bound `BotFrameworkAdapter`
2241
+ * @param options - initialize options
2242
+ *
2243
+ * @beta
2244
+ */
2245
+ constructor(adapter, options) {
2246
+ var _a, _b;
2247
+ const storage = (_a = options === null || options === void 0 ? void 0 : options.storage) !== null && _a !== void 0 ? _a : new LocalFileStorage(path.resolve(process.env.RUNNING_ON_AZURE === "1" ? (_b = process.env.TEMP) !== null && _b !== void 0 ? _b : "./" : "./"));
2248
+ this.conversationReferenceStore = new ConversationReferenceStore(storage);
2249
+ this.adapter = adapter.use(new NotificationMiddleware({
2250
+ conversationReferenceStore: this.conversationReferenceStore,
2251
+ }));
2252
+ }
2253
+ /**
2254
+ * Get all targets where the bot is installed.
2255
+ *
2256
+ * @remarks
2257
+ * The result is retrieving from the persisted storage.
2258
+ *
2259
+ * @returns - an array of {@link TeamsBotInstallation}.
2260
+ *
2261
+ * @beta
2262
+ */
2263
+ async installations() {
2264
+ if (this.conversationReferenceStore === undefined || this.adapter === undefined) {
2265
+ throw new Error("NotificationBot has not been initialized.");
2266
+ }
2267
+ const references = (await this.conversationReferenceStore.getAll()).values();
2268
+ const targets = [];
2269
+ for (const reference of references) {
2270
+ // validate connection
2271
+ let valid = true;
2272
+ this.adapter.continueConversation(reference, async (context) => {
2273
+ try {
2274
+ // try get member to see if the installation is still valid
2275
+ await TeamsInfo.getPagedMembers(context, 1);
2276
+ }
2277
+ catch (error) {
2278
+ if (error.code === "BotNotInConversationRoster") {
2279
+ valid = false;
2280
+ }
2281
+ }
2282
+ });
2283
+ if (valid) {
2284
+ targets.push(new TeamsBotInstallation(this.adapter, reference));
2285
+ }
2286
+ else {
2287
+ this.conversationReferenceStore.delete(reference);
2288
+ }
2289
+ }
2290
+ return targets;
2291
+ }
2292
+ }
2293
+
2294
+ // Copyright (c) Microsoft Corporation.
2295
+ /**
2296
+ * A command bot for receiving commands and sending responses in Teams.
2297
+ *
2298
+ * @remarks
2299
+ * Ensure each command should ONLY be registered with the command once, otherwise it'll cause unexpected behavior if you register the same command more than once.
2300
+ *
2301
+ * @example
2302
+ * You can register your commands through the constructor of the {@link CommandBot}, or use the `registerCommand` and `registerCommands` API to add commands after creating the `CommandBot` instance.
2303
+ *
2304
+ * ```typescript
2305
+ * // register through constructor
2306
+ * const commandBot = new CommandBot(adapter, [ new HelloWorldCommandHandler() ]);
2307
+ *
2308
+ * // register through `register*` API
2309
+ * commandBot.registerCommand(new HelpCommandHandler());
2310
+ * ```
2311
+ *
2312
+ * @beta
2313
+ */
2314
+ class CommandBot {
2315
+ /**
2316
+ * Creates a new instance of the `CommandBot`.
2317
+ *
2318
+ * @param adapter The bound `BotFrameworkAdapter`.
2319
+ * @param commands The commands to registered with the command bot. Each command should implement the interface {@link TeamsFxBotCommandHandler} so that it can be correctly handled by this command bot.
2320
+ *
2321
+ * @beta
2322
+ */
2323
+ constructor(adapter, commands) {
2324
+ this.middleware = new CommandResponseMiddleware(commands);
2325
+ this.adapter = adapter.use(this.middleware);
2326
+ }
2327
+ /**
2328
+ * Registers a command into the command bot.
2329
+ *
2330
+ * @param command The command to registered.
2331
+ *
2332
+ * @beta
2333
+ */
2334
+ registerCommand(command) {
2335
+ if (command) {
2336
+ this.middleware.commandHandlers.push(command);
2337
+ }
2338
+ }
2339
+ /**
2340
+ * Registers commands into the command bot.
2341
+ *
2342
+ * @param commands The command to registered.
2343
+ *
2344
+ * @beta
2345
+ */
2346
+ registerCommands(commands) {
2347
+ if (commands) {
2348
+ this.middleware.commandHandlers.push(...commands);
2349
+ }
2350
+ }
2351
+ }
2352
+
2353
+ // Copyright (c) Microsoft Corporation.
2354
+ const { AdaptiveCards } = require("@microsoft/adaptivecards-tools");
2355
+ /**
2356
+ * Provides utility method to build bot message with cards that supported in Teams.
2357
+ */
2358
+ class MessageBuilder {
2359
+ /**
2360
+ * Build a bot message activity attached with adaptive card.
2361
+ *
2362
+ * @param getCardData Function to prepare your card data.
2363
+ * @param cardTemplate The adaptive card template.
2364
+ * @returns A bot message activity attached with an adaptive card.
2365
+ *
2366
+ * @example
2367
+ * ```javascript
2368
+ * const cardTemplate = {
2369
+ * type: "AdaptiveCard",
2370
+ * body: [
2371
+ * {
2372
+ * "type": "TextBlock",
2373
+ * "text": "${title}",
2374
+ * "size": "Large"
2375
+ * },
2376
+ * {
2377
+ * "type": "TextBlock",
2378
+ * "text": "${description}"
2379
+ * }],
2380
+ * $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
2381
+ * version: "1.4"
2382
+ * };
2383
+ *
2384
+ * type CardData = {
2385
+ * title: string,
2386
+ * description: string
2387
+ * };
2388
+ * const card = MessageBuilder.attachAdaptiveCard<CardData>(() => {
2389
+ * return {
2390
+ * title: "sample card title",
2391
+ * description: "sample card description"
2392
+ * }}, cardTemplate);
2393
+ * ```
2394
+ *
2395
+ * @beta
2396
+ */
2397
+ static attachAdaptiveCard(getCardData, cardTemplate) {
2398
+ const cardData = getCardData();
2399
+ return {
2400
+ attachments: [CardFactory.adaptiveCard(AdaptiveCards.declare(cardTemplate).render(cardData))],
2401
+ };
2402
+ }
2403
+ /**
2404
+ * Build a bot message activity attached with an adaptive card.
2405
+ *
2406
+ * @param card The adaptive card content.
2407
+ * @returns A bot message activity attached with an adaptive card.
2408
+ *
2409
+ * @beta
2410
+ */
2411
+ static attachAdaptiveCardWithoutData(card) {
2412
+ return {
2413
+ attachments: [CardFactory.adaptiveCard(AdaptiveCards.declareWithoutData(card).render())],
2414
+ };
2415
+ }
2416
+ /**
2417
+ * Build a bot message activity attached with an hero card.
2418
+ *
2419
+ * @param title The card title.
2420
+ * @param images Optional. The array of images to include on the card.
2421
+ * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array
2422
+ * is converted to an `imBack` button with a title and value set to the value of the string.
2423
+ * @param other Optional. Any additional properties to include on the card.
2424
+ *
2425
+ * @returns A bot message activity attached with a hero card.
2426
+ *
2427
+ * @example
2428
+ * ```javascript
2429
+ * const message = MessageBuilder.attachHeroCard(
2430
+ * 'sample title',
2431
+ * ['https://example.com/sample.jpg'],
2432
+ * ['action']
2433
+ * );
2434
+ * ```
2435
+ *
2436
+ * @beta
2437
+ */
2438
+ static attachHeroCard(title, images, buttons, other) {
2439
+ return MessageBuilder.attachContent(CardFactory.heroCard(title, images, buttons, other));
2440
+ }
2441
+ /**
2442
+ * Returns an attachment for a sign-in card.
2443
+ *
2444
+ * @param title The title for the card's sign-in button.
2445
+ * @param url The URL of the sign-in page to use.
2446
+ * @param text Optional. Additional text to include on the card.
2447
+ *
2448
+ * @returns A bot message activity attached with a sign-in card.
2449
+ *
2450
+ * @remarks
2451
+ * For channels that don't natively support sign-in cards, an alternative message is rendered.
2452
+ *
2453
+ * @beta
2454
+ */
2455
+ static attachSigninCard(title, url, text) {
2456
+ return MessageBuilder.attachContent(CardFactory.signinCard(title, url, text));
2457
+ }
2458
+ /**
2459
+ * Build a bot message activity attached with an Office 365 connector card.
2460
+ *
2461
+ * @param card A description of the Office 365 connector card.
2462
+ * @returns A bot message activity attached with an Office 365 connector card.
2463
+ *
2464
+ * @beta
2465
+ */
2466
+ static attachO365ConnectorCard(card) {
2467
+ return MessageBuilder.attachContent(CardFactory.o365ConnectorCard(card));
2468
+ }
2469
+ /**
2470
+ * Build a message activity attached with a receipt card.
2471
+ * @param card A description of the receipt card.
2472
+ * @returns A message activity attached with a receipt card.
2473
+ *
2474
+ * @beta
2475
+ */
2476
+ static AttachReceiptCard(card) {
2477
+ return MessageBuilder.attachContent(CardFactory.receiptCard(card));
2478
+ }
2479
+ /**
2480
+ *
2481
+ * @param title The card title.
2482
+ * @param images Optional. The array of images to include on the card.
2483
+ * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array
2484
+ * is converted to an `imBack` button with a title and value set to the value of the string.
2485
+ * @param other Optional. Any additional properties to include on the card.
2486
+ * @returns A message activity attached with a thumbnail card
2487
+ *
2488
+ * @beta
2489
+ */
2490
+ static attachThumbnailCard(title, images, buttons, other) {
2491
+ return MessageBuilder.attachContent(CardFactory.thumbnailCard(title, images, buttons, other));
2492
+ }
2493
+ /**
2494
+ * Add an attachement to a bot activity.
2495
+ * @param attachement The attachment object to attach.
2496
+ * @returns A message activity with an attachment.
2497
+ *
2498
+ * @beta
2499
+ */
2500
+ static attachContent(attachement) {
2501
+ return {
2502
+ attachments: [attachement],
2503
+ };
2504
+ }
2505
+ }
2506
+
2507
+ export { AppCredential, BearerTokenAuthProvider, Channel, CommandBot, ErrorCode, ErrorWithCode, IdentityType, LogLevel, Member, MessageBuilder, MsGraphAuthProvider, NotificationBot, OnBehalfOfUserCredential, TeamsBotInstallation, TeamsBotSsoPrompt, TeamsFx, TeamsUserCredential, createApiClient, createMicrosoftGraphClient, getLogLevel, getTediousConnectionConfig, sendAdaptiveCard, sendMessage, setLogFunction, setLogLevel, setLogger };
1571
2508
  //# sourceMappingURL=index.esm2017.mjs.map