Skip to content

Commit 49e548c

Browse files
Refactoring Microsoft Teams code to reliably check for external users. (#14755)
* Refactoring Microsoft Teams code to reliably check for external users and label them without Global Admin permissions. * package bump. * Linter changes. * lint edits * Updating to use correct query syntax.
1 parent f7669f1 commit 49e548c

File tree

13 files changed

+73
-79
lines changed

13 files changed

+73
-79
lines changed

components/microsoft_teams/actions/create-channel/create-channel.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
name: "Create Channel",
66
description: "Create a new channel in Microsoft Teams. [See the docs here](https://docs.microsoft.com/en-us/graph/api/channel-post?view=graph-rest-1.0&tabs=http)",
77
type: "action",
8-
version: "0.0.7",
8+
version: "0.0.8",
99
props: {
1010
microsoftTeams,
1111
teamId: {

components/microsoft_teams/actions/list-channels/list-channels.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
name: "List Channels",
66
description: "Lists all channels in a Microsoft Team. [See the docs here](https://docs.microsoft.com/en-us/graph/api/channel-list?view=graph-rest-1.0&tabs=http)",
77
type: "action",
8-
version: "0.0.7",
8+
version: "0.0.8",
99
props: {
1010
microsoftTeams,
1111
teamId: {

components/microsoft_teams/actions/list-shifts/list-shifts.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
name: "List Shifts",
66
description: "Get the list of shift instances for a team. [See the documentation](https://learn.microsoft.com/en-us/graph/api/schedule-list-shifts?view=graph-rest-1.0&tabs=http)",
77
type: "action",
8-
version: "0.0.4",
8+
version: "0.0.5",
99
props: {
1010
microsoftTeams,
1111
teamId: {

components/microsoft_teams/actions/send-channel-message/send-channel-message.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
name: "Send Channel Message",
66
description: "Send a message to a team's channel. [See the docs here](https://docs.microsoft.com/en-us/graph/api/channel-post-messages?view=graph-rest-1.0&tabs=http)",
77
type: "action",
8-
version: "0.0.7",
8+
version: "0.0.8",
99
props: {
1010
microsoftTeams,
1111
teamId: {

components/microsoft_teams/actions/send-chat-message/send-chat-message.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
name: "Send Chat Message",
66
description: "Send a message to a team's chat. [See the docs here](https://docs.microsoft.com/en-us/graph/api/chat-post-messages?view=graph-rest-1.0&tabs=http)",
77
type: "action",
8-
version: "0.0.7",
8+
version: "0.0.8",
99
props: {
1010
microsoftTeams,
1111
chatId: {

components/microsoft_teams/microsoft_teams.app.mjs

Lines changed: 61 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export default {
3434
label: "Channel",
3535
description: "Team Channel",
3636
async options({
37-
teamId, prevContext,
37+
teamId,
38+
prevContext,
3839
}) {
3940
const response = prevContext.nextLink
4041
? await this.makeRequest({
@@ -58,76 +59,77 @@ export default {
5859
chat: {
5960
type: "string",
6061
label: "Chat",
61-
description: "Team Chat (internal and external contacts)",
62-
async options({ prevContext }) {
63-
const response = prevContext.nextLink
62+
description: "Select a chat (type to search by participant names)",
63+
async options({
64+
prevContext, query,
65+
}) {
66+
let path = "/chats?$expand=members";
67+
path += "&$top=20";
68+
69+
if (query) {
70+
path += `&$search="${query}"`;
71+
}
72+
73+
const response = prevContext?.nextLink
6474
? await this.makeRequest({
6575
path: prevContext.nextLink,
6676
})
67-
: await this.listChats();
68-
69-
const myTenantId = await this.getAuthenticatedUserTenant();
70-
const options = [];
77+
: await this.makeRequest({
78+
path,
79+
});
7180

7281
this._userCache = this._userCache || new Map();
82+
const options = [];
7383

7484
for (const chat of response.value) {
75-
const messages = await this.makeRequest({
76-
path: `/chats/${chat.id}/messages?$top=50`,
77-
});
78-
79-
const members = await Promise.all(chat.members.map(async (member) => {
80-
const cacheKey = `user_${member.userId}`;
81-
let displayName = member.displayName || this._userCache.get(cacheKey);
85+
let members = chat.members.map((member) => ({
86+
displayName: member.displayName,
87+
wasNull: !member.displayName,
88+
userId: member.userId,
89+
email: member.email,
90+
}));
8291

83-
if (!displayName) {
84-
try {
85-
if (messages?.value?.length > 0) {
86-
const userMessage = messages.value.find((msg) =>
87-
msg.from?.user?.id === member.userId);
88-
if (userMessage?.from?.user?.displayName) {
89-
displayName = userMessage.from.user.displayName;
90-
}
91-
}
92+
if (members.some((member) => !member.displayName)) {
93+
try {
94+
const messages = await this.makeRequest({
95+
path: `/chats/${chat.id}/messages?$top=10&$orderby=createdDateTime desc`,
96+
});
9297

93-
if (!displayName) {
94-
const userDetails = await this.makeRequest({
95-
path: `/users/${member.userId}`,
96-
});
97-
displayName = userDetails.displayName;
98+
const nameMap = new Map();
99+
messages.value.forEach((msg) => {
100+
if (msg.from?.user?.id && msg.from?.user?.displayName) {
101+
nameMap.set(msg.from.user.id, msg.from.user.displayName);
98102
}
103+
});
99104

100-
this._userCache.set(cacheKey, displayName);
101-
} catch (err) {
102-
if (err.statusCode === 404) {
103-
displayName = "User Not Found";
104-
} else if (err.statusCode === 403) {
105-
displayName = "Access Denied";
106-
} else {
107-
displayName = "Unknown User";
108-
}
109-
console.error(`Failed to fetch user details for ${member.userId}:`, err);
110-
}
105+
members = members.map((member) => ({
106+
...member,
107+
displayName: member.displayName || nameMap.get(member.userId) || member.email || "Unknown User",
108+
}));
109+
} catch (err) {
110+
console.error(`Failed to fetch messages for chat ${chat.id}:`, err);
111111
}
112+
}
112113

113-
const isExternal = member.tenantId !== myTenantId || !member.tenantId;
114-
return isExternal
115-
? `${displayName} (External)`
116-
: displayName;
117-
}));
114+
const memberNames = members.map((member) =>
115+
member.wasNull
116+
? `${member.displayName} (External)`
117+
: member.displayName);
118118

119119
options.push({
120-
label: members.join(", "),
120+
label: memberNames.join(", "),
121121
value: chat.id,
122122
});
123123
}
124+
124125
return {
125126
options,
126127
context: {
127128
nextLink: response["@odata.nextLink"],
128129
},
129130
};
130131
},
132+
useQuery: true,
131133
},
132134
channelDisplayName: {
133135
type: "string",
@@ -168,7 +170,10 @@ export default {
168170
});
169171
},
170172
async makeRequest({
171-
method, path, params = {}, content,
173+
method,
174+
path,
175+
params = {},
176+
content,
172177
}) {
173178
const api = this.client().api(path);
174179

@@ -192,22 +197,6 @@ export default {
192197
: reduction;
193198
}, api);
194199
},
195-
async getAuthenticatedUserTenant() {
196-
try {
197-
const { value } = await this.client()
198-
.api("/organization")
199-
.get();
200-
201-
if (!value || value.length === 0) {
202-
throw new Error("No organization found");
203-
}
204-
205-
return value[0].id;
206-
} catch (error) {
207-
console.error("Failed to fetch tenant ID:", error);
208-
throw new Error("Unable to determine tenant ID");
209-
}
210-
},
211200
async authenticatedUserId() {
212201
const { id } = await this.client()
213202
.api("/me")
@@ -231,7 +220,8 @@ export default {
231220
});
232221
},
233222
async createChannel({
234-
teamId, content,
223+
teamId,
224+
content,
235225
}) {
236226
return this.makeRequest({
237227
method: "post",
@@ -240,7 +230,9 @@ export default {
240230
});
241231
},
242232
async sendChannelMessage({
243-
teamId, channelId, content,
233+
teamId,
234+
channelId,
235+
content,
244236
}) {
245237
return this.makeRequest({
246238
method: "post",
@@ -249,7 +241,8 @@ export default {
249241
});
250242
},
251243
async sendChatMessage({
252-
chatId, content,
244+
chatId,
245+
content,
253246
}) {
254247
return this.makeRequest({
255248
method: "post",
@@ -279,7 +272,8 @@ export default {
279272
.get();
280273
},
281274
async listChannelMessages({
282-
teamId, channelId,
275+
teamId,
276+
channelId,
283277
}) {
284278
return this.makeRequest({
285279
path: `/teams/${teamId}/channels/${channelId}/messages/delta`,

components/microsoft_teams/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/microsoft_teams",
3-
"version": "0.1.3",
3+
"version": "0.1.4",
44
"description": "Pipedream Microsoft Teams Components",
55
"main": "microsoft_teams.app.mjs",
66
"keywords": [

components/microsoft_teams/sources/new-channel-message/new-channel-message.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "microsoft_teams-new-channel-message",
66
name: "New Channel Message",
77
description: "Emit new event when a new message is posted in a channel",
8-
version: "0.0.8",
8+
version: "0.0.9",
99
type: "source",
1010
dedupe: "unique",
1111
props: {

components/microsoft_teams/sources/new-channel/new-channel.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "microsoft_teams-new-channel",
66
name: "New Channel",
77
description: "Emit new event when a new channel is created within a team",
8-
version: "0.0.8",
8+
version: "0.0.9",
99
type: "source",
1010
dedupe: "unique",
1111
props: {

components/microsoft_teams/sources/new-chat-message/new-chat-message.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "microsoft_teams-new-chat-message",
66
name: "New Chat Message",
77
description: "Emit new event when a new message is received in a chat",
8-
version: "0.0.8",
8+
version: "0.0.9",
99
type: "source",
1010
dedupe: "unique",
1111
props: {

0 commit comments

Comments
 (0)