@pnp/cli-microsoft365 5.0.0-beta.1d35279 → 5.0.0-beta.21e7f85
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/.eslintrc.js +1 -0
- package/dist/m365/aad/commands/app/app-set.js +98 -3
- package/dist/m365/aad/commands/o365group/o365group-conversation-list.js +41 -0
- package/dist/m365/aad/commands.js +1 -0
- package/dist/m365/outlook/commands/room/room-list.js +43 -0
- package/dist/m365/outlook/commands/roomlist/roomlist-list.js +25 -0
- package/dist/m365/outlook/commands.js +2 -0
- package/dist/m365/spo/commands/group/group-user-add.js +15 -8
- package/dist/m365/teams/commands/channel/channel-get.js +29 -7
- package/dist/m365/teams/commands/chat/chat-message-send.js +225 -0
- package/dist/m365/teams/commands.js +1 -0
- package/docs/docs/cmd/aad/app/app-set.md +21 -0
- package/docs/docs/cmd/aad/o365group/o365group-conversation-list.md +24 -0
- package/docs/docs/cmd/outlook/room/room-list.md +30 -0
- package/docs/docs/cmd/outlook/roomlist/roomlist-list.md +21 -0
- package/docs/docs/cmd/spo/group/group-user-add.md +4 -0
- package/docs/docs/cmd/teams/channel/channel-get.md +10 -1
- package/docs/docs/cmd/teams/chat/chat-message-send.md +55 -0
- package/package.json +3 -1
package/.eslintrc.js
CHANGED
|
@@ -15,6 +15,9 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
15
15
|
telemetryProps.appId = typeof args.options.appId !== 'undefined';
|
|
16
16
|
telemetryProps.objectId = typeof args.options.objectId !== 'undefined';
|
|
17
17
|
telemetryProps.name = typeof args.options.name !== 'undefined';
|
|
18
|
+
telemetryProps.platform = typeof args.options.platform !== 'undefined';
|
|
19
|
+
telemetryProps.redirectUris = typeof args.options.redirectUris !== 'undefined';
|
|
20
|
+
telemetryProps.redirectUrisToRemove = typeof args.options.redirectUrisToRemove !== 'undefined';
|
|
18
21
|
telemetryProps.uri = typeof args.options.uri !== 'undefined';
|
|
19
22
|
return telemetryProps;
|
|
20
23
|
}
|
|
@@ -22,6 +25,7 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
22
25
|
this
|
|
23
26
|
.getAppObjectId(args, logger)
|
|
24
27
|
.then(objectId => this.configureUri(args, objectId, logger))
|
|
28
|
+
.then(objectId => this.configureRedirectUris(args, objectId, logger))
|
|
25
29
|
.then(_ => cb(), (rawRes) => this.handleRejectedODataJsonPromise(rawRes, logger, cb));
|
|
26
30
|
}
|
|
27
31
|
getAppObjectId(args, logger) {
|
|
@@ -57,7 +61,7 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
57
61
|
}
|
|
58
62
|
configureUri(args, objectId, logger) {
|
|
59
63
|
if (!args.options.uri) {
|
|
60
|
-
return Promise.resolve();
|
|
64
|
+
return Promise.resolve(objectId);
|
|
61
65
|
}
|
|
62
66
|
if (this.verbose) {
|
|
63
67
|
logger.logToStderr(`Configuring Azure AD application ID URI...`);
|
|
@@ -73,14 +77,97 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
73
77
|
responseType: 'json',
|
|
74
78
|
data: applicationInfo
|
|
75
79
|
};
|
|
76
|
-
return request_1.default
|
|
80
|
+
return request_1.default
|
|
81
|
+
.patch(requestOptions)
|
|
82
|
+
.then(_ => Promise.resolve(objectId));
|
|
83
|
+
}
|
|
84
|
+
configureRedirectUris(args, objectId, logger) {
|
|
85
|
+
if (!args.options.redirectUris && !args.options.redirectUrisToRemove) {
|
|
86
|
+
return Promise.resolve(objectId);
|
|
87
|
+
}
|
|
88
|
+
if (this.verbose) {
|
|
89
|
+
logger.logToStderr(`Configuring Azure AD application redirect URIs...`);
|
|
90
|
+
}
|
|
91
|
+
const getAppRequestOptions = {
|
|
92
|
+
url: `${this.resource}/v1.0/myorganization/applications/${objectId}`,
|
|
93
|
+
headers: {
|
|
94
|
+
'content-type': 'application/json;odata.metadata=none'
|
|
95
|
+
},
|
|
96
|
+
responseType: 'json'
|
|
97
|
+
};
|
|
98
|
+
return request_1.default
|
|
99
|
+
.get(getAppRequestOptions)
|
|
100
|
+
.then((application) => {
|
|
101
|
+
const publicClientRedirectUris = application.publicClient.redirectUris;
|
|
102
|
+
const spaRedirectUris = application.spa.redirectUris;
|
|
103
|
+
const webRedirectUris = application.web.redirectUris;
|
|
104
|
+
// start with existing redirect URIs
|
|
105
|
+
const applicationPatch = {
|
|
106
|
+
publicClient: {
|
|
107
|
+
redirectUris: publicClientRedirectUris
|
|
108
|
+
},
|
|
109
|
+
spa: {
|
|
110
|
+
redirectUris: spaRedirectUris
|
|
111
|
+
},
|
|
112
|
+
web: {
|
|
113
|
+
redirectUris: webRedirectUris
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
if (args.options.redirectUrisToRemove) {
|
|
117
|
+
// remove redirect URIs from all platforms
|
|
118
|
+
const redirectUrisToRemove = args.options.redirectUrisToRemove
|
|
119
|
+
.split(',')
|
|
120
|
+
.map(u => u.trim());
|
|
121
|
+
applicationPatch.publicClient.redirectUris =
|
|
122
|
+
publicClientRedirectUris.filter(u => !redirectUrisToRemove.includes(u));
|
|
123
|
+
applicationPatch.spa.redirectUris =
|
|
124
|
+
spaRedirectUris.filter(u => !redirectUrisToRemove.includes(u));
|
|
125
|
+
applicationPatch.web.redirectUris =
|
|
126
|
+
webRedirectUris.filter(u => !redirectUrisToRemove.includes(u));
|
|
127
|
+
}
|
|
128
|
+
if (args.options.redirectUris) {
|
|
129
|
+
const urlsToAdd = args.options.redirectUris
|
|
130
|
+
.split(',')
|
|
131
|
+
.map(u => u.trim());
|
|
132
|
+
// add new redirect URIs. If the URI is already present, it will be ignored
|
|
133
|
+
switch (args.options.platform) {
|
|
134
|
+
case 'spa':
|
|
135
|
+
applicationPatch.spa.redirectUris
|
|
136
|
+
.push(...urlsToAdd.filter(u => !spaRedirectUris.includes(u)));
|
|
137
|
+
break;
|
|
138
|
+
case 'publicClient':
|
|
139
|
+
applicationPatch.publicClient.redirectUris
|
|
140
|
+
.push(...urlsToAdd.filter(u => !publicClientRedirectUris.includes(u)));
|
|
141
|
+
break;
|
|
142
|
+
case 'web':
|
|
143
|
+
applicationPatch.web.redirectUris
|
|
144
|
+
.push(...urlsToAdd.filter(u => !webRedirectUris.includes(u)));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const requestOptions = {
|
|
148
|
+
url: `${this.resource}/v1.0/myorganization/applications/${objectId}`,
|
|
149
|
+
headers: {
|
|
150
|
+
'content-type': 'application/json;odata.metadata=none'
|
|
151
|
+
},
|
|
152
|
+
responseType: 'json',
|
|
153
|
+
data: applicationPatch
|
|
154
|
+
};
|
|
155
|
+
return request_1.default.patch(requestOptions);
|
|
156
|
+
})
|
|
157
|
+
.then(_ => Promise.resolve(objectId));
|
|
77
158
|
}
|
|
78
159
|
options() {
|
|
79
160
|
const options = [
|
|
80
161
|
{ option: '--appId [appId]' },
|
|
81
162
|
{ option: '--objectId [objectId]' },
|
|
82
163
|
{ option: '-n, --name [name]' },
|
|
83
|
-
{ option: '-u, --uri [uri]' }
|
|
164
|
+
{ option: '-u, --uri [uri]' },
|
|
165
|
+
{ option: '-r, --redirectUris [redirectUris]' },
|
|
166
|
+
{
|
|
167
|
+
option: '--platform [platform]',
|
|
168
|
+
autocomplete: AadAppSetCommand.aadApplicationPlatform
|
|
169
|
+
},
|
|
170
|
+
{ option: '--redirectUrisToRemove [redirectUrisToRemove]' }
|
|
84
171
|
];
|
|
85
172
|
const parentOptions = super.options();
|
|
86
173
|
return options.concat(parentOptions);
|
|
@@ -96,8 +183,16 @@ class AadAppSetCommand extends GraphCommand_1.default {
|
|
|
96
183
|
(args.options.objectId && args.options.name)) {
|
|
97
184
|
return 'Specify either appId, objectId or name but not both';
|
|
98
185
|
}
|
|
186
|
+
if (args.options.redirectUris && !args.options.platform) {
|
|
187
|
+
return `When you specify redirectUris you also need to specify platform`;
|
|
188
|
+
}
|
|
189
|
+
if (args.options.platform &&
|
|
190
|
+
AadAppSetCommand.aadApplicationPlatform.indexOf(args.options.platform) < 0) {
|
|
191
|
+
return `${args.options.platform} is not a valid value for platform. Allowed values are ${AadAppSetCommand.aadApplicationPlatform.join(', ')}`;
|
|
192
|
+
}
|
|
99
193
|
return true;
|
|
100
194
|
}
|
|
101
195
|
}
|
|
196
|
+
AadAppSetCommand.aadApplicationPlatform = ['spa', 'web', 'publicClient'];
|
|
102
197
|
module.exports = new AadAppSetCommand();
|
|
103
198
|
//# sourceMappingURL=app-set.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Utils_1 = require("../../../../Utils");
|
|
4
|
+
const GraphItemsListCommand_1 = require("../../../base/GraphItemsListCommand");
|
|
5
|
+
const commands_1 = require("../../commands");
|
|
6
|
+
class AadO365GroupConversationListCommand extends GraphItemsListCommand_1.GraphItemsListCommand {
|
|
7
|
+
get name() {
|
|
8
|
+
return commands_1.default.O365GROUP_CONVERSATION_LIST;
|
|
9
|
+
}
|
|
10
|
+
get description() {
|
|
11
|
+
return 'Lists conversations for the specified Microsoft 365 group';
|
|
12
|
+
}
|
|
13
|
+
defaultProperties() {
|
|
14
|
+
return ['topic', 'lastDeliveredDateTime', 'id'];
|
|
15
|
+
}
|
|
16
|
+
commandAction(logger, args, cb) {
|
|
17
|
+
this
|
|
18
|
+
.getAllItems(`${this.resource}/v1.0/groups/${args.options.groupId}/conversations`, logger, true)
|
|
19
|
+
.then(() => {
|
|
20
|
+
logger.log(this.items);
|
|
21
|
+
cb();
|
|
22
|
+
}, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
|
|
23
|
+
}
|
|
24
|
+
options() {
|
|
25
|
+
const options = [
|
|
26
|
+
{
|
|
27
|
+
option: '-i, --groupId <groupId>'
|
|
28
|
+
}
|
|
29
|
+
];
|
|
30
|
+
const parentOptions = super.options();
|
|
31
|
+
return options.concat(parentOptions);
|
|
32
|
+
}
|
|
33
|
+
validate(args) {
|
|
34
|
+
if (!Utils_1.default.isValidGuid(args.options.groupId)) {
|
|
35
|
+
return `${args.options.groupId} is not a valid GUID`;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
module.exports = new AadO365GroupConversationListCommand();
|
|
41
|
+
//# sourceMappingURL=o365group-conversation-list.js.map
|
|
@@ -23,6 +23,7 @@ exports.default = {
|
|
|
23
23
|
O365GROUP_ADD: `${prefix} o365group add`,
|
|
24
24
|
O365GROUP_GET: `${prefix} o365group get`,
|
|
25
25
|
O365GROUP_LIST: `${prefix} o365group list`,
|
|
26
|
+
O365GROUP_CONVERSATION_LIST: `${prefix} o365group conversation list`,
|
|
26
27
|
O365GROUP_RECYCLEBINITEM_CLEAR: `${prefix} o365group recyclebinitem clear`,
|
|
27
28
|
O365GROUP_RECYCLEBINITEM_LIST: `${prefix} o365group recyclebinitem list`,
|
|
28
29
|
O365GROUP_RECYCLEBINITEM_RESTORE: `${prefix} o365group recyclebinitem restore`,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const GraphItemsListCommand_1 = require("../../../base/GraphItemsListCommand");
|
|
4
|
+
const commands_1 = require("../../commands");
|
|
5
|
+
class OutlookRoomListCommand extends GraphItemsListCommand_1.GraphItemsListCommand {
|
|
6
|
+
get name() {
|
|
7
|
+
return commands_1.default.ROOM_LIST;
|
|
8
|
+
}
|
|
9
|
+
get description() {
|
|
10
|
+
return 'Get a collection of all available rooms';
|
|
11
|
+
}
|
|
12
|
+
getTelemetryProperties(args) {
|
|
13
|
+
const telemetryProps = super.getTelemetryProperties(args);
|
|
14
|
+
telemetryProps.roomlistEmail = typeof args.options.roomlistEmail !== 'undefined';
|
|
15
|
+
return telemetryProps;
|
|
16
|
+
}
|
|
17
|
+
defaultProperties() {
|
|
18
|
+
return ['id', 'displayName', 'phone', 'emailAddress'];
|
|
19
|
+
}
|
|
20
|
+
commandAction(logger, args, cb) {
|
|
21
|
+
let endpoint = `${this.resource}/v1.0/places/microsoft.graph.room`;
|
|
22
|
+
if (args.options.roomlistEmail) {
|
|
23
|
+
endpoint = `${this.resource}/v1.0/places/${args.options.roomlistEmail}/microsoft.graph.roomlist/rooms`;
|
|
24
|
+
}
|
|
25
|
+
this
|
|
26
|
+
.getAllItems(endpoint, logger, true)
|
|
27
|
+
.then(() => {
|
|
28
|
+
logger.log(this.items);
|
|
29
|
+
cb();
|
|
30
|
+
}, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
|
|
31
|
+
}
|
|
32
|
+
options() {
|
|
33
|
+
const options = [
|
|
34
|
+
{
|
|
35
|
+
option: '--roomlistEmail [roomlistEmail]'
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
const parentOptions = super.options();
|
|
39
|
+
return options.concat(parentOptions);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
module.exports = new OutlookRoomListCommand();
|
|
43
|
+
//# sourceMappingURL=room-list.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const GraphItemsListCommand_1 = require("../../../base/GraphItemsListCommand");
|
|
4
|
+
const commands_1 = require("../../commands");
|
|
5
|
+
class OutlookRoomListListCommand extends GraphItemsListCommand_1.GraphItemsListCommand {
|
|
6
|
+
get name() {
|
|
7
|
+
return commands_1.default.ROOMLIST_LIST;
|
|
8
|
+
}
|
|
9
|
+
get description() {
|
|
10
|
+
return 'Get a collection of available roomlists';
|
|
11
|
+
}
|
|
12
|
+
defaultProperties() {
|
|
13
|
+
return ['id', 'displayName', 'phone', 'emailAddress'];
|
|
14
|
+
}
|
|
15
|
+
commandAction(logger, args, cb) {
|
|
16
|
+
this
|
|
17
|
+
.getAllItems(`${this.resource}/v1.0/places/microsoft.graph.roomlist`, logger, true)
|
|
18
|
+
.then(() => {
|
|
19
|
+
logger.log(this.items);
|
|
20
|
+
cb();
|
|
21
|
+
}, (err) => this.handleRejectedODataJsonPromise(err, logger, cb));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
module.exports = new OutlookRoomListListCommand();
|
|
25
|
+
//# sourceMappingURL=roomlist-list.js.map
|
|
@@ -16,6 +16,8 @@ exports.default = {
|
|
|
16
16
|
REPORT_MAILBOXUSAGEMAILBOXCOUNT: `${prefix} report mailboxusagemailboxcount`,
|
|
17
17
|
REPORT_MAILBOXUSAGEQUOTASTATUSMAILBOXCOUNTS: `${prefix} report mailboxusagequotastatusmailboxcounts`,
|
|
18
18
|
REPORT_MAILBOXUSAGESTORAGE: `${prefix} report mailboxusagestorage`,
|
|
19
|
+
ROOM_LIST: `${prefix} room list`,
|
|
20
|
+
ROOMLIST_LIST: `${prefix} roomlist list`,
|
|
19
21
|
SENDMAIL: `${prefix} sendmail`
|
|
20
22
|
};
|
|
21
23
|
//# sourceMappingURL=commands.js.map
|
|
@@ -22,7 +22,7 @@ class SpoGroupUserAddCommand extends SpoCommand_1.default {
|
|
|
22
22
|
.getGroupId(args)
|
|
23
23
|
.then((_groupId) => {
|
|
24
24
|
groupId = _groupId;
|
|
25
|
-
return this.
|
|
25
|
+
return this.getValidUsers(args, logger);
|
|
26
26
|
})
|
|
27
27
|
.then((resolvedUsernameList) => {
|
|
28
28
|
if (this.verbose) {
|
|
@@ -73,13 +73,15 @@ class SpoGroupUserAddCommand extends SpoCommand_1.default {
|
|
|
73
73
|
return groupId;
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
getValidUsers(args, logger) {
|
|
77
77
|
if (this.verbose) {
|
|
78
|
-
logger.logToStderr(`
|
|
78
|
+
logger.logToStderr(`Checking if the specified users exist`);
|
|
79
79
|
}
|
|
80
|
-
const
|
|
80
|
+
const validUserNames = [];
|
|
81
|
+
const invalidUserNames = [];
|
|
81
82
|
const userInfo = args.options.userName ? args.options.userName : args.options.email;
|
|
82
|
-
return Promise
|
|
83
|
+
return Promise
|
|
84
|
+
.all(userInfo.split(',').map(singleUserName => {
|
|
83
85
|
const options = {
|
|
84
86
|
output: 'json',
|
|
85
87
|
debug: args.options.debug,
|
|
@@ -91,20 +93,25 @@ class SpoGroupUserAddCommand extends SpoCommand_1.default {
|
|
|
91
93
|
else {
|
|
92
94
|
options.email = singleUserName.trim();
|
|
93
95
|
}
|
|
94
|
-
return cli_1.Cli
|
|
96
|
+
return cli_1.Cli
|
|
97
|
+
.executeCommandWithOutput(AadUserGetCommand, { options: Object.assign(Object.assign({}, options), { _: [] }) })
|
|
95
98
|
.then((getUserGetOutput) => {
|
|
96
99
|
if (this.debug) {
|
|
97
100
|
logger.logToStderr(getUserGetOutput.stderr);
|
|
98
101
|
}
|
|
99
|
-
|
|
102
|
+
validUserNames.push(JSON.parse(getUserGetOutput.stdout).userPrincipalName);
|
|
100
103
|
}, (err) => {
|
|
101
104
|
if (this.debug) {
|
|
102
105
|
logger.logToStderr(err.stderr);
|
|
103
106
|
}
|
|
107
|
+
invalidUserNames.push(singleUserName);
|
|
104
108
|
});
|
|
105
109
|
}))
|
|
106
110
|
.then(() => {
|
|
107
|
-
|
|
111
|
+
if (invalidUserNames.length > 0) {
|
|
112
|
+
return Promise.reject(`Users not added to the group because the following users don't exist: ${invalidUserNames.join(', ')}`);
|
|
113
|
+
}
|
|
114
|
+
return Promise.resolve(validUserNames);
|
|
108
115
|
});
|
|
109
116
|
}
|
|
110
117
|
getFormattedUserList(activeUserList) {
|
|
@@ -21,6 +21,7 @@ class TeamsChannelGetCommand extends GraphCommand_1.default {
|
|
|
21
21
|
telemetryProps.teamName = typeof args.options.teamName !== 'undefined';
|
|
22
22
|
telemetryProps.channelId = typeof args.options.channelId !== 'undefined';
|
|
23
23
|
telemetryProps.channelName = typeof args.options.channelName !== 'undefined';
|
|
24
|
+
telemetryProps.primary = (!(!args.options.primary)).toString();
|
|
24
25
|
return telemetryProps;
|
|
25
26
|
}
|
|
26
27
|
getTeamId(args) {
|
|
@@ -54,6 +55,9 @@ class TeamsChannelGetCommand extends GraphCommand_1.default {
|
|
|
54
55
|
if (args.options.channelId) {
|
|
55
56
|
return Promise.resolve(args.options.channelId);
|
|
56
57
|
}
|
|
58
|
+
if (args.options.primary) {
|
|
59
|
+
return Promise.resolve('');
|
|
60
|
+
}
|
|
57
61
|
const channelRequestOptions = {
|
|
58
62
|
url: `${this.resource}/v1.0/teams/${encodeURIComponent(this.teamId)}/channels?$filter=displayName eq '${encodeURIComponent(args.options.channelName)}'`,
|
|
59
63
|
headers: {
|
|
@@ -79,15 +83,21 @@ class TeamsChannelGetCommand extends GraphCommand_1.default {
|
|
|
79
83
|
return this.getChannelId(args);
|
|
80
84
|
})
|
|
81
85
|
.then((channelId) => {
|
|
86
|
+
let url = '';
|
|
87
|
+
if (args.options.primary) {
|
|
88
|
+
url = `${this.resource}/v1.0/teams/${encodeURIComponent(this.teamId)}/primaryChannel`;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
url = `${this.resource}/v1.0/teams/${encodeURIComponent(this.teamId)}/channels/${encodeURIComponent(channelId)}`;
|
|
92
|
+
}
|
|
82
93
|
const requestOptions = {
|
|
83
|
-
url:
|
|
94
|
+
url: url,
|
|
84
95
|
headers: {
|
|
85
96
|
accept: 'application/json;odata.metadata=none'
|
|
86
97
|
},
|
|
87
98
|
responseType: 'json'
|
|
88
99
|
};
|
|
89
|
-
return request_1.default
|
|
90
|
-
.get(requestOptions);
|
|
100
|
+
return request_1.default.get(requestOptions);
|
|
91
101
|
})
|
|
92
102
|
.then((res) => {
|
|
93
103
|
logger.log(res);
|
|
@@ -107,6 +117,9 @@ class TeamsChannelGetCommand extends GraphCommand_1.default {
|
|
|
107
117
|
},
|
|
108
118
|
{
|
|
109
119
|
option: '--channelName [channelName]'
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
option: '--primary'
|
|
110
123
|
}
|
|
111
124
|
];
|
|
112
125
|
const parentOptions = super.options();
|
|
@@ -122,11 +135,20 @@ class TeamsChannelGetCommand extends GraphCommand_1.default {
|
|
|
122
135
|
if (args.options.teamId && !Utils_1.default.isValidGuid(args.options.teamId)) {
|
|
123
136
|
return `${args.options.teamId} is not a valid GUID`;
|
|
124
137
|
}
|
|
125
|
-
if (args.options.channelId && args.options.channelName) {
|
|
126
|
-
return 'Specify
|
|
138
|
+
if (args.options.channelId && args.options.channelName && args.options.primary) {
|
|
139
|
+
return 'Specify channelId, channelName or primary';
|
|
140
|
+
}
|
|
141
|
+
if (!args.options.channelId && args.options.channelName && args.options.primary) {
|
|
142
|
+
return 'Specify channelId, channelName or primary.';
|
|
143
|
+
}
|
|
144
|
+
if (args.options.channelId && !args.options.channelName && args.options.primary) {
|
|
145
|
+
return 'Specify channelId, channelName or primary.';
|
|
146
|
+
}
|
|
147
|
+
if (args.options.channelId && args.options.channelName && !args.options.primary) {
|
|
148
|
+
return 'Specify channelId, channelName or primary.';
|
|
127
149
|
}
|
|
128
|
-
if (!args.options.channelId && !args.options.channelName) {
|
|
129
|
-
return 'Specify channelId or
|
|
150
|
+
if (!args.options.channelId && !args.options.channelName && !args.options.primary) {
|
|
151
|
+
return 'Specify channelId, channelName or primary, one is required';
|
|
130
152
|
}
|
|
131
153
|
if (args.options.channelId && !Utils_1.default.isValidTeamsChannelId(args.options.channelId)) {
|
|
132
154
|
return `${args.options.channelId} is not a valid Teams ChannelId`;
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const os = require("os");
|
|
13
|
+
const Auth_1 = require("../../../../Auth");
|
|
14
|
+
const request_1 = require("../../../../request");
|
|
15
|
+
const Utils_1 = require("../../../../Utils");
|
|
16
|
+
const GraphCommand_1 = require("../../../base/GraphCommand");
|
|
17
|
+
const commands_1 = require("../../commands");
|
|
18
|
+
class TeamsChatMessageSendCommand extends GraphCommand_1.default {
|
|
19
|
+
get name() {
|
|
20
|
+
return commands_1.default.CHAT_MESSAGE_SEND;
|
|
21
|
+
}
|
|
22
|
+
get description() {
|
|
23
|
+
return 'Send a message to an existing or new chat conversation.';
|
|
24
|
+
}
|
|
25
|
+
commandAction(logger, args, cb) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
try {
|
|
28
|
+
const chatId = args.options.chatId
|
|
29
|
+
|| args.options.userEmails && (yield this.ensureChatIdByUserEmails(args.options.userEmails))
|
|
30
|
+
|| args.options.chatName && (yield this.getChatIdByName(args.options.chatName));
|
|
31
|
+
yield this.sendChatMessage(chatId, args.options);
|
|
32
|
+
cb();
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
this.handleRejectedODataJsonPromise(error, logger, cb);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
options() {
|
|
40
|
+
const options = [
|
|
41
|
+
{
|
|
42
|
+
option: '--chatId [chatId]'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
option: '-e, --userEmails [userEmails]'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
option: '--chatName [chatName]'
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
option: '-m, --message <message>'
|
|
52
|
+
}
|
|
53
|
+
];
|
|
54
|
+
const parentOptions = super.options();
|
|
55
|
+
return options.concat(parentOptions);
|
|
56
|
+
}
|
|
57
|
+
validate(args) {
|
|
58
|
+
if (!args.options.chatId && !args.options.userEmails && !args.options.chatName) {
|
|
59
|
+
return 'Specify chatId or userEmails or chatName, one is required.';
|
|
60
|
+
}
|
|
61
|
+
let nrOfMutuallyExclusiveOptionsInUse = 0;
|
|
62
|
+
if (args.options.chatId) {
|
|
63
|
+
nrOfMutuallyExclusiveOptionsInUse++;
|
|
64
|
+
}
|
|
65
|
+
if (args.options.userEmails) {
|
|
66
|
+
nrOfMutuallyExclusiveOptionsInUse++;
|
|
67
|
+
}
|
|
68
|
+
if (args.options.chatName) {
|
|
69
|
+
nrOfMutuallyExclusiveOptionsInUse++;
|
|
70
|
+
}
|
|
71
|
+
if (nrOfMutuallyExclusiveOptionsInUse > 1) {
|
|
72
|
+
return 'Specify either chatId or userEmails or chatName, but not multiple.';
|
|
73
|
+
}
|
|
74
|
+
if (!args.options.message) {
|
|
75
|
+
return 'Specify a message to send.';
|
|
76
|
+
}
|
|
77
|
+
if (args.options.chatId && !Utils_1.default.isValidTeamsChatId(args.options.chatId)) {
|
|
78
|
+
return `${args.options.chatId} is not a valid Teams ChatId.`;
|
|
79
|
+
}
|
|
80
|
+
if (args.options.userEmails) {
|
|
81
|
+
const userEmails = args.options.userEmails.toLowerCase().replace(/\s/g, '').split(',').filter(e => e && e !== '');
|
|
82
|
+
if (!userEmails || userEmails.length === 0 || userEmails.some(e => !Utils_1.default.isValidUserPrincipalName(e))) {
|
|
83
|
+
return `${args.options.userEmails} contains one or more invalid email addresses.`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
ensureChatIdByUserEmails(userEmailsOption) {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const userEmails = userEmailsOption.toLowerCase().replace(/\s/g, '').split(',').filter(e => e && e !== '');
|
|
91
|
+
const currentUserEmail = Utils_1.default.getUserNameFromAccessToken(Auth_1.default.service.accessTokens[this.resource].accessToken).toLowerCase();
|
|
92
|
+
const existingChats = yield this.findExistingGroupChatsByMembers([currentUserEmail, ...userEmails]);
|
|
93
|
+
if (existingChats && existingChats.length > 0) {
|
|
94
|
+
if (existingChats.length > 1) {
|
|
95
|
+
const disambiguationText = existingChats.map(c => {
|
|
96
|
+
return `- ${c.id}${c.topic && ' - '}${c.topic} - ${c.createdDateTime && new Date(c.createdDateTime).toLocaleString()}`;
|
|
97
|
+
}).join(os.EOL);
|
|
98
|
+
throw new Error(`Multiple chat conversations with this topic found. Please disambiguate:${os.EOL}${disambiguationText}`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return existingChats[0].id;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const chat = yield this.createConversation([currentUserEmail, ...userEmails]);
|
|
105
|
+
return chat.id;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
getChatIdByName(chatName) {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
const existingChats = yield this.findExistingGroupChatsByTopic(chatName);
|
|
111
|
+
if (!existingChats || existingChats.length === 0) {
|
|
112
|
+
throw new Error('No chat conversation was found with this name.');
|
|
113
|
+
}
|
|
114
|
+
if (existingChats.length === 1) {
|
|
115
|
+
return existingChats[0].id;
|
|
116
|
+
}
|
|
117
|
+
const disambiguationText = existingChats.map(c => {
|
|
118
|
+
const memberstring = c.members.map(m => m.email).join(', ');
|
|
119
|
+
return `- ${c.id} - ${c.createdDateTime && new Date(c.createdDateTime).toLocaleString()} - ${memberstring}`;
|
|
120
|
+
}).join(os.EOL);
|
|
121
|
+
throw new Error(`Multiple chat conversations with this topic found. Please disambiguate:${os.EOL}${disambiguationText}`);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
// This Microsoft Graph API request throws an intermittent 404 exception, saying that it cannot find the principal.
|
|
125
|
+
// The same behavior occurs when creating the conversation through the Graph Explorer.
|
|
126
|
+
// It seems to happen when the userEmail casing does not match the casing of the actual UPN.
|
|
127
|
+
// When the first request throws an error, the second request does succeed.
|
|
128
|
+
// Therefore a retry-mechanism is implemented here.
|
|
129
|
+
createConversation(memberEmails, retried = 0) {
|
|
130
|
+
var _a;
|
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
+
try {
|
|
133
|
+
const jsonBody = {
|
|
134
|
+
chatType: memberEmails.length > 2 ? 'group' : 'oneOnOne',
|
|
135
|
+
members: memberEmails.map(email => {
|
|
136
|
+
return {
|
|
137
|
+
'@odata.type': '#microsoft.graph.aadUserConversationMember',
|
|
138
|
+
roles: ['owner'],
|
|
139
|
+
'user@odata.bind': `https://graph.microsoft.com/v1.0/users/${email}`
|
|
140
|
+
};
|
|
141
|
+
})
|
|
142
|
+
};
|
|
143
|
+
const requestOptions = {
|
|
144
|
+
url: `${this.resource}/v1.0/chats`,
|
|
145
|
+
headers: {
|
|
146
|
+
accept: 'application/json;odata.metadata=none',
|
|
147
|
+
'content-type': 'application/json;odata=nometadata'
|
|
148
|
+
},
|
|
149
|
+
responseType: 'json',
|
|
150
|
+
data: jsonBody
|
|
151
|
+
};
|
|
152
|
+
return yield request_1.default.post(requestOptions);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
if (((_a = err.message) === null || _a === void 0 ? void 0 : _a.indexOf('404')) > -1 && retried < 4) {
|
|
156
|
+
return yield this.createConversation(memberEmails, retried + 1);
|
|
157
|
+
}
|
|
158
|
+
throw err;
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
sendChatMessage(chatId, options) {
|
|
163
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
const requestOptions = {
|
|
165
|
+
url: `${this.resource}/v1.0/chats/${chatId}/messages`,
|
|
166
|
+
headers: {
|
|
167
|
+
accept: 'application/json;odata.metadata=none',
|
|
168
|
+
'content-type': 'application/json;odata=nometadata'
|
|
169
|
+
},
|
|
170
|
+
responseType: 'json',
|
|
171
|
+
data: {
|
|
172
|
+
body: {
|
|
173
|
+
content: options.message
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
yield request_1.default.post(requestOptions);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
findExistingGroupChatsByMembers(expectedMemberEmails) {
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
const endpoint = `${this.resource}/v1.0/chats?$filter=chatType eq 'group'&$expand=members&$select=id,topic,createdDateTime,members`;
|
|
183
|
+
const foundChats = [];
|
|
184
|
+
const chats = yield this.getAllChats(endpoint, []);
|
|
185
|
+
for (const chat of chats) {
|
|
186
|
+
const chatMembers = chat.members;
|
|
187
|
+
if (chatMembers.length === expectedMemberEmails.length) {
|
|
188
|
+
const chatMemberEmails = chatMembers.map(member => { var _a; return (_a = member.email) === null || _a === void 0 ? void 0 : _a.toLowerCase(); });
|
|
189
|
+
if (expectedMemberEmails.every(email => chatMemberEmails.some(memberEmail => memberEmail === email))) {
|
|
190
|
+
foundChats.push(chat);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return foundChats;
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
findExistingGroupChatsByTopic(topic) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
const endpoint = `${this.resource}/v1.0/chats?$filter=topic eq '${encodeURIComponent(topic)}'&$expand=members&$select=id,topic,createdDateTime,chatType`;
|
|
200
|
+
const chats = yield this.getAllChats(endpoint, []);
|
|
201
|
+
return chats;
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
getAllChats(url, items) {
|
|
205
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
206
|
+
const requestOptions = {
|
|
207
|
+
url: url,
|
|
208
|
+
headers: {
|
|
209
|
+
accept: 'application/json;odata.metadata=none'
|
|
210
|
+
},
|
|
211
|
+
responseType: 'json'
|
|
212
|
+
};
|
|
213
|
+
const res = yield request_1.default.get(requestOptions);
|
|
214
|
+
items = items.concat(res.value);
|
|
215
|
+
if (res['@odata.nextLink']) {
|
|
216
|
+
return yield this.getAllChats(res['@odata.nextLink'], items);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
return items;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
module.exports = new TeamsChatMessageSendCommand();
|
|
225
|
+
//# sourceMappingURL=chat-message-send.js.map
|
|
@@ -16,6 +16,7 @@ exports.default = {
|
|
|
16
16
|
CHAT_LIST: `${prefix} chat list`,
|
|
17
17
|
CHAT_MEMBER_LIST: `${prefix} chat member list`,
|
|
18
18
|
CHAT_MESSAGE_LIST: `${prefix} chat message list`,
|
|
19
|
+
CHAT_MESSAGE_SEND: `${prefix} chat message send`,
|
|
19
20
|
CONVERSATIONMEMBER_ADD: `${prefix} conversationmember add`,
|
|
20
21
|
CONVERSATIONMEMBER_LIST: `${prefix} conversationmember list`,
|
|
21
22
|
FUNSETTINGS_LIST: `${prefix} funsettings list`,
|
|
@@ -22,6 +22,15 @@ m365 aad app set [options]
|
|
|
22
22
|
`-u, --uri [uri]`
|
|
23
23
|
: Application ID URI to update
|
|
24
24
|
|
|
25
|
+
`-r, --redirectUris [redirectUris]`
|
|
26
|
+
: Comma-separated list of redirect URIs to add to the app registration. Requires `platform` to be specified
|
|
27
|
+
|
|
28
|
+
`-p, --platform [platform]`
|
|
29
|
+
: Platform for which the `redirectUri` should be configured. Allowed values `spa,web,publicClient`
|
|
30
|
+
|
|
31
|
+
`--redirectUrisToRemove [redirectUrisToRemove]`
|
|
32
|
+
: Comma-separated list of existing redirect URIs to remove. Specify, when you want to replace existing redirect URIs with another
|
|
33
|
+
|
|
25
34
|
--8<-- "docs/cmd/_global.md"
|
|
26
35
|
|
|
27
36
|
## Remarks
|
|
@@ -49,3 +58,15 @@ Update the app URI of the Azure AD application registration specified by its nam
|
|
|
49
58
|
```sh
|
|
50
59
|
m365 aad app set --name "My app" --uri https://contoso.com/e75be2e1-0204-4f95-857d-51a37cf40be8
|
|
51
60
|
```
|
|
61
|
+
|
|
62
|
+
Add a new redirect URI for SPA authentication
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
m365 aad app set --objectId 95cfe30d-ed44-4f9d-b73d-c66560f72e83 --redirectUris https://contoso.com/auth --platform spa
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Replace one redirect URI with another for SPA authentication
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
m365 aad app set --objectId 95cfe30d-ed44-4f9d-b73d-c66560f72e83 --redirectUris https://contoso.com/auth --platform spa --redirectUrisToRemove https://contoso.com/old-auth
|
|
72
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# aad o365group conversation list
|
|
2
|
+
|
|
3
|
+
Lists conversations for the specified Microsoft 365 group
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
m365 aad o365group conversation list [options]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Options
|
|
12
|
+
|
|
13
|
+
`-i, --groupId <groupId>`
|
|
14
|
+
: The ID of the Microsoft 365 group
|
|
15
|
+
|
|
16
|
+
--8<-- "docs/cmd/_global.md"
|
|
17
|
+
|
|
18
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
Lists conversations for the specified Microsoft 365 group
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
m365 aad o365group conversation list --groupId '00000000-0000-0000-0000-000000000000'
|
|
24
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# outlook room list
|
|
2
|
+
|
|
3
|
+
Get a collection of all available rooms
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
m365 outlook room list [options]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Options
|
|
12
|
+
|
|
13
|
+
`--roomlistEmail [roomlistEmail]`
|
|
14
|
+
: Use to filter returned rooms by their roomlist email (eg. bldg2@contoso.com)
|
|
15
|
+
|
|
16
|
+
--8<-- "docs/cmd/_global.md"
|
|
17
|
+
|
|
18
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
Get all the rooms
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
m365 outlook room list
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Get all the rooms of specified roomlist e-mail address
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
m365 outlook room list --roomlistEmail "bldg2@contoso.com"
|
|
30
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# outlook roomlist list
|
|
2
|
+
|
|
3
|
+
Get a collection of available roomlists
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
m365 outlook roomlist list [options]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Options
|
|
12
|
+
|
|
13
|
+
--8<-- "docs/cmd/_global.md"
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
Get all roomlists in your tenant
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
m365 outlook roomlist list
|
|
21
|
+
```
|
|
@@ -27,6 +27,10 @@ m365 spo group user add [options]
|
|
|
27
27
|
|
|
28
28
|
--8<-- "docs/cmd/_global.md"
|
|
29
29
|
|
|
30
|
+
## Remarks
|
|
31
|
+
|
|
32
|
+
For the `--userName` or `--email` options you can specify multiple values by separating them with a comma. If one of the specified entries is not valid, the command will fail with an error message showing the list invalid values.
|
|
33
|
+
|
|
30
34
|
## Examples
|
|
31
35
|
|
|
32
36
|
Add a user with name _Alex.Wilber@contoso.com_ to the SharePoint group with id _5_ available on the web _https://contoso.sharepoint.com/sites/SiteA_
|
|
@@ -22,6 +22,9 @@ m365 teams channel get [options]
|
|
|
22
22
|
`--channelName [channelName]`
|
|
23
23
|
: The display name of the channel for which to retrieve more information. Specify either channelId or channelName but not both
|
|
24
24
|
|
|
25
|
+
`--primary`
|
|
26
|
+
: Gets the default channel, General, of a team. If specified, channelId or channelName are not needed
|
|
27
|
+
|
|
25
28
|
--8<-- "docs/cmd/_global.md"
|
|
26
29
|
|
|
27
30
|
## Examples
|
|
@@ -36,4 +39,10 @@ Get information about Microsoft Teams team channel with name _Channel Name_
|
|
|
36
39
|
|
|
37
40
|
```sh
|
|
38
41
|
m365 teams channel get --teamName "Team Name" --channelName "Channel Name"
|
|
39
|
-
```
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Get information about Microsoft Teams team primary channel , i.e. General
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
m365 teams channel get --teamName "Team Name" --primary
|
|
48
|
+
```
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# teams chat message send
|
|
2
|
+
|
|
3
|
+
Sends a chat message to a Microsoft Teams chat conversation.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
m365 teams chat message send [options]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Options
|
|
12
|
+
|
|
13
|
+
`--chatId [chatId]`
|
|
14
|
+
: The ID of the chat conversation. Specify either `chatId`, `chatName` or `userEmails`, but not multiple.
|
|
15
|
+
|
|
16
|
+
`--chatName [chatName]`
|
|
17
|
+
: The display name of the chat conversation. Specify either `chatId`, `chatName` or `userEmails`, but not multiple.
|
|
18
|
+
|
|
19
|
+
`-e, --userEmails [userEmails]`
|
|
20
|
+
: A comma-separated list of one or more e-mail addresses. Specify either `chatId`, `chatName` or `userEmails`, but not multiple.
|
|
21
|
+
|
|
22
|
+
`-m, --message <message>`
|
|
23
|
+
: The message to send
|
|
24
|
+
|
|
25
|
+
--8<-- "docs/cmd/_global.md"
|
|
26
|
+
|
|
27
|
+
## Remarks
|
|
28
|
+
|
|
29
|
+
A new chat conversation will be created if no existing conversation with the participants specified with emails is found.
|
|
30
|
+
|
|
31
|
+
## Examples
|
|
32
|
+
|
|
33
|
+
Send a message to a Microsoft Teams chat conversation by id
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
m365 teams chat message send --chatId 19:2da4c29f6d7041eca70b638b43d45437@thread.v2
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Send a message to a single person
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
m365 teams chat message send --userEmails alexw@contoso.com
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Send a message to a group of people
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
m365 teams chat message send --userEmails alexw@contoso.com,meganb@contoso.com
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Send a message to a chat conversation finding it by display name
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
m365 teams chat message send --chatName "Just a conversation"
|
|
55
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnp/cli-microsoft365",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.21e7f85",
|
|
4
4
|
"description": "Manage Microsoft 365 and SharePoint Framework projects on any platform",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/api.js",
|
|
@@ -85,7 +85,9 @@
|
|
|
85
85
|
],
|
|
86
86
|
"contributors": [
|
|
87
87
|
"Ågren, Simon <simon.agren@sogeti.com>",
|
|
88
|
+
"Akash Karda <akashkarda@gmail.com>",
|
|
88
89
|
"Albany, Bruce <bruce.albany@gmail.com>",
|
|
90
|
+
"Auckloo, Reshmee <reshmee011@gmail.com>",
|
|
89
91
|
"Balasubramaniam, Jayakumar <jayakumar@live.in>",
|
|
90
92
|
"Bauer, Stefan <stefan.bauer@n8d.at>",
|
|
91
93
|
"Bernier, Hugo <hugoabernier@live.ca>",
|