@microsoft/teamsfx 0.6.2-alpha.eb3c5cc12.0 → 0.6.3-alpha.8d048e1f1.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.
@@ -11,10 +11,34 @@ var identity = require('@azure/identity');
11
11
  var botbuilder = require('botbuilder');
12
12
  var botbuilderDialogs = require('botbuilder-dialogs');
13
13
  var uuid = require('uuid');
14
+ var axios = require('axios');
15
+ var path = require('path');
16
+ var fs = require('fs');
14
17
 
15
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
16
19
 
20
+ function _interopNamespace(e) {
21
+ if (e && e.__esModule) return e;
22
+ var n = Object.create(null);
23
+ if (e) {
24
+ Object.keys(e).forEach(function (k) {
25
+ if (k !== 'default') {
26
+ var d = Object.getOwnPropertyDescriptor(e, k);
27
+ Object.defineProperty(n, k, d.get ? d : {
28
+ enumerable: true,
29
+ get: function () { return e[k]; }
30
+ });
31
+ }
32
+ });
33
+ }
34
+ n["default"] = e;
35
+ return Object.freeze(n);
36
+ }
37
+
17
38
  var jwt_decode__default = /*#__PURE__*/_interopDefaultLegacy(jwt_decode);
39
+ var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
40
+ var path__namespace = /*#__PURE__*/_interopNamespace(path);
41
+ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
18
42
 
19
43
  // Copyright (c) Microsoft Corporation.
20
44
  // Licensed under the MIT license.
@@ -1416,6 +1440,72 @@ class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
1416
1440
  }
1417
1441
  }
1418
1442
 
1443
+ // Copyright (c) Microsoft Corporation.
1444
+ /**
1445
+ * Initializes new Axios instance with specific auth provider
1446
+ *
1447
+ * @param apiEndpoint - Base url of the API
1448
+ * @param authProvider - Auth provider that injects authentication info to each request
1449
+ * @returns axios instance configured with specfic auth provider
1450
+ *
1451
+ * @example
1452
+ * ```typescript
1453
+ * const client = createApiClient("https://my-api-endpoint-base-url", new BasicAuthProvider("xxx","xxx"));
1454
+ * ```
1455
+ *
1456
+ * @beta
1457
+ */
1458
+ function createApiClient(apiEndpoint, authProvider) {
1459
+ // Add a request interceptor
1460
+ const instance = axios__default["default"].create({
1461
+ baseURL: apiEndpoint,
1462
+ });
1463
+ instance.interceptors.request.use(function (config) {
1464
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1465
+ return yield authProvider.AddAuthenticationInfo(config);
1466
+ });
1467
+ });
1468
+ return instance;
1469
+ }
1470
+
1471
+ // Copyright (c) Microsoft Corporation.
1472
+ /**
1473
+ * Provider that handles Bearer Token authentication
1474
+ *
1475
+ * @beta
1476
+ */
1477
+ class BearerTokenAuthProvider {
1478
+ /**
1479
+ * @param getToken Function that returns the content of bearer token used in http request
1480
+ *
1481
+ * @beta
1482
+ */
1483
+ constructor(getToken) {
1484
+ this.getToken = getToken;
1485
+ }
1486
+ /**
1487
+ * Adds authentication info to http requests
1488
+ *
1489
+ * @param config - Contains all the request information and can be updated to include extra authentication info.
1490
+ * Refer https://axios-http.com/docs/req_config for detailed document.
1491
+ *
1492
+ * @beta
1493
+ */
1494
+ AddAuthenticationInfo(config) {
1495
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1496
+ const token = yield this.getToken();
1497
+ if (!config.headers) {
1498
+ config.headers = {};
1499
+ }
1500
+ if (config.headers["Authorization"]) {
1501
+ throw new Error("Authorization header already exists!");
1502
+ }
1503
+ config.headers["Authorization"] = `Bearer ${token}`;
1504
+ return config;
1505
+ });
1506
+ }
1507
+ }
1508
+
1419
1509
  // Copyright (c) Microsoft Corporation.
1420
1510
  /**
1421
1511
  * A class providing credential and configuration.
@@ -1602,16 +1692,986 @@ class TeamsFx {
1602
1692
  }
1603
1693
  }
1604
1694
 
1695
+ // Copyright (c) Microsoft Corporation.
1696
+ /**
1697
+ * @internal
1698
+ */
1699
+ var ActivityType;
1700
+ (function (ActivityType) {
1701
+ ActivityType[ActivityType["CurrentBotInstalled"] = 0] = "CurrentBotInstalled";
1702
+ ActivityType[ActivityType["CurrentBotMessaged"] = 1] = "CurrentBotMessaged";
1703
+ ActivityType[ActivityType["CurrentBotUninstalled"] = 2] = "CurrentBotUninstalled";
1704
+ ActivityType[ActivityType["TeamDeleted"] = 3] = "TeamDeleted";
1705
+ ActivityType[ActivityType["TeamRestored"] = 4] = "TeamRestored";
1706
+ ActivityType[ActivityType["Unknown"] = 5] = "Unknown";
1707
+ })(ActivityType || (ActivityType = {}));
1708
+ /**
1709
+ * @internal
1710
+ */
1711
+ class NotificationMiddleware {
1712
+ constructor(options) {
1713
+ this.conversationReferenceStore = options.conversationReferenceStore;
1714
+ }
1715
+ onTurn(context, next) {
1716
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1717
+ const type = this.classifyActivity(context.activity);
1718
+ switch (type) {
1719
+ case ActivityType.CurrentBotInstalled:
1720
+ case ActivityType.TeamRestored: {
1721
+ const reference = botbuilder.TurnContext.getConversationReference(context.activity);
1722
+ yield this.conversationReferenceStore.set(reference);
1723
+ break;
1724
+ }
1725
+ case ActivityType.CurrentBotMessaged: {
1726
+ const reference = botbuilder.TurnContext.getConversationReference(context.activity);
1727
+ if (!(yield this.conversationReferenceStore.check(reference))) {
1728
+ yield this.conversationReferenceStore.set(reference);
1729
+ }
1730
+ break;
1731
+ }
1732
+ case ActivityType.CurrentBotUninstalled:
1733
+ case ActivityType.TeamDeleted: {
1734
+ const reference = botbuilder.TurnContext.getConversationReference(context.activity);
1735
+ yield this.conversationReferenceStore.delete(reference);
1736
+ break;
1737
+ }
1738
+ }
1739
+ yield next();
1740
+ });
1741
+ }
1742
+ classifyActivity(activity) {
1743
+ var _a, _b;
1744
+ const activityType = activity.type;
1745
+ if (activityType === "installationUpdate") {
1746
+ const action = (_a = activity.action) === null || _a === void 0 ? void 0 : _a.toLowerCase();
1747
+ if (action === "add") {
1748
+ return ActivityType.CurrentBotInstalled;
1749
+ }
1750
+ else {
1751
+ return ActivityType.CurrentBotUninstalled;
1752
+ }
1753
+ }
1754
+ else if (activityType === "message") {
1755
+ return ActivityType.CurrentBotMessaged;
1756
+ }
1757
+ else if (activityType === "conversationUpdate") {
1758
+ const eventType = (_b = activity.channelData) === null || _b === void 0 ? void 0 : _b.eventType;
1759
+ if (eventType === "teamDeleted") {
1760
+ return ActivityType.TeamDeleted;
1761
+ }
1762
+ else if (eventType === "teamRestored") {
1763
+ return ActivityType.TeamRestored;
1764
+ }
1765
+ }
1766
+ return ActivityType.Unknown;
1767
+ }
1768
+ }
1769
+ class CommandResponseMiddleware {
1770
+ constructor(handlers) {
1771
+ this.commandHandlers = [];
1772
+ if (handlers && handlers.length > 0) {
1773
+ this.commandHandlers.push(...handlers);
1774
+ }
1775
+ }
1776
+ onTurn(context, next) {
1777
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1778
+ const type = this.classifyActivity(context.activity);
1779
+ switch (type) {
1780
+ case ActivityType.CurrentBotMessaged:
1781
+ // Invoke corresponding command handler for the command response
1782
+ const commandText = this.getActivityText(context.activity);
1783
+ const message = {
1784
+ text: commandText,
1785
+ };
1786
+ for (const handler of this.commandHandlers) {
1787
+ const matchResult = this.shouldTrigger(handler.triggerPatterns, commandText);
1788
+ // It is important to note that the command bot will stop processing handlers
1789
+ // when the first command handler is matched.
1790
+ if (!!matchResult) {
1791
+ message.matches = Array.isArray(matchResult) ? matchResult : void 0;
1792
+ const response = yield handler.handleCommandReceived(context, message);
1793
+ yield context.sendActivity(response);
1794
+ break;
1795
+ }
1796
+ }
1797
+ break;
1798
+ }
1799
+ yield next();
1800
+ });
1801
+ }
1802
+ classifyActivity(activity) {
1803
+ if (activity.type === botbuilder.ActivityTypes.Message) {
1804
+ return ActivityType.CurrentBotMessaged;
1805
+ }
1806
+ return ActivityType.Unknown;
1807
+ }
1808
+ matchPattern(pattern, text) {
1809
+ if (text) {
1810
+ if (typeof pattern === "string") {
1811
+ const regExp = new RegExp(pattern, "i");
1812
+ return regExp.test(text);
1813
+ }
1814
+ if (pattern instanceof RegExp) {
1815
+ const matches = text.match(pattern);
1816
+ return matches !== null && matches !== void 0 ? matches : false;
1817
+ }
1818
+ }
1819
+ return false;
1820
+ }
1821
+ shouldTrigger(patterns, text) {
1822
+ const expressions = Array.isArray(patterns) ? patterns : [patterns];
1823
+ for (const ex of expressions) {
1824
+ const arg = this.matchPattern(ex, text);
1825
+ if (arg)
1826
+ return arg;
1827
+ }
1828
+ return false;
1829
+ }
1830
+ getActivityText(activity) {
1831
+ let text = activity.text;
1832
+ const removedMentionText = botbuilder.TurnContext.removeRecipientMention(activity);
1833
+ if (removedMentionText) {
1834
+ text = removedMentionText
1835
+ .toLowerCase()
1836
+ .replace(/\n|\r\n/g, "")
1837
+ .trim();
1838
+ }
1839
+ return text;
1840
+ }
1841
+ }
1842
+
1843
+ // Copyright (c) Microsoft Corporation.
1844
+ /**
1845
+ * A command bot for receiving commands and sending responses in Teams.
1846
+ *
1847
+ * @remarks
1848
+ * 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.
1849
+ *
1850
+ * @beta
1851
+ */
1852
+ class CommandBot {
1853
+ /**
1854
+ * Creates a new instance of the `CommandBot`.
1855
+ *
1856
+ * @param adapter The bound `BotFrameworkAdapter`.
1857
+ * @param options - initialize options
1858
+ *
1859
+ * @beta
1860
+ */
1861
+ constructor(adapter, options) {
1862
+ this.middleware = new CommandResponseMiddleware(options === null || options === void 0 ? void 0 : options.commands);
1863
+ this.adapter = adapter.use(this.middleware);
1864
+ }
1865
+ /**
1866
+ * Registers a command into the command bot.
1867
+ *
1868
+ * @param command The command to registered.
1869
+ *
1870
+ * @beta
1871
+ */
1872
+ registerCommand(command) {
1873
+ if (command) {
1874
+ this.middleware.commandHandlers.push(command);
1875
+ }
1876
+ }
1877
+ /**
1878
+ * Registers commands into the command bot.
1879
+ *
1880
+ * @param commands The command to registered.
1881
+ *
1882
+ * @beta
1883
+ */
1884
+ registerCommands(commands) {
1885
+ if (commands) {
1886
+ this.middleware.commandHandlers.push(...commands);
1887
+ }
1888
+ }
1889
+ }
1890
+
1891
+ // Copyright (c) Microsoft Corporation.
1892
+ /**
1893
+ * @internal
1894
+ */
1895
+ class LocalFileStorage {
1896
+ constructor(fileDir) {
1897
+ this.localFileName = ".notification.localstore.json";
1898
+ this.filePath = path__namespace.resolve(fileDir, this.localFileName);
1899
+ }
1900
+ read(key) {
1901
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1902
+ if (!(yield this.storeFileExists())) {
1903
+ return undefined;
1904
+ }
1905
+ const data = yield this.readFromFile();
1906
+ return data[key];
1907
+ });
1908
+ }
1909
+ list() {
1910
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1911
+ if (!(yield this.storeFileExists())) {
1912
+ return [];
1913
+ }
1914
+ const data = yield this.readFromFile();
1915
+ return Object.entries(data).map((entry) => entry[1]);
1916
+ });
1917
+ }
1918
+ write(key, object) {
1919
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1920
+ if (!(yield this.storeFileExists())) {
1921
+ yield this.writeToFile({ [key]: object });
1922
+ return;
1923
+ }
1924
+ const data = yield this.readFromFile();
1925
+ yield this.writeToFile(Object.assign(data, { [key]: object }));
1926
+ });
1927
+ }
1928
+ delete(key) {
1929
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1930
+ if (yield this.storeFileExists()) {
1931
+ const data = yield this.readFromFile();
1932
+ if (data[key] !== undefined) {
1933
+ delete data[key];
1934
+ yield this.writeToFile(data);
1935
+ }
1936
+ }
1937
+ });
1938
+ }
1939
+ storeFileExists() {
1940
+ return new Promise((resolve) => {
1941
+ try {
1942
+ fs__namespace.access(this.filePath, (err) => {
1943
+ if (err) {
1944
+ resolve(false);
1945
+ }
1946
+ else {
1947
+ resolve(true);
1948
+ }
1949
+ });
1950
+ }
1951
+ catch (error) {
1952
+ resolve(false);
1953
+ }
1954
+ });
1955
+ }
1956
+ readFromFile() {
1957
+ return new Promise((resolve, reject) => {
1958
+ try {
1959
+ fs__namespace.readFile(this.filePath, { encoding: "utf-8" }, (err, rawData) => {
1960
+ if (err) {
1961
+ reject(err);
1962
+ }
1963
+ else {
1964
+ resolve(JSON.parse(rawData));
1965
+ }
1966
+ });
1967
+ }
1968
+ catch (error) {
1969
+ reject(error);
1970
+ }
1971
+ });
1972
+ }
1973
+ writeToFile(data) {
1974
+ return tslib.__awaiter(this, void 0, void 0, function* () {
1975
+ return new Promise((resolve, reject) => {
1976
+ try {
1977
+ const rawData = JSON.stringify(data, undefined, 2);
1978
+ fs__namespace.writeFile(this.filePath, rawData, { encoding: "utf-8" }, (err) => {
1979
+ if (err) {
1980
+ reject(err);
1981
+ }
1982
+ else {
1983
+ resolve();
1984
+ }
1985
+ });
1986
+ }
1987
+ catch (error) {
1988
+ reject(error);
1989
+ }
1990
+ });
1991
+ });
1992
+ }
1993
+ }
1994
+ /**
1995
+ * @internal
1996
+ */
1997
+ class ConversationReferenceStore {
1998
+ constructor(storage) {
1999
+ this.storage = storage;
2000
+ }
2001
+ check(reference) {
2002
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2003
+ const ref = yield this.storage.read(this.getKey(reference));
2004
+ return ref !== undefined;
2005
+ });
2006
+ }
2007
+ getAll() {
2008
+ return this.storage.list();
2009
+ }
2010
+ set(reference) {
2011
+ return this.storage.write(this.getKey(reference), reference);
2012
+ }
2013
+ delete(reference) {
2014
+ return this.storage.delete(this.getKey(reference));
2015
+ }
2016
+ getKey(reference) {
2017
+ var _a, _b;
2018
+ return `_${(_a = reference.conversation) === null || _a === void 0 ? void 0 : _a.tenantId}_${(_b = reference.conversation) === null || _b === void 0 ? void 0 : _b.id}`;
2019
+ }
2020
+ }
2021
+
2022
+ // Copyright (c) Microsoft Corporation.
2023
+ // Licensed under the MIT license.
2024
+ /**
2025
+ * @internal
2026
+ */
2027
+ function cloneConversation(conversation) {
2028
+ return Object.assign({}, conversation);
2029
+ }
2030
+ /**
2031
+ * @internal
2032
+ */
2033
+ function getTargetType(conversationReference) {
2034
+ var _a;
2035
+ const conversationType = (_a = conversationReference.conversation) === null || _a === void 0 ? void 0 : _a.conversationType;
2036
+ if (conversationType === "personal") {
2037
+ return "Person";
2038
+ }
2039
+ else if (conversationType === "groupChat") {
2040
+ return "Group";
2041
+ }
2042
+ else if (conversationType === "channel") {
2043
+ return "Channel";
2044
+ }
2045
+ else {
2046
+ return undefined;
2047
+ }
2048
+ }
2049
+ /**
2050
+ * @internal
2051
+ */
2052
+ function getTeamsBotInstallationId(context) {
2053
+ var _a, _b, _c, _d;
2054
+ 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;
2055
+ }
2056
+
2057
+ // Copyright (c) Microsoft Corporation.
2058
+ /**
2059
+ * Send a plain text message to a notification target.
2060
+ *
2061
+ * @param target - the notification target.
2062
+ * @param text - the plain text message.
2063
+ * @returns A `Promise` representing the asynchronous operation.
2064
+ *
2065
+ * @beta
2066
+ */
2067
+ function sendMessage(target, text) {
2068
+ return target.sendMessage(text);
2069
+ }
2070
+ /**
2071
+ * Send an adaptive card message to a notification target.
2072
+ *
2073
+ * @param target - the notification target.
2074
+ * @param card - the adaptive card raw JSON.
2075
+ * @returns A `Promise` representing the asynchronous operation.
2076
+ *
2077
+ * @beta
2078
+ */
2079
+ function sendAdaptiveCard(target, card) {
2080
+ return target.sendAdaptiveCard(card);
2081
+ }
2082
+ /**
2083
+ * A {@link NotificationTarget} that represents a team channel.
2084
+ *
2085
+ * @remarks
2086
+ * It's recommended to get channels from {@link TeamsBotInstallation.channels()}.
2087
+ *
2088
+ * @beta
2089
+ */
2090
+ class Channel {
2091
+ /**
2092
+ * Constuctor.
2093
+ *
2094
+ * @remarks
2095
+ * It's recommended to get channels from {@link TeamsBotInstallation.channels()}, instead of using this constructor.
2096
+ *
2097
+ * @param parent - The parent {@link TeamsBotInstallation} where this channel is created from.
2098
+ * @param info - Detailed channel information.
2099
+ *
2100
+ * @beta
2101
+ */
2102
+ constructor(parent, info) {
2103
+ /**
2104
+ * Notification target type. For channel it's always "Channel".
2105
+ *
2106
+ * @beta
2107
+ */
2108
+ this.type = "Channel";
2109
+ this.parent = parent;
2110
+ this.info = info;
2111
+ }
2112
+ /**
2113
+ * Send a plain text message.
2114
+ *
2115
+ * @param text - the plain text message.
2116
+ * @returns A `Promise` representing the asynchronous operation.
2117
+ *
2118
+ * @beta
2119
+ */
2120
+ sendMessage(text) {
2121
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2122
+ const conversation = yield this.newConversation(context);
2123
+ yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
2124
+ yield ctx.sendActivity(text);
2125
+ }));
2126
+ }));
2127
+ }
2128
+ /**
2129
+ * Send an adaptive card message.
2130
+ *
2131
+ * @param card - the adaptive card raw JSON.
2132
+ * @returns A `Promise` representing the asynchronous operation.
2133
+ *
2134
+ * @beta
2135
+ */
2136
+ sendAdaptiveCard(card) {
2137
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2138
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2139
+ const conversation = yield this.newConversation(context);
2140
+ yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
2141
+ yield ctx.sendActivity({
2142
+ attachments: [botbuilder.CardFactory.adaptiveCard(card)],
2143
+ });
2144
+ }));
2145
+ }));
2146
+ });
2147
+ }
2148
+ /**
2149
+ * @internal
2150
+ */
2151
+ newConversation(context) {
2152
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2153
+ const reference = botbuilder.TurnContext.getConversationReference(context.activity);
2154
+ const channelConversation = cloneConversation(reference);
2155
+ channelConversation.conversation.id = this.info.id || "";
2156
+ return channelConversation;
2157
+ });
2158
+ }
2159
+ }
2160
+ /**
2161
+ * A {@link NotificationTarget} that represents a team member.
2162
+ *
2163
+ * @remarks
2164
+ * It's recommended to get members from {@link TeamsBotInstallation.members()}.
2165
+ *
2166
+ * @beta
2167
+ */
2168
+ class Member {
2169
+ /**
2170
+ * Constuctor.
2171
+ *
2172
+ * @remarks
2173
+ * It's recommended to get members from {@link TeamsBotInstallation.members()}, instead of using this constructor.
2174
+ *
2175
+ * @param parent - The parent {@link TeamsBotInstallation} where this member is created from.
2176
+ * @param account - Detailed member account information.
2177
+ *
2178
+ * @beta
2179
+ */
2180
+ constructor(parent, account) {
2181
+ /**
2182
+ * Notification target type. For member it's always "Person".
2183
+ *
2184
+ * @beta
2185
+ */
2186
+ this.type = "Person";
2187
+ this.parent = parent;
2188
+ this.account = account;
2189
+ }
2190
+ /**
2191
+ * Send a plain text message.
2192
+ *
2193
+ * @param text - the plain text message.
2194
+ * @returns A `Promise` representing the asynchronous operation.
2195
+ *
2196
+ * @beta
2197
+ */
2198
+ sendMessage(text) {
2199
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2200
+ const conversation = yield this.newConversation(context);
2201
+ yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
2202
+ yield ctx.sendActivity(text);
2203
+ }));
2204
+ }));
2205
+ }
2206
+ /**
2207
+ * Send an adaptive card message.
2208
+ *
2209
+ * @param card - the adaptive card raw JSON.
2210
+ * @returns A `Promise` representing the asynchronous operation.
2211
+ *
2212
+ * @beta
2213
+ */
2214
+ sendAdaptiveCard(card) {
2215
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2216
+ return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2217
+ const conversation = yield this.newConversation(context);
2218
+ yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
2219
+ yield ctx.sendActivity({
2220
+ attachments: [botbuilder.CardFactory.adaptiveCard(card)],
2221
+ });
2222
+ }));
2223
+ }));
2224
+ });
2225
+ }
2226
+ /**
2227
+ * @internal
2228
+ */
2229
+ newConversation(context) {
2230
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2231
+ const reference = botbuilder.TurnContext.getConversationReference(context.activity);
2232
+ const personalConversation = cloneConversation(reference);
2233
+ const connectorClient = context.turnState.get(this.parent.adapter.ConnectorClientKey);
2234
+ const conversation = yield connectorClient.conversations.createConversation({
2235
+ isGroup: false,
2236
+ tenantId: context.activity.conversation.tenantId,
2237
+ bot: context.activity.recipient,
2238
+ members: [this.account],
2239
+ channelData: {},
2240
+ });
2241
+ personalConversation.conversation.id = conversation.id;
2242
+ return personalConversation;
2243
+ });
2244
+ }
2245
+ }
2246
+ /**
2247
+ * A {@link NotificationTarget} that represents a bot installation. Teams Bot could be installed into
2248
+ * - Personal chat
2249
+ * - Group chat
2250
+ * - Team (by default the `General` channel)
2251
+ *
2252
+ * @remarks
2253
+ * It's recommended to get bot installations from {@link ConversationBot.installations()}.
2254
+ *
2255
+ * @beta
2256
+ */
2257
+ class TeamsBotInstallation {
2258
+ /**
2259
+ * Constructor
2260
+ *
2261
+ * @remarks
2262
+ * It's recommended to get bot installations from {@link ConversationBot.installations()}, instead of using this constructor.
2263
+ *
2264
+ * @param adapter - the bound `BotFrameworkAdapter`.
2265
+ * @param conversationReference - the bound `ConversationReference`.
2266
+ *
2267
+ * @beta
2268
+ */
2269
+ constructor(adapter, conversationReference) {
2270
+ this.adapter = adapter;
2271
+ this.conversationReference = conversationReference;
2272
+ this.type = getTargetType(conversationReference);
2273
+ }
2274
+ /**
2275
+ * Send a plain text message.
2276
+ *
2277
+ * @param text - the plain text message.
2278
+ * @returns A `Promise` representing the asynchronous operation.
2279
+ *
2280
+ * @beta
2281
+ */
2282
+ sendMessage(text) {
2283
+ return this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2284
+ yield context.sendActivity(text);
2285
+ }));
2286
+ }
2287
+ /**
2288
+ * Send an adaptive card message.
2289
+ *
2290
+ * @param card - the adaptive card raw JSON.
2291
+ * @returns A `Promise` representing the asynchronous operation.
2292
+ *
2293
+ * @beta
2294
+ */
2295
+ sendAdaptiveCard(card) {
2296
+ return this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2297
+ yield context.sendActivity({
2298
+ attachments: [botbuilder.CardFactory.adaptiveCard(card)],
2299
+ });
2300
+ }));
2301
+ }
2302
+ /**
2303
+ * Get channels from this bot installation.
2304
+ *
2305
+ * @returns an array of channels if bot is installed into a team, otherwise returns an empty array.
2306
+ *
2307
+ * @beta
2308
+ */
2309
+ channels() {
2310
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2311
+ let teamsChannels = [];
2312
+ yield this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2313
+ const teamId = getTeamsBotInstallationId(context);
2314
+ if (teamId !== undefined) {
2315
+ teamsChannels = yield botbuilder.TeamsInfo.getTeamChannels(context, teamId);
2316
+ }
2317
+ }));
2318
+ const channels = [];
2319
+ for (const channel of teamsChannels) {
2320
+ channels.push(new Channel(this, channel));
2321
+ }
2322
+ return channels;
2323
+ });
2324
+ }
2325
+ /**
2326
+ * Get members from this bot installation.
2327
+ *
2328
+ * @returns an array of members from where the bot is installed.
2329
+ *
2330
+ * @beta
2331
+ */
2332
+ members() {
2333
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2334
+ const members = [];
2335
+ yield this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2336
+ let continuationToken;
2337
+ do {
2338
+ const pagedMembers = yield botbuilder.TeamsInfo.getPagedMembers(context, undefined, continuationToken);
2339
+ continuationToken = pagedMembers.continuationToken;
2340
+ for (const member of pagedMembers.members) {
2341
+ members.push(new Member(this, member));
2342
+ }
2343
+ } while (continuationToken !== undefined);
2344
+ }));
2345
+ return members;
2346
+ });
2347
+ }
2348
+ }
2349
+ /**
2350
+ * Provide utilities to send notification to varies targets (e.g., member, channel, incoming wehbook).
2351
+ *
2352
+ * @beta
2353
+ */
2354
+ class NotificationBot {
2355
+ /**
2356
+ * constructor of the notification bot.
2357
+ *
2358
+ * @remarks
2359
+ * To ensure accuracy, it's recommended to initialize before handling any message.
2360
+ *
2361
+ * @param adapter - the bound `BotFrameworkAdapter`
2362
+ * @param options - initialize options
2363
+ *
2364
+ * @beta
2365
+ */
2366
+ constructor(adapter, options) {
2367
+ var _a, _b;
2368
+ const storage = (_a = options === null || options === void 0 ? void 0 : options.storage) !== null && _a !== void 0 ? _a : new LocalFileStorage(path__namespace.resolve(process.env.RUNNING_ON_AZURE === "1" ? (_b = process.env.TEMP) !== null && _b !== void 0 ? _b : "./" : "./"));
2369
+ this.conversationReferenceStore = new ConversationReferenceStore(storage);
2370
+ this.adapter = adapter.use(new NotificationMiddleware({
2371
+ conversationReferenceStore: this.conversationReferenceStore,
2372
+ }));
2373
+ }
2374
+ /**
2375
+ * Get all targets where the bot is installed.
2376
+ *
2377
+ * @remarks
2378
+ * The result is retrieving from the persisted storage.
2379
+ *
2380
+ * @returns - an array of {@link TeamsBotInstallation}.
2381
+ *
2382
+ * @beta
2383
+ */
2384
+ installations() {
2385
+ return tslib.__awaiter(this, void 0, void 0, function* () {
2386
+ if (this.conversationReferenceStore === undefined || this.adapter === undefined) {
2387
+ throw new Error("NotificationBot has not been initialized.");
2388
+ }
2389
+ const references = (yield this.conversationReferenceStore.getAll()).values();
2390
+ const targets = [];
2391
+ for (const reference of references) {
2392
+ // validate connection
2393
+ let valid = true;
2394
+ this.adapter.continueConversation(reference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
2395
+ try {
2396
+ // try get member to see if the installation is still valid
2397
+ yield botbuilder.TeamsInfo.getPagedMembers(context, 1);
2398
+ }
2399
+ catch (error) {
2400
+ if (error.code === "BotNotInConversationRoster") {
2401
+ valid = false;
2402
+ }
2403
+ }
2404
+ }));
2405
+ if (valid) {
2406
+ targets.push(new TeamsBotInstallation(this.adapter, reference));
2407
+ }
2408
+ else {
2409
+ this.conversationReferenceStore.delete(reference);
2410
+ }
2411
+ }
2412
+ return targets;
2413
+ });
2414
+ }
2415
+ }
2416
+
2417
+ // Copyright (c) Microsoft Corporation.
2418
+ /**
2419
+ * Provide utilities for bot conversation, including:
2420
+ * - handle command and response.
2421
+ * - send notification to varies targets (e.g., member, channel, incoming wehbook).
2422
+ *
2423
+ * @example
2424
+ * For command and response, you can register your commands through the constructor, or use the `registerCommand` and `registerCommands` API to add commands later.
2425
+ *
2426
+ * ```typescript
2427
+ * // register through constructor
2428
+ * const conversationBot = new ConversationBot({
2429
+ * command: {
2430
+ * enabled: true,
2431
+ * options: {
2432
+ * commands: [ new HelloWorldCommandHandler() ],
2433
+ * },
2434
+ * },
2435
+ * });
2436
+ *
2437
+ * // register through `register*` API
2438
+ * conversationBot.command.registerCommand(new HelpCommandHandler());
2439
+ * ```
2440
+ *
2441
+ * For notification, you can enable notification at initialization, then send notificaations at any time.
2442
+ *
2443
+ * ```typescript
2444
+ * // enable through constructor
2445
+ * const conversationBot = new ConversationBot({
2446
+ * notification: {
2447
+ * enabled: true,
2448
+ * },
2449
+ * });
2450
+ *
2451
+ * // get all bot installations and send message
2452
+ * for (const target of await conversationBot.notification.installations()) {
2453
+ * await target.sendMessage("Hello Notification");
2454
+ * }
2455
+ *
2456
+ * // alternative - send message to all members
2457
+ * for (const target of await conversationBot.notification.installations()) {
2458
+ * for (const member of await target.members()) {
2459
+ * await member.sendMessage("Hello Notification");
2460
+ * }
2461
+ * }
2462
+ * ```
2463
+ *
2464
+ * @remarks
2465
+ * Set `adapter` in {@link ConversationOptions} to use your own bot adapter.
2466
+ *
2467
+ * For command and response, 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.
2468
+ *
2469
+ * For notification, set `notification.options.storage` in {@link ConversationOptions} to use your own storage implementation.
2470
+ *
2471
+ * @beta
2472
+ */
2473
+ class ConversationBot {
2474
+ /**
2475
+ * Creates new instance of the `ConversationBot`.
2476
+ *
2477
+ * @param options - initialize options
2478
+ *
2479
+ * @beta
2480
+ */
2481
+ constructor(options) {
2482
+ if (options.adapter) {
2483
+ this.adapter = options.adapter;
2484
+ }
2485
+ else {
2486
+ this.adapter = new botbuilder.BotFrameworkAdapter({
2487
+ appId: process.env.BOT_ID,
2488
+ appPassword: process.env.BOT_PASSWORD,
2489
+ });
2490
+ }
2491
+ if (options.command.enabled) {
2492
+ this.command = new CommandBot(this.adapter, options.command.options);
2493
+ }
2494
+ if (options.notification.enabled) {
2495
+ this.notification = new NotificationBot(this.adapter, options.notification.options);
2496
+ }
2497
+ }
2498
+ }
2499
+
2500
+ // Copyright (c) Microsoft Corporation.
2501
+ const { AdaptiveCards } = require("@microsoft/adaptivecards-tools");
2502
+ /**
2503
+ * Provides utility method to build bot message with cards that supported in Teams.
2504
+ */
2505
+ class MessageBuilder {
2506
+ /**
2507
+ * Build a bot message activity attached with adaptive card.
2508
+ *
2509
+ * @param getCardData Function to prepare your card data.
2510
+ * @param cardTemplate The adaptive card template.
2511
+ * @returns A bot message activity attached with an adaptive card.
2512
+ *
2513
+ * @example
2514
+ * ```javascript
2515
+ * const cardTemplate = {
2516
+ * type: "AdaptiveCard",
2517
+ * body: [
2518
+ * {
2519
+ * "type": "TextBlock",
2520
+ * "text": "${title}",
2521
+ * "size": "Large"
2522
+ * },
2523
+ * {
2524
+ * "type": "TextBlock",
2525
+ * "text": "${description}"
2526
+ * }],
2527
+ * $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
2528
+ * version: "1.4"
2529
+ * };
2530
+ *
2531
+ * type CardData = {
2532
+ * title: string,
2533
+ * description: string
2534
+ * };
2535
+ * const card = MessageBuilder.attachAdaptiveCard<CardData>(() => {
2536
+ * return {
2537
+ * title: "sample card title",
2538
+ * description: "sample card description"
2539
+ * }}, cardTemplate);
2540
+ * ```
2541
+ *
2542
+ * @beta
2543
+ */
2544
+ static attachAdaptiveCard(getCardData, cardTemplate) {
2545
+ const cardData = getCardData();
2546
+ return {
2547
+ attachments: [botbuilder.CardFactory.adaptiveCard(AdaptiveCards.declare(cardTemplate).render(cardData))],
2548
+ };
2549
+ }
2550
+ /**
2551
+ * Build a bot message activity attached with an adaptive card.
2552
+ *
2553
+ * @param card The adaptive card content.
2554
+ * @returns A bot message activity attached with an adaptive card.
2555
+ *
2556
+ * @beta
2557
+ */
2558
+ static attachAdaptiveCardWithoutData(card) {
2559
+ return {
2560
+ attachments: [botbuilder.CardFactory.adaptiveCard(AdaptiveCards.declareWithoutData(card).render())],
2561
+ };
2562
+ }
2563
+ /**
2564
+ * Build a bot message activity attached with an hero card.
2565
+ *
2566
+ * @param title The card title.
2567
+ * @param images Optional. The array of images to include on the card.
2568
+ * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array
2569
+ * is converted to an `imBack` button with a title and value set to the value of the string.
2570
+ * @param other Optional. Any additional properties to include on the card.
2571
+ *
2572
+ * @returns A bot message activity attached with a hero card.
2573
+ *
2574
+ * @example
2575
+ * ```javascript
2576
+ * const message = MessageBuilder.attachHeroCard(
2577
+ * 'sample title',
2578
+ * ['https://example.com/sample.jpg'],
2579
+ * ['action']
2580
+ * );
2581
+ * ```
2582
+ *
2583
+ * @beta
2584
+ */
2585
+ static attachHeroCard(title, images, buttons, other) {
2586
+ return MessageBuilder.attachContent(botbuilder.CardFactory.heroCard(title, images, buttons, other));
2587
+ }
2588
+ /**
2589
+ * Returns an attachment for a sign-in card.
2590
+ *
2591
+ * @param title The title for the card's sign-in button.
2592
+ * @param url The URL of the sign-in page to use.
2593
+ * @param text Optional. Additional text to include on the card.
2594
+ *
2595
+ * @returns A bot message activity attached with a sign-in card.
2596
+ *
2597
+ * @remarks
2598
+ * For channels that don't natively support sign-in cards, an alternative message is rendered.
2599
+ *
2600
+ * @beta
2601
+ */
2602
+ static attachSigninCard(title, url, text) {
2603
+ return MessageBuilder.attachContent(botbuilder.CardFactory.signinCard(title, url, text));
2604
+ }
2605
+ /**
2606
+ * Build a bot message activity attached with an Office 365 connector card.
2607
+ *
2608
+ * @param card A description of the Office 365 connector card.
2609
+ * @returns A bot message activity attached with an Office 365 connector card.
2610
+ *
2611
+ * @beta
2612
+ */
2613
+ static attachO365ConnectorCard(card) {
2614
+ return MessageBuilder.attachContent(botbuilder.CardFactory.o365ConnectorCard(card));
2615
+ }
2616
+ /**
2617
+ * Build a message activity attached with a receipt card.
2618
+ * @param card A description of the receipt card.
2619
+ * @returns A message activity attached with a receipt card.
2620
+ *
2621
+ * @beta
2622
+ */
2623
+ static AttachReceiptCard(card) {
2624
+ return MessageBuilder.attachContent(botbuilder.CardFactory.receiptCard(card));
2625
+ }
2626
+ /**
2627
+ *
2628
+ * @param title The card title.
2629
+ * @param images Optional. The array of images to include on the card.
2630
+ * @param buttons Optional. The array of buttons to include on the card. Each `string` in the array
2631
+ * is converted to an `imBack` button with a title and value set to the value of the string.
2632
+ * @param other Optional. Any additional properties to include on the card.
2633
+ * @returns A message activity attached with a thumbnail card
2634
+ *
2635
+ * @beta
2636
+ */
2637
+ static attachThumbnailCard(title, images, buttons, other) {
2638
+ return MessageBuilder.attachContent(botbuilder.CardFactory.thumbnailCard(title, images, buttons, other));
2639
+ }
2640
+ /**
2641
+ * Add an attachement to a bot activity.
2642
+ * @param attachement The attachment object to attach.
2643
+ * @returns A message activity with an attachment.
2644
+ *
2645
+ * @beta
2646
+ */
2647
+ static attachContent(attachement) {
2648
+ return {
2649
+ attachments: [attachement],
2650
+ };
2651
+ }
2652
+ }
2653
+
1605
2654
  exports.AppCredential = AppCredential;
2655
+ exports.BearerTokenAuthProvider = BearerTokenAuthProvider;
2656
+ exports.Channel = Channel;
2657
+ exports.CommandBot = CommandBot;
2658
+ exports.ConversationBot = ConversationBot;
1606
2659
  exports.ErrorWithCode = ErrorWithCode;
2660
+ exports.Member = Member;
2661
+ exports.MessageBuilder = MessageBuilder;
1607
2662
  exports.MsGraphAuthProvider = MsGraphAuthProvider;
2663
+ exports.NotificationBot = NotificationBot;
1608
2664
  exports.OnBehalfOfUserCredential = OnBehalfOfUserCredential;
2665
+ exports.TeamsBotInstallation = TeamsBotInstallation;
1609
2666
  exports.TeamsBotSsoPrompt = TeamsBotSsoPrompt;
1610
2667
  exports.TeamsFx = TeamsFx;
1611
2668
  exports.TeamsUserCredential = TeamsUserCredential;
2669
+ exports.createApiClient = createApiClient;
1612
2670
  exports.createMicrosoftGraphClient = createMicrosoftGraphClient;
1613
2671
  exports.getLogLevel = getLogLevel;
1614
2672
  exports.getTediousConnectionConfig = getTediousConnectionConfig;
2673
+ exports.sendAdaptiveCard = sendAdaptiveCard;
2674
+ exports.sendMessage = sendMessage;
1615
2675
  exports.setLogFunction = setLogFunction;
1616
2676
  exports.setLogLevel = setLogLevel;
1617
2677
  exports.setLogger = setLogger;