Skip to content

Commit

Permalink
#3044 refactoring prisma queries and misc changes
Browse files Browse the repository at this point in the history
  • Loading branch information
chpy04 committed Dec 27, 2024
1 parent 4d18129 commit 1dbb550
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 58 deletions.
4 changes: 3 additions & 1 deletion src/backend/src/controllers/slack.controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default class SlackController {
if (relatedOrganization) {
slackServices.processMessageSent(event, relatedOrganization.organizationId);
}
} catch (error: unknown) {}
} catch (error: unknown) {
console.log(error);
}
}
}
23 changes: 7 additions & 16 deletions src/backend/src/integrations/slack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,41 +182,35 @@ export const getUsersInChannel = async (channelId: string) => {

return members;
} catch (error) {
return [];
return members;
}
};

/**
* Given a slack channel id, produces the name of the channel
* @param channelId the id of the slack channel
* @returns the name of the channel
* @returns the name of the channel or undefined if it cannot be found
*/
export const getChannelName = async (channelId: string) => {
const { SLACK_BOT_TOKEN } = process.env;
if (!SLACK_BOT_TOKEN) return channelId;

try {
const channelRes = await slack.conversations.info({ channel: channelId });
return channelRes.channel?.name || 'Unknown Channel';
return channelRes.channel?.name;
} catch (error) {
return;
return undefined;
}
};

/**
* Given a slack user id, prood.uces the name of the channel
* @param userId the id of the slack user
* @returns the name of the user (real name if no display name)
* @returns the name of the user (real name if no display name), undefined if cannot be found
*/
export const getUserName = async (userId: string) => {
const { SLACK_BOT_TOKEN } = process.env;
if (!SLACK_BOT_TOKEN) return;

try {
const userRes = await slack.users.info({ user: userId });
return userRes.user?.profile?.display_name || userRes.user?.real_name || 'Unkown User';
return userRes.user?.profile?.display_name || userRes.user?.real_name;
} catch (error) {
return;
return undefined;
}
};

Expand All @@ -225,9 +219,6 @@ export const getUserName = async (userId: string) => {
* @returns the id of the workspace
*/
export const getWorkspaceId = async () => {
const { SLACK_BOT_TOKEN } = process.env;
if (!SLACK_BOT_TOKEN) return;

try {
const response = await slack.auth.test();
if (response.ok) {
Expand Down
8 changes: 2 additions & 6 deletions src/backend/src/routes/slack.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ import SlackController from '../controllers/slack.controllers';

export const slackEvents = createEventAdapter(process.env.SLACK_SIGNING_SECRET || '');

slackEvents.on('message', async (event) => {
SlackController.processMessageEvent(event);
});
slackEvents.on('message', SlackController.processMessageEvent);

slackEvents.on('error', (error) => {
console.log(error.name);
});
slackEvents.on('error', console.log);
8 changes: 5 additions & 3 deletions src/backend/src/services/announcement.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Announcement } from 'shared';
import prisma from '../prisma/prisma';
import { getAnnouncementQueryArgs } from '../prisma-query-args/announcements.query.args';
import announcementTransformer from '../transformers/announcements.transformer';
import { HttpException, NotFoundException } from '../utils/errors.utils';
import { DeletedException, HttpException, NotFoundException } from '../utils/errors.utils';

export default class AnnouncementService {
/**
Expand Down Expand Up @@ -48,7 +48,6 @@ export default class AnnouncementService {
static async updateAnnouncement(
text: string,
usersReceivedIds: string[],
dateMessageSent: Date,
senderName: string,
slackEventId: string,
slackChannelName: string,
Expand All @@ -62,6 +61,8 @@ export default class AnnouncementService {

if (!originalAnnouncement) throw new NotFoundException('Announcement', slackEventId);

if (originalAnnouncement.dateDeleted) throw new DeletedException('Announcement', slackEventId);

const announcement = await prisma.announcement.update({
where: { announcementId: originalAnnouncement.announcementId },
data: {
Expand All @@ -72,7 +73,6 @@ export default class AnnouncementService {
}))
},
slackEventId,
dateMessageSent,
senderName,
slackChannelName
},
Expand All @@ -91,6 +91,8 @@ export default class AnnouncementService {

if (!originalAnnouncement) throw new NotFoundException('Announcement', slackEventId);

if (originalAnnouncement.dateDeleted) throw new DeletedException('Announcement', slackEventId);

const announcement = await prisma.announcement.update({
where: { slackEventId },
data: {
Expand Down
12 changes: 1 addition & 11 deletions src/backend/src/services/slack.services.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import UsersService from './users.services';
import { getChannelName, getUserName } from '../integrations/slack';
import AnnouncementService from './announcement.service';
import { Announcement } from 'shared';
Expand Down Expand Up @@ -105,14 +104,6 @@ export default class slackServices {
let messageText = '';
let userIdsToNotify: string[] = [];

//Get the settings of all users in this organization to compare slack ids
const users = await UsersService.getAllUsers();
const userSettings = await Promise.all(
users.map((user) => {
return UsersService.getUserSettings(user.userId);
})
);

//get the name of the user that sent the message from slack
let userName = (await getUserName(eventMessage.user)) ?? '';

Expand All @@ -132,7 +123,7 @@ export default class slackServices {
if (richTextBlocks && richTextBlocks.length > 0 && richTextBlocks[0].elements.length > 0) {
for (const element of richTextBlocks[0].elements[0].elements) {
messageText += await blockToString(element);
userIdsToNotify = userIdsToNotify.concat(await blockToMentionedUsers(element, userSettings, event.channel));
userIdsToNotify = userIdsToNotify.concat(await blockToMentionedUsers(element, organizationId, event.channel));
}
} else {
return;
Expand All @@ -152,7 +143,6 @@ export default class slackServices {
return await AnnouncementService.updateAnnouncement(
messageText,
userIdsToNotify,
dateCreated,
userName,
eventMessage.client_msg_id,
slackChannelName,
Expand Down
43 changes: 30 additions & 13 deletions src/backend/src/utils/slack.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ChangeRequest, daysBetween, Task, UserPreview, wbsPipe, calculateEndDate } from 'shared';
import { User, User_Settings } from '@prisma/client';
import { User } from '@prisma/client';
import {
editMessage,
getChannelName,
Expand All @@ -20,6 +20,7 @@ import { WorkPackageQueryArgs } from '../prisma-query-args/work-packages.query-a
import { Prisma } from '@prisma/client';
import { userTransformer } from '../transformers/user.transformer';
import { SlackRichTextBlock } from '../services/slack.services';
import UsersService from '../services/users.services';

interface SlackMessageThread {
messageInfoId: string;
Expand Down Expand Up @@ -524,38 +525,54 @@ export const blockToString = async (block: SlackRichTextBlock) => {
/**
* Gets the users notified in a specific SlackRichTextBlock.
* @param block the block that may contain mentioned user/users
* @param usersSettings the settings of all the users in prisma
* @param orgainzationId the id of the organization corresponding to this slack channel
* @param channelId the id of the channel that the block is being sent in
* @returns an array of prisma user ids of users to be notified
*/
export const blockToMentionedUsers = async (
block: SlackRichTextBlock,
usersSettings: User_Settings[],
organizationId: string,
channelId: string
) => {
): Promise<string[]> => {
switch (block.type) {
case 'broadcast':
switch (block.range) {
case 'everyone':
return usersSettings.map((usersSettings) => usersSettings.userId);
const usersInOrg = await UsersService.getAllUsers(organizationId);
return usersInOrg.map((user) => user.userId);
case 'channel':
case 'here':
//@here behaves the same as @channel; notifies all the users in that channel
const slackIds: string[] = await getUsersInChannel(channelId);
return usersSettings
.filter((userSettings) => {
return slackIds.some((slackId) => slackId === userSettings.slackId);
})
.map((user) => user.userId);
const prismaIds: (string | undefined)[] = await Promise.all(slackIds.map(getUserIdFromSlackId));
return prismaIds.filter((id): id is string => id !== undefined);
default:
return [];
}
case 'user':
return usersSettings
.filter((userSettings) => userSettings.slackId === block.user_id)
.map((userSettings) => userSettings.userId);
const prismaId = await getUserIdFromSlackId(block.user_id ?? '');
return prismaId ? [prismaId] : [];
default:
//only broadcasts and specific user mentions add recievers to announcements
return [];
}
};

/**
* given a slack id, produce the user id of the corresponding user
* @param slackId the slack id in the settings of the user
* @returns the user id, or undefined if no users were found
*/
export const getUserIdFromSlackId = async (slackId: string): Promise<string | undefined> => {
const user = await prisma.user.findFirst({
where: {
userSettings: {
slackId
}
}
});

if (!user) return undefined;

return user.userId;
};
19 changes: 13 additions & 6 deletions src/backend/tests/integration/slackMessages.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import * as apiFunctions from '../../src/integrations/slack';
import AnnouncementService from '../../src/services/announcement.service';
import slackServices from '../../src/services/slack.services';
import { vi } from 'vitest';
import prisma from '../../src/prisma/prisma';

vi.mock('../../src/integrations/slack', async (importOriginal) => {
return {
Expand All @@ -36,6 +37,16 @@ describe('Slack message tests', () => {
batman = await createTestUser(batmanAppAdmin, orgId, batmanSettings);
superman = await createTestUser(supermanAdmin, orgId, supermanSettings);
wonderwoman = await createTestUser(wonderwomanGuest, orgId, wonderwomanSettings);
await prisma.organization.update({
where: {
organizationId: orgId
},
data: {
users: {
set: [{ userId: batman.userId }, { userId: superman.userId }, { userId: wonderwoman.userId }]
}
}
});
});

afterEach(async () => {
Expand All @@ -58,12 +69,10 @@ describe('Slack message tests', () => {
orgId
);

console.log(announcement);

expect(spy).toBeCalledTimes(1);
expect(spy).toBeCalledWith(
'test with @everyone broadcast (@everyone)',
[organization.userCreatedId, batman.userId, superman.userId, wonderwoman.userId],
[batman.userId, superman.userId, wonderwoman.userId],
new Date(1000),
'Slack User Name',
'id_1',
Expand All @@ -76,7 +85,7 @@ describe('Slack message tests', () => {
expect(announcement?.senderName).toBe('Slack User Name');
expect(announcement?.slackChannelName).toBe('Slack Channel Name');
expect(announcement?.slackEventId).toBe('id_1');
expect(announcement?.usersReceived).toHaveLength(4);
expect(announcement?.usersReceived).toHaveLength(3);
});

it('Adds message to people in channel with @channel and @mention (w/o duplicates)', async () => {
Expand Down Expand Up @@ -256,7 +265,6 @@ describe('Slack message tests', () => {
expect(updateSpy).toBeCalledWith(
'@Slack User Name added text',
[wonderwoman.userId],
new Date(1000),
'Slack User Name',
'id_1',
'Slack Channel Name',
Expand Down Expand Up @@ -302,7 +310,6 @@ describe('Slack message tests', () => {
expect(updateSpy).toBeCalledWith(
'@Slack User Name added text',
[wonderwoman.userId],
new Date(1000),
'Slack User Name',
'id_1',
'Slack Channel Name',
Expand Down
2 changes: 0 additions & 2 deletions src/backend/tests/unit/announcements.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ describe('announcement tests', () => {
const updatedAnnouncement = await AnnouncementService.updateAnnouncement(
'new text',
[batman.userId, wonderwoman.userId],
new Date(1000000000000),
'sender name',
'slack id',
'channel name',
Expand All @@ -113,7 +112,6 @@ describe('announcement tests', () => {
await AnnouncementService.updateAnnouncement(
'new text',
[batman.userId, wonderwoman.userId],
new Date(1000000000000),
'sender name',
'slack id',
'channel name',
Expand Down

0 comments on commit 1dbb550

Please sign in to comment.