@microsoft/teamsfx 0.6.2 → 0.6.3-alpha.42a29d71b.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.
- package/dist/index.esm2017.js +636 -1
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm2017.mjs +1306 -5
- package/dist/index.esm2017.mjs.map +1 -1
- package/dist/index.esm5.js +658 -1
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.node.cjs.js +1383 -3
- package/dist/index.node.cjs.js.map +1 -1
- package/package.json +5 -3
- package/types/teamsfx.d.ts +1106 -102
package/dist/index.node.cjs.js
CHANGED
|
@@ -11,10 +11,35 @@ 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 https = require('https');
|
|
16
|
+
var path = require('path');
|
|
17
|
+
var fs = require('fs');
|
|
14
18
|
|
|
15
19
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
16
20
|
|
|
21
|
+
function _interopNamespace(e) {
|
|
22
|
+
if (e && e.__esModule) return e;
|
|
23
|
+
var n = Object.create(null);
|
|
24
|
+
if (e) {
|
|
25
|
+
Object.keys(e).forEach(function (k) {
|
|
26
|
+
if (k !== 'default') {
|
|
27
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
28
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () { return e[k]; }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
n["default"] = e;
|
|
36
|
+
return Object.freeze(n);
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
var jwt_decode__default = /*#__PURE__*/_interopDefaultLegacy(jwt_decode);
|
|
40
|
+
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
41
|
+
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
42
|
+
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
18
43
|
|
|
19
44
|
// Copyright (c) Microsoft Corporation.
|
|
20
45
|
// Licensed under the MIT license.
|
|
@@ -76,6 +101,10 @@ exports.ErrorCode = void 0;
|
|
|
76
101
|
* Identity type error.
|
|
77
102
|
*/
|
|
78
103
|
ErrorCode["IdentityTypeNotSupported"] = "IdentityTypeNotSupported";
|
|
104
|
+
/**
|
|
105
|
+
* Authentication info already exists error.
|
|
106
|
+
*/
|
|
107
|
+
ErrorCode["AuthorizationInfoAlreadyExists"] = "AuthorizationInfoAlreadyExists";
|
|
79
108
|
})(exports.ErrorCode || (exports.ErrorCode = {}));
|
|
80
109
|
/**
|
|
81
110
|
* @internal
|
|
@@ -97,6 +126,14 @@ ErrorMessage.FailToAcquireTokenOnBehalfOfUser = "Failed to acquire access token
|
|
|
97
126
|
ErrorMessage.OnlyMSTeamsChannelSupported = "{0} is only supported in MS Teams Channel";
|
|
98
127
|
// IdentityTypeNotSupported Error
|
|
99
128
|
ErrorMessage.IdentityTypeNotSupported = "{0} identity is not supported in {1}";
|
|
129
|
+
// AuthorizationInfoError
|
|
130
|
+
ErrorMessage.AuthorizationHeaderAlreadyExists = "Authorization header already exists!";
|
|
131
|
+
ErrorMessage.BasicCredentialAlreadyExists = "Basic credential already exists!";
|
|
132
|
+
// InvalidParameter Error
|
|
133
|
+
ErrorMessage.EmptyParameter = "Parameter {0} is empty";
|
|
134
|
+
ErrorMessage.DuplicateHttpsOptionProperty = "Axios HTTPS agent already defined value for property {0}";
|
|
135
|
+
ErrorMessage.DuplicateApiKeyInHeader = "The request already defined api key in request header with name {0}.";
|
|
136
|
+
ErrorMessage.DuplicateApiKeyInQueryParam = "The request already defined api key in query parameter with name {0}.";
|
|
100
137
|
/**
|
|
101
138
|
* Error class with code and message thrown by the SDK.
|
|
102
139
|
*
|
|
@@ -1417,6 +1454,335 @@ class TeamsBotSsoPrompt extends botbuilderDialogs.Dialog {
|
|
|
1417
1454
|
}
|
|
1418
1455
|
|
|
1419
1456
|
// Copyright (c) Microsoft Corporation.
|
|
1457
|
+
/**
|
|
1458
|
+
* Initializes new Axios instance with specific auth provider
|
|
1459
|
+
*
|
|
1460
|
+
* @param apiEndpoint - Base url of the API
|
|
1461
|
+
* @param authProvider - Auth provider that injects authentication info to each request
|
|
1462
|
+
* @returns axios instance configured with specfic auth provider
|
|
1463
|
+
*
|
|
1464
|
+
* @example
|
|
1465
|
+
* ```typescript
|
|
1466
|
+
* const client = createApiClient("https://my-api-endpoint-base-url", new BasicAuthProvider("xxx","xxx"));
|
|
1467
|
+
* ```
|
|
1468
|
+
*
|
|
1469
|
+
* @beta
|
|
1470
|
+
*/
|
|
1471
|
+
function createApiClient(apiEndpoint, authProvider) {
|
|
1472
|
+
// Add a request interceptor
|
|
1473
|
+
const instance = axios__default["default"].create({
|
|
1474
|
+
baseURL: apiEndpoint,
|
|
1475
|
+
});
|
|
1476
|
+
instance.interceptors.request.use(function (config) {
|
|
1477
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1478
|
+
return yield authProvider.AddAuthenticationInfo(config);
|
|
1479
|
+
});
|
|
1480
|
+
});
|
|
1481
|
+
return instance;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
// Copyright (c) Microsoft Corporation.
|
|
1485
|
+
/**
|
|
1486
|
+
* Provider that handles Bearer Token authentication
|
|
1487
|
+
*
|
|
1488
|
+
* @beta
|
|
1489
|
+
*/
|
|
1490
|
+
class BearerTokenAuthProvider {
|
|
1491
|
+
/**
|
|
1492
|
+
* @param { () => Promise<string> } getToken - Function that returns the content of bearer token used in http request
|
|
1493
|
+
*
|
|
1494
|
+
* @beta
|
|
1495
|
+
*/
|
|
1496
|
+
constructor(getToken) {
|
|
1497
|
+
this.getToken = getToken;
|
|
1498
|
+
}
|
|
1499
|
+
/**
|
|
1500
|
+
* Adds authentication info to http requests
|
|
1501
|
+
*
|
|
1502
|
+
* @param { AxiosRequestConfig } config - Contains all the request information and can be updated to include extra authentication info.
|
|
1503
|
+
* Refer https://axios-http.com/docs/req_config for detailed document.
|
|
1504
|
+
*
|
|
1505
|
+
* @returns Updated axios request config.
|
|
1506
|
+
*
|
|
1507
|
+
* @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when Authorization header already exists in request configuration.
|
|
1508
|
+
*
|
|
1509
|
+
* @beta
|
|
1510
|
+
*/
|
|
1511
|
+
AddAuthenticationInfo(config) {
|
|
1512
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1513
|
+
const token = yield this.getToken();
|
|
1514
|
+
if (!config.headers) {
|
|
1515
|
+
config.headers = {};
|
|
1516
|
+
}
|
|
1517
|
+
if (config.headers["Authorization"]) {
|
|
1518
|
+
throw new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, exports.ErrorCode.AuthorizationInfoAlreadyExists);
|
|
1519
|
+
}
|
|
1520
|
+
config.headers["Authorization"] = `Bearer ${token}`;
|
|
1521
|
+
return config;
|
|
1522
|
+
});
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
// Copyright (c) Microsoft Corporation.
|
|
1527
|
+
/**
|
|
1528
|
+
* Provider that handles Basic authentication
|
|
1529
|
+
*
|
|
1530
|
+
* @beta
|
|
1531
|
+
*/
|
|
1532
|
+
class BasicAuthProvider {
|
|
1533
|
+
/**
|
|
1534
|
+
*
|
|
1535
|
+
* @param { string } userName - Username used in basic auth
|
|
1536
|
+
* @param { string } password - Password used in basic auth
|
|
1537
|
+
*
|
|
1538
|
+
* @throws {@link ErrorCode|InvalidParameter} - when username or password is empty.
|
|
1539
|
+
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
|
|
1540
|
+
*
|
|
1541
|
+
* @beta
|
|
1542
|
+
*/
|
|
1543
|
+
constructor(userName, password) {
|
|
1544
|
+
if (!userName) {
|
|
1545
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "username"), exports.ErrorCode.InvalidParameter);
|
|
1546
|
+
}
|
|
1547
|
+
if (!password) {
|
|
1548
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "password"), exports.ErrorCode.InvalidParameter);
|
|
1549
|
+
}
|
|
1550
|
+
this.userName = userName;
|
|
1551
|
+
this.password = password;
|
|
1552
|
+
}
|
|
1553
|
+
/**
|
|
1554
|
+
* Adds authentication info to http requests
|
|
1555
|
+
*
|
|
1556
|
+
* @param { AxiosRequestConfig } config - Contains all the request information and can be updated to include extra authentication info.
|
|
1557
|
+
* Refer https://axios-http.com/docs/req_config for detailed document.
|
|
1558
|
+
*
|
|
1559
|
+
* @returns Updated axios request config.
|
|
1560
|
+
*
|
|
1561
|
+
* @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when Authorization header or auth property already exists in request configuration.
|
|
1562
|
+
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
|
|
1563
|
+
*
|
|
1564
|
+
* @beta
|
|
1565
|
+
*/
|
|
1566
|
+
AddAuthenticationInfo(config) {
|
|
1567
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1568
|
+
if (config.headers && config.headers["Authorization"]) {
|
|
1569
|
+
throw new ErrorWithCode(ErrorMessage.AuthorizationHeaderAlreadyExists, exports.ErrorCode.AuthorizationInfoAlreadyExists);
|
|
1570
|
+
}
|
|
1571
|
+
if (config.auth) {
|
|
1572
|
+
throw new ErrorWithCode(ErrorMessage.BasicCredentialAlreadyExists, exports.ErrorCode.AuthorizationInfoAlreadyExists);
|
|
1573
|
+
}
|
|
1574
|
+
config.auth = {
|
|
1575
|
+
username: this.userName,
|
|
1576
|
+
password: this.password,
|
|
1577
|
+
};
|
|
1578
|
+
return config;
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
// Copyright (c) Microsoft Corporation.
|
|
1584
|
+
/**
|
|
1585
|
+
* Provider that handles API Key authentication
|
|
1586
|
+
*
|
|
1587
|
+
* @beta
|
|
1588
|
+
*/
|
|
1589
|
+
class ApiKeyProvider {
|
|
1590
|
+
/**
|
|
1591
|
+
*
|
|
1592
|
+
* @param { string } keyName - The name of request header or query parameter that specifies API Key
|
|
1593
|
+
* @param { string } keyValue - The value of API Key
|
|
1594
|
+
* @param { ApiKeyLocation } keyLocation - The location of API Key: request header or query parameter.
|
|
1595
|
+
*
|
|
1596
|
+
* @throws {@link ErrorCode|InvalidParameter} - when key name or key value is empty.
|
|
1597
|
+
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
|
|
1598
|
+
*
|
|
1599
|
+
* @beta
|
|
1600
|
+
*/
|
|
1601
|
+
constructor(keyName, keyValue, keyLocation) {
|
|
1602
|
+
if (!keyName) {
|
|
1603
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "keyName"), exports.ErrorCode.InvalidParameter);
|
|
1604
|
+
}
|
|
1605
|
+
if (!keyValue) {
|
|
1606
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "keyVaule"), exports.ErrorCode.InvalidParameter);
|
|
1607
|
+
}
|
|
1608
|
+
this.keyName = keyName;
|
|
1609
|
+
this.keyValue = keyValue;
|
|
1610
|
+
this.keyLocation = keyLocation;
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Adds authentication info to http requests
|
|
1614
|
+
*
|
|
1615
|
+
* @param { AxiosRequestConfig } config - Contains all the request information and can be updated to include extra authentication info.
|
|
1616
|
+
* Refer https://axios-http.com/docs/req_config for detailed document.
|
|
1617
|
+
*
|
|
1618
|
+
* @returns Updated axios request config.
|
|
1619
|
+
*
|
|
1620
|
+
* @throws {@link ErrorCode|AuthorizationInfoAlreadyExists} - when API key already exists in request header or url query parameter.
|
|
1621
|
+
* @throws {@link ErrorCode|RuntimeNotSupported} when runtime is browser.
|
|
1622
|
+
*
|
|
1623
|
+
* @beta
|
|
1624
|
+
*/
|
|
1625
|
+
AddAuthenticationInfo(config) {
|
|
1626
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1627
|
+
switch (this.keyLocation) {
|
|
1628
|
+
case exports.ApiKeyLocation.Header:
|
|
1629
|
+
if (!config.headers) {
|
|
1630
|
+
config.headers = {};
|
|
1631
|
+
}
|
|
1632
|
+
if (config.headers[this.keyName]) {
|
|
1633
|
+
throw new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInHeader, this.keyName), exports.ErrorCode.AuthorizationInfoAlreadyExists);
|
|
1634
|
+
}
|
|
1635
|
+
config.headers[this.keyName] = this.keyValue;
|
|
1636
|
+
break;
|
|
1637
|
+
case exports.ApiKeyLocation.QueryParams:
|
|
1638
|
+
if (!config.params) {
|
|
1639
|
+
config.params = {};
|
|
1640
|
+
}
|
|
1641
|
+
const url = new URL(config.url, config.baseURL);
|
|
1642
|
+
if (config.params[this.keyName] || url.searchParams.has(this.keyName)) {
|
|
1643
|
+
throw new ErrorWithCode(formatString(ErrorMessage.DuplicateApiKeyInQueryParam, this.keyName), exports.ErrorCode.AuthorizationInfoAlreadyExists);
|
|
1644
|
+
}
|
|
1645
|
+
config.params[this.keyName] = this.keyValue;
|
|
1646
|
+
break;
|
|
1647
|
+
}
|
|
1648
|
+
return config;
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Define available location for API Key location
|
|
1654
|
+
*
|
|
1655
|
+
* @beta
|
|
1656
|
+
*/
|
|
1657
|
+
exports.ApiKeyLocation = void 0;
|
|
1658
|
+
(function (ApiKeyLocation) {
|
|
1659
|
+
/**
|
|
1660
|
+
* The API Key is placed in request header
|
|
1661
|
+
*/
|
|
1662
|
+
ApiKeyLocation[ApiKeyLocation["Header"] = 0] = "Header";
|
|
1663
|
+
/**
|
|
1664
|
+
* The API Key is placed in query parameter
|
|
1665
|
+
*/
|
|
1666
|
+
ApiKeyLocation[ApiKeyLocation["QueryParams"] = 1] = "QueryParams";
|
|
1667
|
+
})(exports.ApiKeyLocation || (exports.ApiKeyLocation = {}));
|
|
1668
|
+
|
|
1669
|
+
// Copyright (c) Microsoft Corporation.
|
|
1670
|
+
/**
|
|
1671
|
+
* Provider that handles Certificate authentication
|
|
1672
|
+
*
|
|
1673
|
+
* @beta
|
|
1674
|
+
*/
|
|
1675
|
+
class CertificateAuthProvider {
|
|
1676
|
+
/**
|
|
1677
|
+
*
|
|
1678
|
+
* @param { SecureContextOptions } certOption - information about the cert used in http requests
|
|
1679
|
+
*
|
|
1680
|
+
* @throws {@link ErrorCode|InvalidParameter} - when cert option is empty.
|
|
1681
|
+
*
|
|
1682
|
+
* @beta
|
|
1683
|
+
*/
|
|
1684
|
+
constructor(certOption) {
|
|
1685
|
+
if (certOption && Object.keys(certOption).length !== 0) {
|
|
1686
|
+
this.certOption = certOption;
|
|
1687
|
+
}
|
|
1688
|
+
else {
|
|
1689
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "certOption"), exports.ErrorCode.InvalidParameter);
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
/**
|
|
1693
|
+
* Adds authentication info to http requests.
|
|
1694
|
+
*
|
|
1695
|
+
* @param { AxiosRequestConfig } config - Contains all the request information and can be updated to include extra authentication info.
|
|
1696
|
+
* Refer https://axios-http.com/docs/req_config for detailed document.
|
|
1697
|
+
*
|
|
1698
|
+
* @returns Updated axios request config.
|
|
1699
|
+
*
|
|
1700
|
+
* @throws {@link ErrorCode|InvalidParameter} - when custom httpsAgent in the request has duplicate properties with certOption provided in constructor.
|
|
1701
|
+
*
|
|
1702
|
+
* @beta
|
|
1703
|
+
*/
|
|
1704
|
+
AddAuthenticationInfo(config) {
|
|
1705
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1706
|
+
if (!config.httpsAgent) {
|
|
1707
|
+
config.httpsAgent = new https.Agent(this.certOption);
|
|
1708
|
+
}
|
|
1709
|
+
else {
|
|
1710
|
+
const existingProperties = new Set(Object.keys(config.httpsAgent.options));
|
|
1711
|
+
for (const property of Object.keys(this.certOption)) {
|
|
1712
|
+
if (existingProperties.has(property)) {
|
|
1713
|
+
throw new ErrorWithCode(formatString(ErrorMessage.DuplicateHttpsOptionProperty, property), exports.ErrorCode.InvalidParameter);
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
Object.assign(config.httpsAgent.options, this.certOption);
|
|
1717
|
+
}
|
|
1718
|
+
return config;
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
/**
|
|
1723
|
+
* Helper to create SecureContextOptions from PEM format cert
|
|
1724
|
+
*
|
|
1725
|
+
* @param { string | Buffer } cert - The cert chain in PEM format
|
|
1726
|
+
* @param { string | Buffer } key - The private key for the cert chain
|
|
1727
|
+
* @param { {passphrase?: string; ca?: string | Buffer} } options - Optional settings when create the cert options.
|
|
1728
|
+
*
|
|
1729
|
+
* @returns Instance of SecureContextOptions
|
|
1730
|
+
*
|
|
1731
|
+
* @throws {@link ErrorCode|InvalidParameter} - when any parameter is empty
|
|
1732
|
+
*
|
|
1733
|
+
*/
|
|
1734
|
+
function createPemCertOption(cert, key, options) {
|
|
1735
|
+
if (cert.length === 0) {
|
|
1736
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "cert"), exports.ErrorCode.InvalidParameter);
|
|
1737
|
+
}
|
|
1738
|
+
if (key.length === 0) {
|
|
1739
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "key"), exports.ErrorCode.InvalidParameter);
|
|
1740
|
+
}
|
|
1741
|
+
return {
|
|
1742
|
+
cert,
|
|
1743
|
+
key,
|
|
1744
|
+
passphrase: options === null || options === void 0 ? void 0 : options.passphrase,
|
|
1745
|
+
ca: options === null || options === void 0 ? void 0 : options.ca,
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* Helper to create SecureContextOptions from PFX format cert
|
|
1750
|
+
*
|
|
1751
|
+
* @param { string | Buffer } pfx - The content of .pfx file
|
|
1752
|
+
* @param { {passphrase?: string} } options - Optional settings when create the cert options.
|
|
1753
|
+
*
|
|
1754
|
+
* @returns Instance of SecureContextOptions
|
|
1755
|
+
*
|
|
1756
|
+
* @throws {@link ErrorCode|InvalidParameter} - when any parameter is empty
|
|
1757
|
+
*
|
|
1758
|
+
*/
|
|
1759
|
+
function createPfxCertOption(pfx, options) {
|
|
1760
|
+
if (pfx.length === 0) {
|
|
1761
|
+
throw new ErrorWithCode(formatString(ErrorMessage.EmptyParameter, "pfx"), exports.ErrorCode.InvalidParameter);
|
|
1762
|
+
}
|
|
1763
|
+
return {
|
|
1764
|
+
pfx,
|
|
1765
|
+
passphrase: options === null || options === void 0 ? void 0 : options.passphrase,
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
|
|
1769
|
+
// Copyright (c) Microsoft Corporation.
|
|
1770
|
+
// Following keys are used by SDK internally
|
|
1771
|
+
const ReservedKey = new Set([
|
|
1772
|
+
"authorityHost",
|
|
1773
|
+
"tenantId",
|
|
1774
|
+
"clientId",
|
|
1775
|
+
"clientSecret",
|
|
1776
|
+
"initiateLoginEndpoint",
|
|
1777
|
+
"applicationIdUri",
|
|
1778
|
+
"apiEndpoint",
|
|
1779
|
+
"apiName",
|
|
1780
|
+
"sqlServerEndpoint",
|
|
1781
|
+
"sqlUsername",
|
|
1782
|
+
"sqlPassword",
|
|
1783
|
+
"sqlDatabaseName",
|
|
1784
|
+
"sqlIdentityId",
|
|
1785
|
+
]);
|
|
1420
1786
|
/**
|
|
1421
1787
|
* A class providing credential and configuration.
|
|
1422
1788
|
* @beta
|
|
@@ -1594,24 +1960,1038 @@ class TeamsFx {
|
|
|
1594
1960
|
this.configuration.set("sqlDatabaseName", env.SQL_DATABASE_NAME);
|
|
1595
1961
|
this.configuration.set("sqlIdentityId", env.IDENTITY_ID);
|
|
1596
1962
|
Object.keys(env).forEach((key) => {
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1963
|
+
if (ReservedKey.has(key)) {
|
|
1964
|
+
internalLogger.warn(`The name of environment variable ${key} is preserved. Will not load it as configuration.`);
|
|
1965
|
+
}
|
|
1966
|
+
this.configuration.set(key, env[key]);
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
// Copyright (c) Microsoft Corporation.
|
|
1972
|
+
/**
|
|
1973
|
+
* @internal
|
|
1974
|
+
*/
|
|
1975
|
+
var ActivityType;
|
|
1976
|
+
(function (ActivityType) {
|
|
1977
|
+
ActivityType[ActivityType["CurrentBotInstalled"] = 0] = "CurrentBotInstalled";
|
|
1978
|
+
ActivityType[ActivityType["CurrentBotMessaged"] = 1] = "CurrentBotMessaged";
|
|
1979
|
+
ActivityType[ActivityType["CurrentBotUninstalled"] = 2] = "CurrentBotUninstalled";
|
|
1980
|
+
ActivityType[ActivityType["TeamDeleted"] = 3] = "TeamDeleted";
|
|
1981
|
+
ActivityType[ActivityType["TeamRestored"] = 4] = "TeamRestored";
|
|
1982
|
+
ActivityType[ActivityType["Unknown"] = 5] = "Unknown";
|
|
1983
|
+
})(ActivityType || (ActivityType = {}));
|
|
1984
|
+
/**
|
|
1985
|
+
* @internal
|
|
1986
|
+
*/
|
|
1987
|
+
class NotificationMiddleware {
|
|
1988
|
+
constructor(options) {
|
|
1989
|
+
this.conversationReferenceStore = options.conversationReferenceStore;
|
|
1990
|
+
}
|
|
1991
|
+
onTurn(context, next) {
|
|
1992
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
1993
|
+
const type = this.classifyActivity(context.activity);
|
|
1994
|
+
switch (type) {
|
|
1995
|
+
case ActivityType.CurrentBotInstalled:
|
|
1996
|
+
case ActivityType.TeamRestored: {
|
|
1997
|
+
const reference = botbuilder.TurnContext.getConversationReference(context.activity);
|
|
1998
|
+
yield this.conversationReferenceStore.set(reference);
|
|
1999
|
+
break;
|
|
2000
|
+
}
|
|
2001
|
+
case ActivityType.CurrentBotUninstalled:
|
|
2002
|
+
case ActivityType.TeamDeleted: {
|
|
2003
|
+
const reference = botbuilder.TurnContext.getConversationReference(context.activity);
|
|
2004
|
+
yield this.conversationReferenceStore.delete(reference);
|
|
2005
|
+
break;
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
yield next();
|
|
2009
|
+
});
|
|
2010
|
+
}
|
|
2011
|
+
classifyActivity(activity) {
|
|
2012
|
+
var _a, _b;
|
|
2013
|
+
const activityType = activity.type;
|
|
2014
|
+
if (activityType === "installationUpdate") {
|
|
2015
|
+
const action = (_a = activity.action) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
2016
|
+
if (action === "add") {
|
|
2017
|
+
return ActivityType.CurrentBotInstalled;
|
|
1600
2018
|
}
|
|
2019
|
+
else {
|
|
2020
|
+
return ActivityType.CurrentBotUninstalled;
|
|
2021
|
+
}
|
|
2022
|
+
}
|
|
2023
|
+
else if (activityType === "conversationUpdate") {
|
|
2024
|
+
const eventType = (_b = activity.channelData) === null || _b === void 0 ? void 0 : _b.eventType;
|
|
2025
|
+
if (eventType === "teamDeleted") {
|
|
2026
|
+
return ActivityType.TeamDeleted;
|
|
2027
|
+
}
|
|
2028
|
+
else if (eventType === "teamRestored") {
|
|
2029
|
+
return ActivityType.TeamRestored;
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
return ActivityType.Unknown;
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
class CommandResponseMiddleware {
|
|
2036
|
+
constructor(handlers) {
|
|
2037
|
+
this.commandHandlers = [];
|
|
2038
|
+
if (handlers && handlers.length > 0) {
|
|
2039
|
+
this.commandHandlers.push(...handlers);
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
onTurn(context, next) {
|
|
2043
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2044
|
+
const type = this.classifyActivity(context.activity);
|
|
2045
|
+
switch (type) {
|
|
2046
|
+
case ActivityType.CurrentBotMessaged:
|
|
2047
|
+
// Invoke corresponding command handler for the command response
|
|
2048
|
+
const commandText = this.getActivityText(context.activity);
|
|
2049
|
+
const message = {
|
|
2050
|
+
text: commandText,
|
|
2051
|
+
};
|
|
2052
|
+
for (const handler of this.commandHandlers) {
|
|
2053
|
+
const matchResult = this.shouldTrigger(handler.triggerPatterns, commandText);
|
|
2054
|
+
// It is important to note that the command bot will stop processing handlers
|
|
2055
|
+
// when the first command handler is matched.
|
|
2056
|
+
if (!!matchResult) {
|
|
2057
|
+
message.matches = Array.isArray(matchResult) ? matchResult : void 0;
|
|
2058
|
+
const response = yield handler.handleCommandReceived(context, message);
|
|
2059
|
+
yield context.sendActivity(response);
|
|
2060
|
+
break;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
break;
|
|
2064
|
+
}
|
|
2065
|
+
yield next();
|
|
1601
2066
|
});
|
|
1602
2067
|
}
|
|
2068
|
+
classifyActivity(activity) {
|
|
2069
|
+
if (activity.type === botbuilder.ActivityTypes.Message) {
|
|
2070
|
+
return ActivityType.CurrentBotMessaged;
|
|
2071
|
+
}
|
|
2072
|
+
return ActivityType.Unknown;
|
|
2073
|
+
}
|
|
2074
|
+
matchPattern(pattern, text) {
|
|
2075
|
+
if (text) {
|
|
2076
|
+
if (typeof pattern === "string") {
|
|
2077
|
+
const regExp = new RegExp(pattern, "i");
|
|
2078
|
+
return regExp.test(text);
|
|
2079
|
+
}
|
|
2080
|
+
if (pattern instanceof RegExp) {
|
|
2081
|
+
const matches = text.match(pattern);
|
|
2082
|
+
return matches !== null && matches !== void 0 ? matches : false;
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
return false;
|
|
2086
|
+
}
|
|
2087
|
+
shouldTrigger(patterns, text) {
|
|
2088
|
+
const expressions = Array.isArray(patterns) ? patterns : [patterns];
|
|
2089
|
+
for (const ex of expressions) {
|
|
2090
|
+
const arg = this.matchPattern(ex, text);
|
|
2091
|
+
if (arg)
|
|
2092
|
+
return arg;
|
|
2093
|
+
}
|
|
2094
|
+
return false;
|
|
2095
|
+
}
|
|
2096
|
+
getActivityText(activity) {
|
|
2097
|
+
let text = activity.text;
|
|
2098
|
+
const removedMentionText = botbuilder.TurnContext.removeRecipientMention(activity);
|
|
2099
|
+
if (removedMentionText) {
|
|
2100
|
+
text = removedMentionText
|
|
2101
|
+
.toLowerCase()
|
|
2102
|
+
.replace(/\n|\r\n/g, "")
|
|
2103
|
+
.trim();
|
|
2104
|
+
}
|
|
2105
|
+
return text;
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
|
|
2109
|
+
// Copyright (c) Microsoft Corporation.
|
|
2110
|
+
/**
|
|
2111
|
+
* A command bot for receiving commands and sending responses in Teams.
|
|
2112
|
+
*
|
|
2113
|
+
* @remarks
|
|
2114
|
+
* 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.
|
|
2115
|
+
*
|
|
2116
|
+
* @beta
|
|
2117
|
+
*/
|
|
2118
|
+
class CommandBot {
|
|
2119
|
+
/**
|
|
2120
|
+
* Creates a new instance of the `CommandBot`.
|
|
2121
|
+
*
|
|
2122
|
+
* @param adapter The bound `BotFrameworkAdapter`.
|
|
2123
|
+
* @param options - initialize options
|
|
2124
|
+
*
|
|
2125
|
+
* @beta
|
|
2126
|
+
*/
|
|
2127
|
+
constructor(adapter, options) {
|
|
2128
|
+
this.middleware = new CommandResponseMiddleware(options === null || options === void 0 ? void 0 : options.commands);
|
|
2129
|
+
this.adapter = adapter.use(this.middleware);
|
|
2130
|
+
}
|
|
2131
|
+
/**
|
|
2132
|
+
* Registers a command into the command bot.
|
|
2133
|
+
*
|
|
2134
|
+
* @param command The command to registered.
|
|
2135
|
+
*
|
|
2136
|
+
* @beta
|
|
2137
|
+
*/
|
|
2138
|
+
registerCommand(command) {
|
|
2139
|
+
if (command) {
|
|
2140
|
+
this.middleware.commandHandlers.push(command);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Registers commands into the command bot.
|
|
2145
|
+
*
|
|
2146
|
+
* @param commands The command to registered.
|
|
2147
|
+
*
|
|
2148
|
+
* @beta
|
|
2149
|
+
*/
|
|
2150
|
+
registerCommands(commands) {
|
|
2151
|
+
if (commands) {
|
|
2152
|
+
this.middleware.commandHandlers.push(...commands);
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
// Copyright (c) Microsoft Corporation.
|
|
2158
|
+
/**
|
|
2159
|
+
* @internal
|
|
2160
|
+
*/
|
|
2161
|
+
class LocalFileStorage {
|
|
2162
|
+
constructor(fileDir) {
|
|
2163
|
+
this.localFileName = ".notification.localstore.json";
|
|
2164
|
+
this.filePath = path__namespace.resolve(fileDir, this.localFileName);
|
|
2165
|
+
}
|
|
2166
|
+
read(key) {
|
|
2167
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2168
|
+
if (!(yield this.storeFileExists())) {
|
|
2169
|
+
return undefined;
|
|
2170
|
+
}
|
|
2171
|
+
const data = yield this.readFromFile();
|
|
2172
|
+
return data[key];
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
list() {
|
|
2176
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2177
|
+
if (!(yield this.storeFileExists())) {
|
|
2178
|
+
return [];
|
|
2179
|
+
}
|
|
2180
|
+
const data = yield this.readFromFile();
|
|
2181
|
+
return Object.entries(data).map((entry) => entry[1]);
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
write(key, object) {
|
|
2185
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2186
|
+
if (!(yield this.storeFileExists())) {
|
|
2187
|
+
yield this.writeToFile({ [key]: object });
|
|
2188
|
+
return;
|
|
2189
|
+
}
|
|
2190
|
+
const data = yield this.readFromFile();
|
|
2191
|
+
yield this.writeToFile(Object.assign(data, { [key]: object }));
|
|
2192
|
+
});
|
|
2193
|
+
}
|
|
2194
|
+
delete(key) {
|
|
2195
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2196
|
+
if (yield this.storeFileExists()) {
|
|
2197
|
+
const data = yield this.readFromFile();
|
|
2198
|
+
if (data[key] !== undefined) {
|
|
2199
|
+
delete data[key];
|
|
2200
|
+
yield this.writeToFile(data);
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
});
|
|
2204
|
+
}
|
|
2205
|
+
storeFileExists() {
|
|
2206
|
+
return new Promise((resolve) => {
|
|
2207
|
+
try {
|
|
2208
|
+
fs__namespace.access(this.filePath, (err) => {
|
|
2209
|
+
if (err) {
|
|
2210
|
+
resolve(false);
|
|
2211
|
+
}
|
|
2212
|
+
else {
|
|
2213
|
+
resolve(true);
|
|
2214
|
+
}
|
|
2215
|
+
});
|
|
2216
|
+
}
|
|
2217
|
+
catch (error) {
|
|
2218
|
+
resolve(false);
|
|
2219
|
+
}
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
readFromFile() {
|
|
2223
|
+
return new Promise((resolve, reject) => {
|
|
2224
|
+
try {
|
|
2225
|
+
fs__namespace.readFile(this.filePath, { encoding: "utf-8" }, (err, rawData) => {
|
|
2226
|
+
if (err) {
|
|
2227
|
+
reject(err);
|
|
2228
|
+
}
|
|
2229
|
+
else {
|
|
2230
|
+
resolve(JSON.parse(rawData));
|
|
2231
|
+
}
|
|
2232
|
+
});
|
|
2233
|
+
}
|
|
2234
|
+
catch (error) {
|
|
2235
|
+
reject(error);
|
|
2236
|
+
}
|
|
2237
|
+
});
|
|
2238
|
+
}
|
|
2239
|
+
writeToFile(data) {
|
|
2240
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2241
|
+
return new Promise((resolve, reject) => {
|
|
2242
|
+
try {
|
|
2243
|
+
const rawData = JSON.stringify(data, undefined, 2);
|
|
2244
|
+
fs__namespace.writeFile(this.filePath, rawData, { encoding: "utf-8" }, (err) => {
|
|
2245
|
+
if (err) {
|
|
2246
|
+
reject(err);
|
|
2247
|
+
}
|
|
2248
|
+
else {
|
|
2249
|
+
resolve();
|
|
2250
|
+
}
|
|
2251
|
+
});
|
|
2252
|
+
}
|
|
2253
|
+
catch (error) {
|
|
2254
|
+
reject(error);
|
|
2255
|
+
}
|
|
2256
|
+
});
|
|
2257
|
+
});
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
/**
|
|
2261
|
+
* @internal
|
|
2262
|
+
*/
|
|
2263
|
+
class ConversationReferenceStore {
|
|
2264
|
+
constructor(storage) {
|
|
2265
|
+
this.storage = storage;
|
|
2266
|
+
}
|
|
2267
|
+
check(reference) {
|
|
2268
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2269
|
+
const ref = yield this.storage.read(this.getKey(reference));
|
|
2270
|
+
return ref !== undefined;
|
|
2271
|
+
});
|
|
2272
|
+
}
|
|
2273
|
+
getAll() {
|
|
2274
|
+
return this.storage.list();
|
|
2275
|
+
}
|
|
2276
|
+
set(reference) {
|
|
2277
|
+
return this.storage.write(this.getKey(reference), reference);
|
|
2278
|
+
}
|
|
2279
|
+
delete(reference) {
|
|
2280
|
+
return this.storage.delete(this.getKey(reference));
|
|
2281
|
+
}
|
|
2282
|
+
getKey(reference) {
|
|
2283
|
+
var _a, _b;
|
|
2284
|
+
return `_${(_a = reference.conversation) === null || _a === void 0 ? void 0 : _a.tenantId}_${(_b = reference.conversation) === null || _b === void 0 ? void 0 : _b.id}`;
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
|
|
2288
|
+
// Copyright (c) Microsoft Corporation.
|
|
2289
|
+
// Licensed under the MIT license.
|
|
2290
|
+
/**
|
|
2291
|
+
* @internal
|
|
2292
|
+
*/
|
|
2293
|
+
function cloneConversation(conversation) {
|
|
2294
|
+
return Object.assign({}, conversation);
|
|
2295
|
+
}
|
|
2296
|
+
/**
|
|
2297
|
+
* @internal
|
|
2298
|
+
*/
|
|
2299
|
+
function getTargetType(conversationReference) {
|
|
2300
|
+
var _a;
|
|
2301
|
+
const conversationType = (_a = conversationReference.conversation) === null || _a === void 0 ? void 0 : _a.conversationType;
|
|
2302
|
+
if (conversationType === "personal") {
|
|
2303
|
+
return "Person";
|
|
2304
|
+
}
|
|
2305
|
+
else if (conversationType === "groupChat") {
|
|
2306
|
+
return "Group";
|
|
2307
|
+
}
|
|
2308
|
+
else if (conversationType === "channel") {
|
|
2309
|
+
return "Channel";
|
|
2310
|
+
}
|
|
2311
|
+
else {
|
|
2312
|
+
return undefined;
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
/**
|
|
2316
|
+
* @internal
|
|
2317
|
+
*/
|
|
2318
|
+
function getTeamsBotInstallationId(context) {
|
|
2319
|
+
var _a, _b, _c, _d;
|
|
2320
|
+
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;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
// Copyright (c) Microsoft Corporation.
|
|
2324
|
+
/**
|
|
2325
|
+
* Send a plain text message to a notification target.
|
|
2326
|
+
*
|
|
2327
|
+
* @param target - the notification target.
|
|
2328
|
+
* @param text - the plain text message.
|
|
2329
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2330
|
+
*
|
|
2331
|
+
* @beta
|
|
2332
|
+
*/
|
|
2333
|
+
function sendMessage(target, text) {
|
|
2334
|
+
return target.sendMessage(text);
|
|
2335
|
+
}
|
|
2336
|
+
/**
|
|
2337
|
+
* Send an adaptive card message to a notification target.
|
|
2338
|
+
*
|
|
2339
|
+
* @param target - the notification target.
|
|
2340
|
+
* @param card - the adaptive card raw JSON.
|
|
2341
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2342
|
+
*
|
|
2343
|
+
* @beta
|
|
2344
|
+
*/
|
|
2345
|
+
function sendAdaptiveCard(target, card) {
|
|
2346
|
+
return target.sendAdaptiveCard(card);
|
|
2347
|
+
}
|
|
2348
|
+
/**
|
|
2349
|
+
* A {@link NotificationTarget} that represents a team channel.
|
|
2350
|
+
*
|
|
2351
|
+
* @remarks
|
|
2352
|
+
* It's recommended to get channels from {@link TeamsBotInstallation.channels()}.
|
|
2353
|
+
*
|
|
2354
|
+
* @beta
|
|
2355
|
+
*/
|
|
2356
|
+
class Channel {
|
|
2357
|
+
/**
|
|
2358
|
+
* Constuctor.
|
|
2359
|
+
*
|
|
2360
|
+
* @remarks
|
|
2361
|
+
* It's recommended to get channels from {@link TeamsBotInstallation.channels()}, instead of using this constructor.
|
|
2362
|
+
*
|
|
2363
|
+
* @param parent - The parent {@link TeamsBotInstallation} where this channel is created from.
|
|
2364
|
+
* @param info - Detailed channel information.
|
|
2365
|
+
*
|
|
2366
|
+
* @beta
|
|
2367
|
+
*/
|
|
2368
|
+
constructor(parent, info) {
|
|
2369
|
+
/**
|
|
2370
|
+
* Notification target type. For channel it's always "Channel".
|
|
2371
|
+
*
|
|
2372
|
+
* @beta
|
|
2373
|
+
*/
|
|
2374
|
+
this.type = "Channel";
|
|
2375
|
+
this.parent = parent;
|
|
2376
|
+
this.info = info;
|
|
2377
|
+
}
|
|
2378
|
+
/**
|
|
2379
|
+
* Send a plain text message.
|
|
2380
|
+
*
|
|
2381
|
+
* @param text - the plain text message.
|
|
2382
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2383
|
+
*
|
|
2384
|
+
* @beta
|
|
2385
|
+
*/
|
|
2386
|
+
sendMessage(text) {
|
|
2387
|
+
return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2388
|
+
const conversation = yield this.newConversation(context);
|
|
2389
|
+
yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2390
|
+
yield ctx.sendActivity(text);
|
|
2391
|
+
}));
|
|
2392
|
+
}));
|
|
2393
|
+
}
|
|
2394
|
+
/**
|
|
2395
|
+
* Send an adaptive card message.
|
|
2396
|
+
*
|
|
2397
|
+
* @param card - the adaptive card raw JSON.
|
|
2398
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2399
|
+
*
|
|
2400
|
+
* @beta
|
|
2401
|
+
*/
|
|
2402
|
+
sendAdaptiveCard(card) {
|
|
2403
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2404
|
+
return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2405
|
+
const conversation = yield this.newConversation(context);
|
|
2406
|
+
yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2407
|
+
yield ctx.sendActivity({
|
|
2408
|
+
attachments: [botbuilder.CardFactory.adaptiveCard(card)],
|
|
2409
|
+
});
|
|
2410
|
+
}));
|
|
2411
|
+
}));
|
|
2412
|
+
});
|
|
2413
|
+
}
|
|
2414
|
+
/**
|
|
2415
|
+
* @internal
|
|
2416
|
+
*/
|
|
2417
|
+
newConversation(context) {
|
|
2418
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2419
|
+
const reference = botbuilder.TurnContext.getConversationReference(context.activity);
|
|
2420
|
+
const channelConversation = cloneConversation(reference);
|
|
2421
|
+
channelConversation.conversation.id = this.info.id || "";
|
|
2422
|
+
return channelConversation;
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
/**
|
|
2427
|
+
* A {@link NotificationTarget} that represents a team member.
|
|
2428
|
+
*
|
|
2429
|
+
* @remarks
|
|
2430
|
+
* It's recommended to get members from {@link TeamsBotInstallation.members()}.
|
|
2431
|
+
*
|
|
2432
|
+
* @beta
|
|
2433
|
+
*/
|
|
2434
|
+
class Member {
|
|
2435
|
+
/**
|
|
2436
|
+
* Constuctor.
|
|
2437
|
+
*
|
|
2438
|
+
* @remarks
|
|
2439
|
+
* It's recommended to get members from {@link TeamsBotInstallation.members()}, instead of using this constructor.
|
|
2440
|
+
*
|
|
2441
|
+
* @param parent - The parent {@link TeamsBotInstallation} where this member is created from.
|
|
2442
|
+
* @param account - Detailed member account information.
|
|
2443
|
+
*
|
|
2444
|
+
* @beta
|
|
2445
|
+
*/
|
|
2446
|
+
constructor(parent, account) {
|
|
2447
|
+
/**
|
|
2448
|
+
* Notification target type. For member it's always "Person".
|
|
2449
|
+
*
|
|
2450
|
+
* @beta
|
|
2451
|
+
*/
|
|
2452
|
+
this.type = "Person";
|
|
2453
|
+
this.parent = parent;
|
|
2454
|
+
this.account = account;
|
|
2455
|
+
}
|
|
2456
|
+
/**
|
|
2457
|
+
* Send a plain text message.
|
|
2458
|
+
*
|
|
2459
|
+
* @param text - the plain text message.
|
|
2460
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2461
|
+
*
|
|
2462
|
+
* @beta
|
|
2463
|
+
*/
|
|
2464
|
+
sendMessage(text) {
|
|
2465
|
+
return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2466
|
+
const conversation = yield this.newConversation(context);
|
|
2467
|
+
yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2468
|
+
yield ctx.sendActivity(text);
|
|
2469
|
+
}));
|
|
2470
|
+
}));
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Send an adaptive card message.
|
|
2474
|
+
*
|
|
2475
|
+
* @param card - the adaptive card raw JSON.
|
|
2476
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2477
|
+
*
|
|
2478
|
+
* @beta
|
|
2479
|
+
*/
|
|
2480
|
+
sendAdaptiveCard(card) {
|
|
2481
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2482
|
+
return this.parent.adapter.continueConversation(this.parent.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2483
|
+
const conversation = yield this.newConversation(context);
|
|
2484
|
+
yield this.parent.adapter.continueConversation(conversation, (ctx) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2485
|
+
yield ctx.sendActivity({
|
|
2486
|
+
attachments: [botbuilder.CardFactory.adaptiveCard(card)],
|
|
2487
|
+
});
|
|
2488
|
+
}));
|
|
2489
|
+
}));
|
|
2490
|
+
});
|
|
2491
|
+
}
|
|
2492
|
+
/**
|
|
2493
|
+
* @internal
|
|
2494
|
+
*/
|
|
2495
|
+
newConversation(context) {
|
|
2496
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2497
|
+
const reference = botbuilder.TurnContext.getConversationReference(context.activity);
|
|
2498
|
+
const personalConversation = cloneConversation(reference);
|
|
2499
|
+
const connectorClient = context.turnState.get(this.parent.adapter.ConnectorClientKey);
|
|
2500
|
+
const conversation = yield connectorClient.conversations.createConversation({
|
|
2501
|
+
isGroup: false,
|
|
2502
|
+
tenantId: context.activity.conversation.tenantId,
|
|
2503
|
+
bot: context.activity.recipient,
|
|
2504
|
+
members: [this.account],
|
|
2505
|
+
channelData: {},
|
|
2506
|
+
});
|
|
2507
|
+
personalConversation.conversation.id = conversation.id;
|
|
2508
|
+
return personalConversation;
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
/**
|
|
2513
|
+
* A {@link NotificationTarget} that represents a bot installation. Teams Bot could be installed into
|
|
2514
|
+
* - Personal chat
|
|
2515
|
+
* - Group chat
|
|
2516
|
+
* - Team (by default the `General` channel)
|
|
2517
|
+
*
|
|
2518
|
+
* @remarks
|
|
2519
|
+
* It's recommended to get bot installations from {@link ConversationBot.installations()}.
|
|
2520
|
+
*
|
|
2521
|
+
* @beta
|
|
2522
|
+
*/
|
|
2523
|
+
class TeamsBotInstallation {
|
|
2524
|
+
/**
|
|
2525
|
+
* Constructor
|
|
2526
|
+
*
|
|
2527
|
+
* @remarks
|
|
2528
|
+
* It's recommended to get bot installations from {@link ConversationBot.installations()}, instead of using this constructor.
|
|
2529
|
+
*
|
|
2530
|
+
* @param adapter - the bound `BotFrameworkAdapter`.
|
|
2531
|
+
* @param conversationReference - the bound `ConversationReference`.
|
|
2532
|
+
*
|
|
2533
|
+
* @beta
|
|
2534
|
+
*/
|
|
2535
|
+
constructor(adapter, conversationReference) {
|
|
2536
|
+
this.adapter = adapter;
|
|
2537
|
+
this.conversationReference = conversationReference;
|
|
2538
|
+
this.type = getTargetType(conversationReference);
|
|
2539
|
+
}
|
|
2540
|
+
/**
|
|
2541
|
+
* Send a plain text message.
|
|
2542
|
+
*
|
|
2543
|
+
* @param text - the plain text message.
|
|
2544
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2545
|
+
*
|
|
2546
|
+
* @beta
|
|
2547
|
+
*/
|
|
2548
|
+
sendMessage(text) {
|
|
2549
|
+
return this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2550
|
+
yield context.sendActivity(text);
|
|
2551
|
+
}));
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Send an adaptive card message.
|
|
2555
|
+
*
|
|
2556
|
+
* @param card - the adaptive card raw JSON.
|
|
2557
|
+
* @returns A `Promise` representing the asynchronous operation.
|
|
2558
|
+
*
|
|
2559
|
+
* @beta
|
|
2560
|
+
*/
|
|
2561
|
+
sendAdaptiveCard(card) {
|
|
2562
|
+
return this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2563
|
+
yield context.sendActivity({
|
|
2564
|
+
attachments: [botbuilder.CardFactory.adaptiveCard(card)],
|
|
2565
|
+
});
|
|
2566
|
+
}));
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Get channels from this bot installation.
|
|
2570
|
+
*
|
|
2571
|
+
* @returns an array of channels if bot is installed into a team, otherwise returns an empty array.
|
|
2572
|
+
*
|
|
2573
|
+
* @beta
|
|
2574
|
+
*/
|
|
2575
|
+
channels() {
|
|
2576
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2577
|
+
let teamsChannels = [];
|
|
2578
|
+
yield this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2579
|
+
const teamId = getTeamsBotInstallationId(context);
|
|
2580
|
+
if (teamId !== undefined) {
|
|
2581
|
+
teamsChannels = yield botbuilder.TeamsInfo.getTeamChannels(context, teamId);
|
|
2582
|
+
}
|
|
2583
|
+
}));
|
|
2584
|
+
const channels = [];
|
|
2585
|
+
for (const channel of teamsChannels) {
|
|
2586
|
+
channels.push(new Channel(this, channel));
|
|
2587
|
+
}
|
|
2588
|
+
return channels;
|
|
2589
|
+
});
|
|
2590
|
+
}
|
|
2591
|
+
/**
|
|
2592
|
+
* Get members from this bot installation.
|
|
2593
|
+
*
|
|
2594
|
+
* @returns an array of members from where the bot is installed.
|
|
2595
|
+
*
|
|
2596
|
+
* @beta
|
|
2597
|
+
*/
|
|
2598
|
+
members() {
|
|
2599
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2600
|
+
const members = [];
|
|
2601
|
+
yield this.adapter.continueConversation(this.conversationReference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2602
|
+
let continuationToken;
|
|
2603
|
+
do {
|
|
2604
|
+
const pagedMembers = yield botbuilder.TeamsInfo.getPagedMembers(context, undefined, continuationToken);
|
|
2605
|
+
continuationToken = pagedMembers.continuationToken;
|
|
2606
|
+
for (const member of pagedMembers.members) {
|
|
2607
|
+
members.push(new Member(this, member));
|
|
2608
|
+
}
|
|
2609
|
+
} while (continuationToken !== undefined);
|
|
2610
|
+
}));
|
|
2611
|
+
return members;
|
|
2612
|
+
});
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
/**
|
|
2616
|
+
* Provide utilities to send notification to varies targets (e.g., member, group, channel).
|
|
2617
|
+
*
|
|
2618
|
+
* @beta
|
|
2619
|
+
*/
|
|
2620
|
+
class NotificationBot {
|
|
2621
|
+
/**
|
|
2622
|
+
* constructor of the notification bot.
|
|
2623
|
+
*
|
|
2624
|
+
* @remarks
|
|
2625
|
+
* To ensure accuracy, it's recommended to initialize before handling any message.
|
|
2626
|
+
*
|
|
2627
|
+
* @param adapter - the bound `BotFrameworkAdapter`
|
|
2628
|
+
* @param options - initialize options
|
|
2629
|
+
*
|
|
2630
|
+
* @beta
|
|
2631
|
+
*/
|
|
2632
|
+
constructor(adapter, options) {
|
|
2633
|
+
var _a, _b;
|
|
2634
|
+
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 : "./" : "./"));
|
|
2635
|
+
this.conversationReferenceStore = new ConversationReferenceStore(storage);
|
|
2636
|
+
this.adapter = adapter.use(new NotificationMiddleware({
|
|
2637
|
+
conversationReferenceStore: this.conversationReferenceStore,
|
|
2638
|
+
}));
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Get all targets where the bot is installed.
|
|
2642
|
+
*
|
|
2643
|
+
* @remarks
|
|
2644
|
+
* The result is retrieving from the persisted storage.
|
|
2645
|
+
*
|
|
2646
|
+
* @returns - an array of {@link TeamsBotInstallation}.
|
|
2647
|
+
*
|
|
2648
|
+
* @beta
|
|
2649
|
+
*/
|
|
2650
|
+
installations() {
|
|
2651
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2652
|
+
if (this.conversationReferenceStore === undefined || this.adapter === undefined) {
|
|
2653
|
+
throw new Error("NotificationBot has not been initialized.");
|
|
2654
|
+
}
|
|
2655
|
+
const references = (yield this.conversationReferenceStore.getAll()).values();
|
|
2656
|
+
const targets = [];
|
|
2657
|
+
for (const reference of references) {
|
|
2658
|
+
// validate connection
|
|
2659
|
+
let valid = true;
|
|
2660
|
+
this.adapter.continueConversation(reference, (context) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2661
|
+
try {
|
|
2662
|
+
// try get member to see if the installation is still valid
|
|
2663
|
+
yield botbuilder.TeamsInfo.getPagedMembers(context, 1);
|
|
2664
|
+
}
|
|
2665
|
+
catch (error) {
|
|
2666
|
+
if (error.code === "BotNotInConversationRoster") {
|
|
2667
|
+
valid = false;
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
}));
|
|
2671
|
+
if (valid) {
|
|
2672
|
+
targets.push(new TeamsBotInstallation(this.adapter, reference));
|
|
2673
|
+
}
|
|
2674
|
+
else {
|
|
2675
|
+
this.conversationReferenceStore.delete(reference);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
return targets;
|
|
2679
|
+
});
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
// Copyright (c) Microsoft Corporation.
|
|
2684
|
+
/**
|
|
2685
|
+
* Provide utilities for bot conversation, including:
|
|
2686
|
+
* - handle command and response.
|
|
2687
|
+
* - send notification to varies targets (e.g., member, group, channel).
|
|
2688
|
+
*
|
|
2689
|
+
* @example
|
|
2690
|
+
* For command and response, you can register your commands through the constructor, or use the `registerCommand` and `registerCommands` API to add commands later.
|
|
2691
|
+
*
|
|
2692
|
+
* ```typescript
|
|
2693
|
+
* // register through constructor
|
|
2694
|
+
* const conversationBot = new ConversationBot({
|
|
2695
|
+
* command: {
|
|
2696
|
+
* enabled: true,
|
|
2697
|
+
* commands: [ new HelloWorldCommandHandler() ],
|
|
2698
|
+
* },
|
|
2699
|
+
* });
|
|
2700
|
+
*
|
|
2701
|
+
* // register through `register*` API
|
|
2702
|
+
* conversationBot.command.registerCommand(new HelpCommandHandler());
|
|
2703
|
+
* ```
|
|
2704
|
+
*
|
|
2705
|
+
* For notification, you can enable notification at initialization, then send notifications at any time.
|
|
2706
|
+
*
|
|
2707
|
+
* ```typescript
|
|
2708
|
+
* // enable through constructor
|
|
2709
|
+
* const conversationBot = new ConversationBot({
|
|
2710
|
+
* notification: {
|
|
2711
|
+
* enabled: true,
|
|
2712
|
+
* },
|
|
2713
|
+
* });
|
|
2714
|
+
*
|
|
2715
|
+
* // get all bot installations and send message
|
|
2716
|
+
* for (const target of await conversationBot.notification.installations()) {
|
|
2717
|
+
* await target.sendMessage("Hello Notification");
|
|
2718
|
+
* }
|
|
2719
|
+
*
|
|
2720
|
+
* // alternative - send message to all members
|
|
2721
|
+
* for (const target of await conversationBot.notification.installations()) {
|
|
2722
|
+
* for (const member of await target.members()) {
|
|
2723
|
+
* await member.sendMessage("Hello Notification");
|
|
2724
|
+
* }
|
|
2725
|
+
* }
|
|
2726
|
+
* ```
|
|
2727
|
+
*
|
|
2728
|
+
* @remarks
|
|
2729
|
+
* Set `adapter` in {@link ConversationOptions} to use your own bot adapter.
|
|
2730
|
+
*
|
|
2731
|
+
* 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.
|
|
2732
|
+
*
|
|
2733
|
+
* For notification, set `notification.storage` in {@link ConversationOptions} to use your own storage implementation.
|
|
2734
|
+
*
|
|
2735
|
+
* @beta
|
|
2736
|
+
*/
|
|
2737
|
+
class ConversationBot {
|
|
2738
|
+
/**
|
|
2739
|
+
* Creates new instance of the `ConversationBot`.
|
|
2740
|
+
*
|
|
2741
|
+
* @remarks
|
|
2742
|
+
* It's recommended to create your own adapter and storage for production environment instead of the default one.
|
|
2743
|
+
*
|
|
2744
|
+
* @param options - initialize options
|
|
2745
|
+
*
|
|
2746
|
+
* @beta
|
|
2747
|
+
*/
|
|
2748
|
+
constructor(options) {
|
|
2749
|
+
var _a, _b;
|
|
2750
|
+
if (options.adapter) {
|
|
2751
|
+
this.adapter = options.adapter;
|
|
2752
|
+
}
|
|
2753
|
+
else {
|
|
2754
|
+
this.adapter = this.createDefaultAdapter(options.adapterConfig);
|
|
2755
|
+
}
|
|
2756
|
+
if ((_a = options.command) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
2757
|
+
this.command = new CommandBot(this.adapter, options.command);
|
|
2758
|
+
}
|
|
2759
|
+
if ((_b = options.notification) === null || _b === void 0 ? void 0 : _b.enabled) {
|
|
2760
|
+
this.notification = new NotificationBot(this.adapter, options.notification);
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
createDefaultAdapter(adapterConfig) {
|
|
2764
|
+
const adapter = adapterConfig === undefined
|
|
2765
|
+
? new botbuilder.BotFrameworkAdapter({
|
|
2766
|
+
appId: process.env.BOT_ID,
|
|
2767
|
+
appPassword: process.env.BOT_PASSWORD,
|
|
2768
|
+
})
|
|
2769
|
+
: new botbuilder.BotFrameworkAdapter(adapterConfig);
|
|
2770
|
+
// the default error handler
|
|
2771
|
+
adapter.onTurnError = (context, error) => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2772
|
+
// This check writes out errors to console.
|
|
2773
|
+
console.error(`[onTurnError] unhandled error: ${error}`);
|
|
2774
|
+
// Send a trace activity, which will be displayed in Bot Framework Emulator
|
|
2775
|
+
yield context.sendTraceActivity("OnTurnError Trace", `${error}`, "https://www.botframework.com/schemas/error", "TurnError");
|
|
2776
|
+
// Send a message to the user
|
|
2777
|
+
yield context.sendActivity(`The bot encountered unhandled error: ${error.message}`);
|
|
2778
|
+
yield context.sendActivity("To continue to run this bot, please fix the bot source code.");
|
|
2779
|
+
});
|
|
2780
|
+
return adapter;
|
|
2781
|
+
}
|
|
2782
|
+
/**
|
|
2783
|
+
* The request handler to integrate with web request.
|
|
2784
|
+
*
|
|
2785
|
+
* @param req - an Express or Restify style request object.
|
|
2786
|
+
* @param res - an Express or Restify style response object.
|
|
2787
|
+
* @param logic - the additional function to handle bot context.
|
|
2788
|
+
*
|
|
2789
|
+
* @example
|
|
2790
|
+
* For example, to use with Restify:
|
|
2791
|
+
* ``` typescript
|
|
2792
|
+
* // The default/empty behavior
|
|
2793
|
+
* server.post("api/messages", conversationBot.requestHandler);
|
|
2794
|
+
*
|
|
2795
|
+
* // Or, add your own logic
|
|
2796
|
+
* server.post("api/messages", async (req, res) => {
|
|
2797
|
+
* await conversationBot.requestHandler(req, res, async (context) => {
|
|
2798
|
+
* // your-own-context-logic
|
|
2799
|
+
* });
|
|
2800
|
+
* });
|
|
2801
|
+
* ```
|
|
2802
|
+
*
|
|
2803
|
+
* @beta
|
|
2804
|
+
*/
|
|
2805
|
+
requestHandler(req, res, logic) {
|
|
2806
|
+
return tslib.__awaiter(this, void 0, void 0, function* () {
|
|
2807
|
+
if (logic === undefined) {
|
|
2808
|
+
// create empty logic
|
|
2809
|
+
logic = () => tslib.__awaiter(this, void 0, void 0, function* () { });
|
|
2810
|
+
}
|
|
2811
|
+
yield this.adapter.processActivity(req, res, logic);
|
|
2812
|
+
});
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
// Copyright (c) Microsoft Corporation.
|
|
2817
|
+
const { AdaptiveCards } = require("@microsoft/adaptivecards-tools");
|
|
2818
|
+
/**
|
|
2819
|
+
* Provides utility method to build bot message with cards that supported in Teams.
|
|
2820
|
+
*/
|
|
2821
|
+
class MessageBuilder {
|
|
2822
|
+
/**
|
|
2823
|
+
* Build a bot message activity attached with adaptive card.
|
|
2824
|
+
*
|
|
2825
|
+
* @param cardTemplate The adaptive card template.
|
|
2826
|
+
* @param data card data used to render the template.
|
|
2827
|
+
* @returns A bot message activity attached with an adaptive card.
|
|
2828
|
+
*
|
|
2829
|
+
* @example
|
|
2830
|
+
* ```javascript
|
|
2831
|
+
* const cardTemplate = {
|
|
2832
|
+
* type: "AdaptiveCard",
|
|
2833
|
+
* body: [
|
|
2834
|
+
* {
|
|
2835
|
+
* "type": "TextBlock",
|
|
2836
|
+
* "text": "${title}",
|
|
2837
|
+
* "size": "Large"
|
|
2838
|
+
* },
|
|
2839
|
+
* {
|
|
2840
|
+
* "type": "TextBlock",
|
|
2841
|
+
* "text": "${description}"
|
|
2842
|
+
* }],
|
|
2843
|
+
* $schema: "http://adaptivecards.io/schemas/adaptive-card.json",
|
|
2844
|
+
* version: "1.4"
|
|
2845
|
+
* };
|
|
2846
|
+
*
|
|
2847
|
+
* type CardData = {
|
|
2848
|
+
* title: string,
|
|
2849
|
+
* description: string
|
|
2850
|
+
* };
|
|
2851
|
+
* const card = MessageBuilder.attachAdaptiveCard<CardData>(
|
|
2852
|
+
* cardTemplate, {
|
|
2853
|
+
* title: "sample card title",
|
|
2854
|
+
* description: "sample card description"
|
|
2855
|
+
* });
|
|
2856
|
+
* ```
|
|
2857
|
+
*
|
|
2858
|
+
* @beta
|
|
2859
|
+
*/
|
|
2860
|
+
static attachAdaptiveCard(cardTemplate, data) {
|
|
2861
|
+
return {
|
|
2862
|
+
attachments: [botbuilder.CardFactory.adaptiveCard(AdaptiveCards.declare(cardTemplate).render(data))],
|
|
2863
|
+
};
|
|
2864
|
+
}
|
|
2865
|
+
/**
|
|
2866
|
+
* Build a bot message activity attached with an adaptive card.
|
|
2867
|
+
*
|
|
2868
|
+
* @param card The adaptive card content.
|
|
2869
|
+
* @returns A bot message activity attached with an adaptive card.
|
|
2870
|
+
*
|
|
2871
|
+
* @beta
|
|
2872
|
+
*/
|
|
2873
|
+
static attachAdaptiveCardWithoutData(card) {
|
|
2874
|
+
return {
|
|
2875
|
+
attachments: [botbuilder.CardFactory.adaptiveCard(AdaptiveCards.declareWithoutData(card).render())],
|
|
2876
|
+
};
|
|
2877
|
+
}
|
|
2878
|
+
/**
|
|
2879
|
+
* Build a bot message activity attached with an hero card.
|
|
2880
|
+
*
|
|
2881
|
+
* @param title The card title.
|
|
2882
|
+
* @param images Optional. The array of images to include on the card.
|
|
2883
|
+
* @param buttons Optional. The array of buttons to include on the card. Each `string` in the array
|
|
2884
|
+
* is converted to an `imBack` button with a title and value set to the value of the string.
|
|
2885
|
+
* @param other Optional. Any additional properties to include on the card.
|
|
2886
|
+
*
|
|
2887
|
+
* @returns A bot message activity attached with a hero card.
|
|
2888
|
+
*
|
|
2889
|
+
* @example
|
|
2890
|
+
* ```javascript
|
|
2891
|
+
* const message = MessageBuilder.attachHeroCard(
|
|
2892
|
+
* 'sample title',
|
|
2893
|
+
* ['https://example.com/sample.jpg'],
|
|
2894
|
+
* ['action']
|
|
2895
|
+
* );
|
|
2896
|
+
* ```
|
|
2897
|
+
*
|
|
2898
|
+
* @beta
|
|
2899
|
+
*/
|
|
2900
|
+
static attachHeroCard(title, images, buttons, other) {
|
|
2901
|
+
return MessageBuilder.attachContent(botbuilder.CardFactory.heroCard(title, images, buttons, other));
|
|
2902
|
+
}
|
|
2903
|
+
/**
|
|
2904
|
+
* Returns an attachment for a sign-in card.
|
|
2905
|
+
*
|
|
2906
|
+
* @param title The title for the card's sign-in button.
|
|
2907
|
+
* @param url The URL of the sign-in page to use.
|
|
2908
|
+
* @param text Optional. Additional text to include on the card.
|
|
2909
|
+
*
|
|
2910
|
+
* @returns A bot message activity attached with a sign-in card.
|
|
2911
|
+
*
|
|
2912
|
+
* @remarks
|
|
2913
|
+
* For channels that don't natively support sign-in cards, an alternative message is rendered.
|
|
2914
|
+
*
|
|
2915
|
+
* @beta
|
|
2916
|
+
*/
|
|
2917
|
+
static attachSigninCard(title, url, text) {
|
|
2918
|
+
return MessageBuilder.attachContent(botbuilder.CardFactory.signinCard(title, url, text));
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Build a bot message activity attached with an Office 365 connector card.
|
|
2922
|
+
*
|
|
2923
|
+
* @param card A description of the Office 365 connector card.
|
|
2924
|
+
* @returns A bot message activity attached with an Office 365 connector card.
|
|
2925
|
+
*
|
|
2926
|
+
* @beta
|
|
2927
|
+
*/
|
|
2928
|
+
static attachO365ConnectorCard(card) {
|
|
2929
|
+
return MessageBuilder.attachContent(botbuilder.CardFactory.o365ConnectorCard(card));
|
|
2930
|
+
}
|
|
2931
|
+
/**
|
|
2932
|
+
* Build a message activity attached with a receipt card.
|
|
2933
|
+
* @param card A description of the receipt card.
|
|
2934
|
+
* @returns A message activity attached with a receipt card.
|
|
2935
|
+
*
|
|
2936
|
+
* @beta
|
|
2937
|
+
*/
|
|
2938
|
+
static AttachReceiptCard(card) {
|
|
2939
|
+
return MessageBuilder.attachContent(botbuilder.CardFactory.receiptCard(card));
|
|
2940
|
+
}
|
|
2941
|
+
/**
|
|
2942
|
+
*
|
|
2943
|
+
* @param title The card title.
|
|
2944
|
+
* @param images Optional. The array of images to include on the card.
|
|
2945
|
+
* @param buttons Optional. The array of buttons to include on the card. Each `string` in the array
|
|
2946
|
+
* is converted to an `imBack` button with a title and value set to the value of the string.
|
|
2947
|
+
* @param other Optional. Any additional properties to include on the card.
|
|
2948
|
+
* @returns A message activity attached with a thumbnail card
|
|
2949
|
+
*
|
|
2950
|
+
* @beta
|
|
2951
|
+
*/
|
|
2952
|
+
static attachThumbnailCard(title, images, buttons, other) {
|
|
2953
|
+
return MessageBuilder.attachContent(botbuilder.CardFactory.thumbnailCard(title, images, buttons, other));
|
|
2954
|
+
}
|
|
2955
|
+
/**
|
|
2956
|
+
* Add an attachement to a bot activity.
|
|
2957
|
+
* @param attachement The attachment object to attach.
|
|
2958
|
+
* @returns A message activity with an attachment.
|
|
2959
|
+
*
|
|
2960
|
+
* @beta
|
|
2961
|
+
*/
|
|
2962
|
+
static attachContent(attachement) {
|
|
2963
|
+
return {
|
|
2964
|
+
attachments: [attachement],
|
|
2965
|
+
};
|
|
2966
|
+
}
|
|
1603
2967
|
}
|
|
1604
2968
|
|
|
2969
|
+
exports.ApiKeyProvider = ApiKeyProvider;
|
|
1605
2970
|
exports.AppCredential = AppCredential;
|
|
2971
|
+
exports.BasicAuthProvider = BasicAuthProvider;
|
|
2972
|
+
exports.BearerTokenAuthProvider = BearerTokenAuthProvider;
|
|
2973
|
+
exports.CertificateAuthProvider = CertificateAuthProvider;
|
|
2974
|
+
exports.Channel = Channel;
|
|
2975
|
+
exports.CommandBot = CommandBot;
|
|
2976
|
+
exports.ConversationBot = ConversationBot;
|
|
1606
2977
|
exports.ErrorWithCode = ErrorWithCode;
|
|
2978
|
+
exports.Member = Member;
|
|
2979
|
+
exports.MessageBuilder = MessageBuilder;
|
|
1607
2980
|
exports.MsGraphAuthProvider = MsGraphAuthProvider;
|
|
2981
|
+
exports.NotificationBot = NotificationBot;
|
|
1608
2982
|
exports.OnBehalfOfUserCredential = OnBehalfOfUserCredential;
|
|
2983
|
+
exports.TeamsBotInstallation = TeamsBotInstallation;
|
|
1609
2984
|
exports.TeamsBotSsoPrompt = TeamsBotSsoPrompt;
|
|
1610
2985
|
exports.TeamsFx = TeamsFx;
|
|
1611
2986
|
exports.TeamsUserCredential = TeamsUserCredential;
|
|
2987
|
+
exports.createApiClient = createApiClient;
|
|
1612
2988
|
exports.createMicrosoftGraphClient = createMicrosoftGraphClient;
|
|
2989
|
+
exports.createPemCertOption = createPemCertOption;
|
|
2990
|
+
exports.createPfxCertOption = createPfxCertOption;
|
|
1613
2991
|
exports.getLogLevel = getLogLevel;
|
|
1614
2992
|
exports.getTediousConnectionConfig = getTediousConnectionConfig;
|
|
2993
|
+
exports.sendAdaptiveCard = sendAdaptiveCard;
|
|
2994
|
+
exports.sendMessage = sendMessage;
|
|
1615
2995
|
exports.setLogFunction = setLogFunction;
|
|
1616
2996
|
exports.setLogLevel = setLogLevel;
|
|
1617
2997
|
exports.setLogger = setLogger;
|