@mcp-consultant-tools/teams 1.0.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/README.md +134 -0
- package/build/TeamsService.d.ts +110 -0
- package/build/TeamsService.d.ts.map +1 -0
- package/build/TeamsService.js +598 -0
- package/build/TeamsService.js.map +1 -0
- package/build/cards/templates.d.ts +13 -0
- package/build/cards/templates.d.ts.map +1 -0
- package/build/cards/templates.js +247 -0
- package/build/cards/templates.js.map +1 -0
- package/build/index.d.ts +30 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +124 -0
- package/build/index.js.map +1 -0
- package/build/tools/authenticate.d.ts +22 -0
- package/build/tools/authenticate.d.ts.map +1 -0
- package/build/tools/authenticate.js +148 -0
- package/build/tools/authenticate.js.map +1 -0
- package/build/tools/list-channels.d.ts +20 -0
- package/build/tools/list-channels.d.ts.map +1 -0
- package/build/tools/list-channels.js +113 -0
- package/build/tools/list-channels.js.map +1 -0
- package/build/tools/send-card.d.ts +48 -0
- package/build/tools/send-card.d.ts.map +1 -0
- package/build/tools/send-card.js +102 -0
- package/build/tools/send-card.js.map +1 -0
- package/build/tools/send-message.d.ts +19 -0
- package/build/tools/send-message.d.ts.map +1 -0
- package/build/tools/send-message.js +123 -0
- package/build/tools/send-message.js.map +1 -0
- package/build/types.d.ts +170 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +5 -0
- package/build/types.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teams Service - Microsoft Graph API client for Teams operations
|
|
3
|
+
*
|
|
4
|
+
* Supports two authentication modes:
|
|
5
|
+
* - Client Credentials (app-only) - for automation, requires client secret
|
|
6
|
+
* - Device Code (user auth) - for interactive use, authenticates via browser
|
|
7
|
+
*
|
|
8
|
+
* For device-code mode, use the authenticate() method first, which returns
|
|
9
|
+
* the URL and code for the user to complete authentication.
|
|
10
|
+
*/
|
|
11
|
+
import { ConfidentialClientApplication, PublicClientApplication } from "@azure/msal-node";
|
|
12
|
+
import { Client } from "@microsoft/microsoft-graph-client";
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import * as os from "node:os";
|
|
16
|
+
// Token storage path for device code flow
|
|
17
|
+
const TOKEN_DIR = path.join(os.homedir(), ".mcp-consultant-tools");
|
|
18
|
+
const TOKEN_FILE = path.join(TOKEN_DIR, "teams-auth.json");
|
|
19
|
+
export class TeamsService {
|
|
20
|
+
config;
|
|
21
|
+
msalConfidentialClient = null;
|
|
22
|
+
msalPublicClient = null;
|
|
23
|
+
graphClient = null;
|
|
24
|
+
accessToken = null;
|
|
25
|
+
tokenExpirationTime = 0;
|
|
26
|
+
pendingAuth = null;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
if (config.authMode === "client-credentials") {
|
|
30
|
+
if (!config.clientSecret) {
|
|
31
|
+
throw new Error("Client secret is required for client-credentials auth mode");
|
|
32
|
+
}
|
|
33
|
+
this.msalConfidentialClient = new ConfidentialClientApplication({
|
|
34
|
+
auth: {
|
|
35
|
+
clientId: config.clientId,
|
|
36
|
+
clientSecret: config.clientSecret,
|
|
37
|
+
authority: `https://login.microsoftonline.com/${config.tenantId}`,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
console.error("Teams service created (client-credentials mode)");
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// Device code flow uses PublicClientApplication
|
|
44
|
+
this.msalPublicClient = new PublicClientApplication({
|
|
45
|
+
auth: {
|
|
46
|
+
clientId: config.clientId,
|
|
47
|
+
authority: `https://login.microsoftonline.com/${config.tenantId}`,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
console.error("Teams service created (device-code mode)");
|
|
51
|
+
// Try to load existing token
|
|
52
|
+
this.loadStoredToken();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Load stored token from disk (device-code mode)
|
|
57
|
+
*/
|
|
58
|
+
loadStoredToken() {
|
|
59
|
+
try {
|
|
60
|
+
if (fs.existsSync(TOKEN_FILE)) {
|
|
61
|
+
const data = fs.readFileSync(TOKEN_FILE, "utf8");
|
|
62
|
+
const stored = JSON.parse(data);
|
|
63
|
+
// Check if token matches current client and hasn't expired
|
|
64
|
+
if (stored.clientId === this.config.clientId) {
|
|
65
|
+
const expiresAt = new Date(stored.expiresAt).getTime();
|
|
66
|
+
if (expiresAt > Date.now()) {
|
|
67
|
+
this.accessToken = stored.accessToken;
|
|
68
|
+
this.tokenExpirationTime = expiresAt - 5 * 60 * 1000; // 5 min buffer
|
|
69
|
+
console.error("Loaded existing Teams token (expires: " + stored.expiresAt + ")");
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.error("Stored Teams token has expired, will need to re-authenticate");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
console.error("Could not load stored token:", error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Save token to disk (device-code mode)
|
|
83
|
+
*/
|
|
84
|
+
saveToken(token, expiresAt) {
|
|
85
|
+
try {
|
|
86
|
+
if (!fs.existsSync(TOKEN_DIR)) {
|
|
87
|
+
fs.mkdirSync(TOKEN_DIR, { recursive: true, mode: 0o700 });
|
|
88
|
+
}
|
|
89
|
+
const stored = {
|
|
90
|
+
accessToken: token,
|
|
91
|
+
expiresAt: expiresAt.toISOString(),
|
|
92
|
+
clientId: this.config.clientId,
|
|
93
|
+
authenticatedAt: new Date().toISOString(),
|
|
94
|
+
};
|
|
95
|
+
fs.writeFileSync(TOKEN_FILE, JSON.stringify(stored, null, 2), { mode: 0o600 });
|
|
96
|
+
console.error("Teams token saved to " + TOKEN_FILE);
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error("Could not save token:", error);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Get access token - handles both auth modes
|
|
104
|
+
*/
|
|
105
|
+
async getAccessToken() {
|
|
106
|
+
const currentTime = Date.now();
|
|
107
|
+
// Return cached token if still valid (with 5 minute buffer)
|
|
108
|
+
if (this.accessToken && this.tokenExpirationTime > currentTime) {
|
|
109
|
+
return this.accessToken;
|
|
110
|
+
}
|
|
111
|
+
if (this.config.authMode === "client-credentials") {
|
|
112
|
+
return this.getTokenClientCredentials();
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return this.getTokenDeviceCode();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get token using client credentials flow
|
|
120
|
+
*/
|
|
121
|
+
async getTokenClientCredentials() {
|
|
122
|
+
if (!this.msalConfidentialClient) {
|
|
123
|
+
throw new Error("MSAL client not initialized for client-credentials mode");
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
const result = await this.msalConfidentialClient.acquireTokenByClientCredential({
|
|
127
|
+
scopes: ["https://graph.microsoft.com/.default"],
|
|
128
|
+
});
|
|
129
|
+
if (!result || !result.accessToken) {
|
|
130
|
+
throw new Error("Failed to acquire access token from Azure AD");
|
|
131
|
+
}
|
|
132
|
+
this.accessToken = result.accessToken;
|
|
133
|
+
this.tokenExpirationTime = result.expiresOn
|
|
134
|
+
? result.expiresOn.getTime() - 5 * 60 * 1000
|
|
135
|
+
: Date.now() + 55 * 60 * 1000;
|
|
136
|
+
console.error("Teams access token acquired (client-credentials)");
|
|
137
|
+
return this.accessToken;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
141
|
+
throw new Error(`Failed to get Teams access token: ${message}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get token using device code flow
|
|
146
|
+
* This method checks for existing/cached tokens or waits for pending auth.
|
|
147
|
+
* It does NOT start a new auth flow - use startAuthentication() for that.
|
|
148
|
+
*/
|
|
149
|
+
async getTokenDeviceCode() {
|
|
150
|
+
if (!this.msalPublicClient) {
|
|
151
|
+
throw new Error("MSAL client not initialized for device-code mode");
|
|
152
|
+
}
|
|
153
|
+
// Check if we have a valid token in memory
|
|
154
|
+
if (this.accessToken && this.tokenExpirationTime > Date.now()) {
|
|
155
|
+
return this.accessToken;
|
|
156
|
+
}
|
|
157
|
+
// Try to load stored token
|
|
158
|
+
this.loadStoredToken();
|
|
159
|
+
if (this.accessToken && this.tokenExpirationTime > Date.now()) {
|
|
160
|
+
return this.accessToken;
|
|
161
|
+
}
|
|
162
|
+
// Check if there's a pending authentication
|
|
163
|
+
if (this.pendingAuth && this.pendingAuth.expiresAt > Date.now()) {
|
|
164
|
+
// Wait briefly for the auth to complete (user might have just finished)
|
|
165
|
+
const result = await Promise.race([
|
|
166
|
+
this.pendingAuth.promise,
|
|
167
|
+
new Promise((resolve) => setTimeout(() => resolve({ status: "timeout", message: "Still waiting..." }), 2000)),
|
|
168
|
+
]);
|
|
169
|
+
if (result.status === "authenticated" && this.accessToken) {
|
|
170
|
+
return this.accessToken;
|
|
171
|
+
}
|
|
172
|
+
// Auth still pending - throw helpful error
|
|
173
|
+
throw new Error(`Authentication in progress.\n\n` +
|
|
174
|
+
`Please complete sign-in:\n` +
|
|
175
|
+
`1. Open: ${this.pendingAuth.verificationUri}\n` +
|
|
176
|
+
`2. Enter code: ${this.pendingAuth.userCode}\n` +
|
|
177
|
+
`3. Sign in with your Microsoft account\n\n` +
|
|
178
|
+
`Then try this operation again.`);
|
|
179
|
+
}
|
|
180
|
+
// No token and no pending auth - need to authenticate
|
|
181
|
+
throw new Error(`Not authenticated to Microsoft Teams.\n\n` +
|
|
182
|
+
`Please use the 'authenticate' tool first to sign in.\n\n` +
|
|
183
|
+
`This will provide you with a URL and code to complete authentication in your browser.`);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Check if authenticated (device-code mode)
|
|
187
|
+
*/
|
|
188
|
+
isAuthenticated() {
|
|
189
|
+
return this.accessToken !== null && this.tokenExpirationTime > Date.now();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Get current authentication status
|
|
193
|
+
*/
|
|
194
|
+
getAuthStatus() {
|
|
195
|
+
// Client credentials mode is always ready (auth happens on first call)
|
|
196
|
+
if (this.config.authMode === "client-credentials") {
|
|
197
|
+
return {
|
|
198
|
+
status: "authenticated",
|
|
199
|
+
authMode: "client-credentials",
|
|
200
|
+
message: "Client credentials mode - authentication happens automatically on first API call.",
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
// Device-code mode - check various states
|
|
204
|
+
if (this.accessToken && this.tokenExpirationTime > Date.now()) {
|
|
205
|
+
return {
|
|
206
|
+
status: "authenticated",
|
|
207
|
+
authMode: "device-code",
|
|
208
|
+
expiresAt: new Date(this.tokenExpirationTime).toISOString(),
|
|
209
|
+
message: "Authenticated. Token valid until " + new Date(this.tokenExpirationTime).toLocaleString(),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
if (this.pendingAuth && this.pendingAuth.expiresAt > Date.now()) {
|
|
213
|
+
return {
|
|
214
|
+
status: "pending",
|
|
215
|
+
authMode: "device-code",
|
|
216
|
+
message: `Authentication in progress. Go to ${this.pendingAuth.verificationUri} and enter code: ${this.pendingAuth.userCode}`,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// Check for stored token
|
|
220
|
+
if (fs.existsSync(TOKEN_FILE)) {
|
|
221
|
+
try {
|
|
222
|
+
const data = fs.readFileSync(TOKEN_FILE, "utf8");
|
|
223
|
+
const stored = JSON.parse(data);
|
|
224
|
+
if (stored.clientId === this.config.clientId) {
|
|
225
|
+
const expiresAt = new Date(stored.expiresAt).getTime();
|
|
226
|
+
if (expiresAt > Date.now()) {
|
|
227
|
+
// Load the token
|
|
228
|
+
this.accessToken = stored.accessToken;
|
|
229
|
+
this.tokenExpirationTime = expiresAt - 5 * 60 * 1000;
|
|
230
|
+
return {
|
|
231
|
+
status: "authenticated",
|
|
232
|
+
authMode: "device-code",
|
|
233
|
+
expiresAt: stored.expiresAt,
|
|
234
|
+
message: "Authenticated (from cached token). Valid until " + new Date(expiresAt).toLocaleString(),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
status: "expired",
|
|
239
|
+
authMode: "device-code",
|
|
240
|
+
message: "Token has expired. Please re-authenticate.",
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
// Ignore errors reading stored token
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
status: "not_authenticated",
|
|
250
|
+
authMode: "device-code",
|
|
251
|
+
message: "Not authenticated. Call the 'authenticate' tool to sign in.",
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Start device-code authentication flow
|
|
256
|
+
* Returns immediately with the URL and code for the user
|
|
257
|
+
* Polls in background and resolves when complete
|
|
258
|
+
*/
|
|
259
|
+
async startAuthentication() {
|
|
260
|
+
// Client credentials mode doesn't need explicit authentication
|
|
261
|
+
if (this.config.authMode === "client-credentials") {
|
|
262
|
+
// Try to get a token to verify credentials work
|
|
263
|
+
try {
|
|
264
|
+
await this.getTokenClientCredentials();
|
|
265
|
+
return {
|
|
266
|
+
status: "authenticated",
|
|
267
|
+
message: "Client credentials authentication successful.",
|
|
268
|
+
expiresAt: new Date(this.tokenExpirationTime).toISOString(),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
273
|
+
return {
|
|
274
|
+
status: "failed",
|
|
275
|
+
message: `Client credentials authentication failed: ${msg}`,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// Check if already authenticated
|
|
280
|
+
if (this.accessToken && this.tokenExpirationTime > Date.now()) {
|
|
281
|
+
return {
|
|
282
|
+
status: "authenticated",
|
|
283
|
+
message: "Already authenticated. Token valid until " + new Date(this.tokenExpirationTime).toLocaleString(),
|
|
284
|
+
expiresAt: new Date(this.tokenExpirationTime).toISOString(),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
// Check if auth is already pending
|
|
288
|
+
if (this.pendingAuth && this.pendingAuth.expiresAt > Date.now()) {
|
|
289
|
+
return {
|
|
290
|
+
status: "pending",
|
|
291
|
+
userCode: this.pendingAuth.userCode,
|
|
292
|
+
verificationUri: this.pendingAuth.verificationUri,
|
|
293
|
+
message: "Authentication already in progress. Please complete sign-in.",
|
|
294
|
+
expiresInSeconds: Math.floor((this.pendingAuth.expiresAt - Date.now()) / 1000),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
// Start new device code flow
|
|
298
|
+
if (!this.msalPublicClient) {
|
|
299
|
+
throw new Error("MSAL client not initialized for device-code mode");
|
|
300
|
+
}
|
|
301
|
+
const scopes = [
|
|
302
|
+
"User.Read",
|
|
303
|
+
"Team.ReadBasic.All",
|
|
304
|
+
"Channel.ReadBasic.All",
|
|
305
|
+
"ChannelMessage.Send",
|
|
306
|
+
"Group.Read.All",
|
|
307
|
+
];
|
|
308
|
+
return new Promise((resolve) => {
|
|
309
|
+
let deviceCodeInfo = null;
|
|
310
|
+
const authPromise = this.msalPublicClient.acquireTokenByDeviceCode({
|
|
311
|
+
scopes,
|
|
312
|
+
deviceCodeCallback: (response) => {
|
|
313
|
+
deviceCodeInfo = {
|
|
314
|
+
userCode: response.userCode,
|
|
315
|
+
verificationUri: response.verificationUri,
|
|
316
|
+
expiresIn: response.expiresIn || 900, // Default 15 minutes
|
|
317
|
+
};
|
|
318
|
+
// Store pending auth state
|
|
319
|
+
this.pendingAuth = {
|
|
320
|
+
userCode: response.userCode,
|
|
321
|
+
verificationUri: response.verificationUri,
|
|
322
|
+
expiresAt: Date.now() + (response.expiresIn || 900) * 1000,
|
|
323
|
+
promise: authPromise.then((result) => {
|
|
324
|
+
if (result && result.accessToken) {
|
|
325
|
+
this.accessToken = result.accessToken;
|
|
326
|
+
const expiresAt = result.expiresOn || new Date(Date.now() + 60 * 60 * 1000);
|
|
327
|
+
this.tokenExpirationTime = expiresAt.getTime() - 5 * 60 * 1000;
|
|
328
|
+
this.saveToken(result.accessToken, expiresAt);
|
|
329
|
+
this.pendingAuth = null;
|
|
330
|
+
return {
|
|
331
|
+
status: "authenticated",
|
|
332
|
+
message: "Authentication successful!",
|
|
333
|
+
expiresAt: expiresAt.toISOString(),
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
this.pendingAuth = null;
|
|
337
|
+
return { status: "failed", message: "No access token received" };
|
|
338
|
+
}, (error) => {
|
|
339
|
+
this.pendingAuth = null;
|
|
340
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
341
|
+
if (msg.includes("expired") || msg.includes("timeout")) {
|
|
342
|
+
return { status: "timeout", message: "Authentication timed out. Please try again." };
|
|
343
|
+
}
|
|
344
|
+
return { status: "failed", message: `Authentication failed: ${msg}` };
|
|
345
|
+
}),
|
|
346
|
+
};
|
|
347
|
+
// Return immediately with the device code info
|
|
348
|
+
console.error("\n" + "=".repeat(60));
|
|
349
|
+
console.error("🔐 TEAMS AUTHENTICATION REQUIRED");
|
|
350
|
+
console.error("=".repeat(60));
|
|
351
|
+
console.error(`\n1. Open: ${response.verificationUri}`);
|
|
352
|
+
console.error(`2. Enter code: ${response.userCode}`);
|
|
353
|
+
console.error("3. Sign in with your Microsoft account");
|
|
354
|
+
console.error("=".repeat(60) + "\n");
|
|
355
|
+
resolve({
|
|
356
|
+
status: "pending",
|
|
357
|
+
userCode: response.userCode,
|
|
358
|
+
verificationUri: response.verificationUri,
|
|
359
|
+
message: `Please authenticate:\n\n1. Open this URL: ${response.verificationUri}\n2. Enter this code: ${response.userCode}\n3. Sign in with your Microsoft account\n\nThe authentication will complete automatically once you sign in.`,
|
|
360
|
+
expiresInSeconds: response.expiresIn || 900,
|
|
361
|
+
});
|
|
362
|
+
},
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Wait for pending authentication to complete
|
|
368
|
+
* @param timeoutMs Maximum time to wait (default 5 minutes)
|
|
369
|
+
*/
|
|
370
|
+
async waitForAuthentication(timeoutMs = 300000) {
|
|
371
|
+
if (this.config.authMode === "client-credentials") {
|
|
372
|
+
try {
|
|
373
|
+
await this.getTokenClientCredentials();
|
|
374
|
+
return {
|
|
375
|
+
status: "authenticated",
|
|
376
|
+
message: "Client credentials authentication successful.",
|
|
377
|
+
expiresAt: new Date(this.tokenExpirationTime).toISOString(),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
382
|
+
return { status: "failed", message: `Authentication failed: ${msg}` };
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Already authenticated
|
|
386
|
+
if (this.accessToken && this.tokenExpirationTime > Date.now()) {
|
|
387
|
+
return {
|
|
388
|
+
status: "authenticated",
|
|
389
|
+
message: "Already authenticated.",
|
|
390
|
+
expiresAt: new Date(this.tokenExpirationTime).toISOString(),
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
// No pending auth
|
|
394
|
+
if (!this.pendingAuth) {
|
|
395
|
+
return {
|
|
396
|
+
status: "failed",
|
|
397
|
+
message: "No authentication in progress. Call startAuthentication() first.",
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
// Wait for pending auth with timeout
|
|
401
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
402
|
+
setTimeout(() => {
|
|
403
|
+
resolve({
|
|
404
|
+
status: "timeout",
|
|
405
|
+
message: "Timed out waiting for authentication. The authentication may still complete if you sign in.",
|
|
406
|
+
});
|
|
407
|
+
}, timeoutMs);
|
|
408
|
+
});
|
|
409
|
+
return Promise.race([this.pendingAuth.promise, timeoutPromise]);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Require authentication before proceeding
|
|
413
|
+
* Throws a helpful error if not authenticated
|
|
414
|
+
*/
|
|
415
|
+
requireAuth() {
|
|
416
|
+
const status = this.getAuthStatus();
|
|
417
|
+
if (status.status === "authenticated") {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
if (status.status === "pending") {
|
|
421
|
+
throw new Error(`Authentication in progress.\n\n` +
|
|
422
|
+
`Please complete sign-in:\n` +
|
|
423
|
+
`1. Open: ${this.pendingAuth?.verificationUri}\n` +
|
|
424
|
+
`2. Enter code: ${this.pendingAuth?.userCode}\n` +
|
|
425
|
+
`3. Sign in with your Microsoft account\n\n` +
|
|
426
|
+
`Then try this operation again.`);
|
|
427
|
+
}
|
|
428
|
+
throw new Error(`Not authenticated.\n\n` +
|
|
429
|
+
`Please use the 'authenticate' tool first to sign in to Microsoft Teams.\n\n` +
|
|
430
|
+
`Example: Call the 'authenticate' tool, then follow the instructions to sign in.`);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Clear stored authentication (device-code mode)
|
|
434
|
+
*/
|
|
435
|
+
logout() {
|
|
436
|
+
this.accessToken = null;
|
|
437
|
+
this.tokenExpirationTime = 0;
|
|
438
|
+
this.pendingAuth = null;
|
|
439
|
+
try {
|
|
440
|
+
if (fs.existsSync(TOKEN_FILE)) {
|
|
441
|
+
fs.unlinkSync(TOKEN_FILE);
|
|
442
|
+
console.error("Teams authentication cleared");
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
catch (error) {
|
|
446
|
+
console.error("Could not clear token file:", error);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Get or create Graph client with current access token
|
|
451
|
+
*/
|
|
452
|
+
async getGraphClient() {
|
|
453
|
+
const token = await this.getAccessToken();
|
|
454
|
+
this.graphClient = Client.initWithMiddleware({
|
|
455
|
+
authProvider: {
|
|
456
|
+
getAccessToken: async () => token,
|
|
457
|
+
},
|
|
458
|
+
});
|
|
459
|
+
return this.graphClient;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Get the effective team ID (from parameter or default)
|
|
463
|
+
*/
|
|
464
|
+
getTeamId(teamId) {
|
|
465
|
+
const effectiveTeamId = teamId || this.config.defaultTeamId;
|
|
466
|
+
if (!effectiveTeamId) {
|
|
467
|
+
throw new Error("Team ID is required. Either provide teamId parameter or set TEAMS_DEFAULT_TEAM_ID environment variable.");
|
|
468
|
+
}
|
|
469
|
+
return effectiveTeamId;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Get the effective channel ID (from parameter or default)
|
|
473
|
+
*/
|
|
474
|
+
getChannelId(channelId) {
|
|
475
|
+
const effectiveChannelId = channelId || this.config.defaultChannelId;
|
|
476
|
+
if (!effectiveChannelId) {
|
|
477
|
+
throw new Error("Channel ID is required. Either provide channelId parameter or set TEAMS_DEFAULT_CHANNEL_ID environment variable.");
|
|
478
|
+
}
|
|
479
|
+
return effectiveChannelId;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* List teams the user/app has access to
|
|
483
|
+
*/
|
|
484
|
+
async listTeams() {
|
|
485
|
+
const client = await this.getGraphClient();
|
|
486
|
+
try {
|
|
487
|
+
// For user auth, use /me/joinedTeams; for app auth, use /groups filter
|
|
488
|
+
const endpoint = this.config.authMode === "device-code"
|
|
489
|
+
? "/me/joinedTeams"
|
|
490
|
+
: "/groups?$filter=resourceProvisioningOptions/Any(x:x eq 'Team')";
|
|
491
|
+
const response = await client
|
|
492
|
+
.api(endpoint)
|
|
493
|
+
.select("id,displayName,description")
|
|
494
|
+
.top(100)
|
|
495
|
+
.get();
|
|
496
|
+
return (response.value || []).map((team) => ({
|
|
497
|
+
id: team.id,
|
|
498
|
+
displayName: team.displayName,
|
|
499
|
+
description: team.description,
|
|
500
|
+
}));
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
504
|
+
throw new Error(`Failed to list teams: ${message}`);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* List channels in a team
|
|
509
|
+
*/
|
|
510
|
+
async listChannels(teamId) {
|
|
511
|
+
const client = await this.getGraphClient();
|
|
512
|
+
const effectiveTeamId = this.getTeamId(teamId);
|
|
513
|
+
try {
|
|
514
|
+
const response = await client
|
|
515
|
+
.api(`/teams/${effectiveTeamId}/channels`)
|
|
516
|
+
.select("id,displayName,description,membershipType")
|
|
517
|
+
.get();
|
|
518
|
+
return (response.value || []).map((channel) => ({
|
|
519
|
+
id: channel.id,
|
|
520
|
+
displayName: channel.displayName,
|
|
521
|
+
description: channel.description,
|
|
522
|
+
membershipType: channel.membershipType,
|
|
523
|
+
}));
|
|
524
|
+
}
|
|
525
|
+
catch (error) {
|
|
526
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
527
|
+
throw new Error(`Failed to list channels: ${message}`);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Send a text or HTML message to a channel
|
|
532
|
+
*/
|
|
533
|
+
async sendChannelMessage(content, options = {}) {
|
|
534
|
+
const client = await this.getGraphClient();
|
|
535
|
+
const effectiveTeamId = this.getTeamId(options.teamId);
|
|
536
|
+
const effectiveChannelId = this.getChannelId(options.channelId);
|
|
537
|
+
const messagePayload = {
|
|
538
|
+
body: {
|
|
539
|
+
content,
|
|
540
|
+
contentType: options.contentType || "html",
|
|
541
|
+
},
|
|
542
|
+
};
|
|
543
|
+
if (options.importance && options.importance !== "normal") {
|
|
544
|
+
messagePayload.importance = options.importance;
|
|
545
|
+
}
|
|
546
|
+
try {
|
|
547
|
+
const result = await client
|
|
548
|
+
.api(`/teams/${effectiveTeamId}/channels/${effectiveChannelId}/messages`)
|
|
549
|
+
.post(messagePayload);
|
|
550
|
+
return {
|
|
551
|
+
messageId: result.id,
|
|
552
|
+
webUrl: result.webUrl,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
catch (error) {
|
|
556
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
557
|
+
throw new Error(`Failed to send channel message: ${message}`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Send an Adaptive Card to a channel
|
|
562
|
+
*/
|
|
563
|
+
async sendAdaptiveCard(card, options = {}) {
|
|
564
|
+
const client = await this.getGraphClient();
|
|
565
|
+
const effectiveTeamId = this.getTeamId(options.teamId);
|
|
566
|
+
const effectiveChannelId = this.getChannelId(options.channelId);
|
|
567
|
+
const messagePayload = {
|
|
568
|
+
body: {
|
|
569
|
+
contentType: "html",
|
|
570
|
+
content: "",
|
|
571
|
+
},
|
|
572
|
+
attachments: [
|
|
573
|
+
{
|
|
574
|
+
id: "adaptive-card-1",
|
|
575
|
+
contentType: "application/vnd.microsoft.card.adaptive",
|
|
576
|
+
content: JSON.stringify(card),
|
|
577
|
+
},
|
|
578
|
+
],
|
|
579
|
+
};
|
|
580
|
+
if (options.importance && options.importance !== "normal") {
|
|
581
|
+
messagePayload.importance = options.importance;
|
|
582
|
+
}
|
|
583
|
+
try {
|
|
584
|
+
const result = await client
|
|
585
|
+
.api(`/teams/${effectiveTeamId}/channels/${effectiveChannelId}/messages`)
|
|
586
|
+
.post(messagePayload);
|
|
587
|
+
return {
|
|
588
|
+
messageId: result.id,
|
|
589
|
+
webUrl: result.webUrl,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
catch (error) {
|
|
593
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
594
|
+
throw new Error(`Failed to send adaptive card: ${message}`);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
//# sourceMappingURL=TeamsService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TeamsService.js","sourceRoot":"","sources":["../src/TeamsService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adaptive Card Templates for Release Announcements
|
|
3
|
+
*/
|
|
4
|
+
import type { AdaptiveCard, ReleaseTemplateData, CardTemplate } from "../types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Get a card from a template
|
|
7
|
+
*/
|
|
8
|
+
export declare function getCardFromTemplate(template: CardTemplate, data: ReleaseTemplateData): AdaptiveCard;
|
|
9
|
+
/**
|
|
10
|
+
* Available templates
|
|
11
|
+
*/
|
|
12
|
+
export declare const AVAILABLE_TEMPLATES: CardTemplate[];
|
|
13
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cards/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAoOnF;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,mBAAmB,GACxB,YAAY,CAWd;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAAY,EAI7C,CAAC"}
|