Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into feat/dm-members-when-…
Browse files Browse the repository at this point in the history
…securing-the-bag
  • Loading branch information
ramiAbdou committed Dec 6, 2024
2 parents 4ed6fb6 + b29b817 commit b968fe4
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CONTRIBUTORS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,5 @@
- AbdulmajeedKabala
- amnzer
- Ifethecoder
- elizafoam
- dubemnwiz
2 changes: 1 addition & 1 deletion apps/member-profile/app/routes/_profile.profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function ProfileHeader() {
function ProfileNavigation() {
return (
<nav>
<ul className="flex flex-col gap-6">
<ul className="sticky top-8 flex flex-col gap-6">
<ProfileNavigationItem
icon={<Settings size={20} />}
label="General"
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/infrastructure/bull/bull.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ export const SlackBullJob = z.discriminatedUnion('name', [
name: z.literal('slack.joined'),
data: z.object({
email: Student.shape.email,
slackId: Student.shape.slackId,
slackId: z.string().trim().min(1),
}),
}),
z.object({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { db } from '@oyster/db';

import { type GetBullJobData } from '@/infrastructure/bull/bull.types';
import { getMemberByEmail } from '@/modules/member/queries/get-member-by-email';
import { addDirectoryLinkToSlackProfile } from '@/modules/slack/slack-profile';
import { NotFoundError } from '@/shared/errors';

export async function onSlackWorkspaceJoined({
Expand All @@ -27,4 +28,9 @@ export async function onSlackWorkspaceJoined({
})
.where('id', '=', member.id)
.execute();

await addDirectoryLinkToSlackProfile({
id: member.id,
slackId,
});
}
70 changes: 70 additions & 0 deletions packages/core/src/modules/slack/slack-profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { db, type DB } from '@oyster/db';

import { reportException } from '@/modules/sentry/use-cases/report-exception';
import { slack } from '@/modules/slack/instances';
import { ENV } from '@/shared/env';
import { RateLimiter } from '@/shared/utils/rate-limiter';

// Environment Variables

const SLACK_MEMBER_DIRECTORY_FIELD_ID = process.env
.SLACK_MEMBER_DIRECTORY_FIELD_ID as string;

// Core

/**
* @see https://api.slack.com/apis/rate-limits#tier_t3
*/
const updateProfileRateLimiter = new RateLimiter('slack:profile:update', {
rateLimit: 50,
rateLimitWindow: 60,
});

export async function addDirectoryLinkToSlackProfiles() {
const members = await db
.selectFrom('students')
.select(['email', 'id', 'slackId'])
.where('slackId', 'is not', null)
.orderBy('createdAt', 'desc')
.execute();

console.log(`Found ${members.length} members to update.`);

for (const member of members) {
console.log('Updating Slack profile...', member.email);

try {
await addDirectoryLinkToSlackProfile(member);
console.count('Updated Slack profile!');
} catch (e) {
console.count('Failed to update Slack profile.');
reportException(e);
}
}
}

/**
* Adds a member's Member Directory profile link to their Slack profile. Throws
* an error if the profile update fails.
*
* @param member - The member whose Slack profile we'll update.
*/
export async function addDirectoryLinkToSlackProfile(
member: Pick<DB['students'], 'id' | 'slackId'>
) {
await updateProfileRateLimiter.process();

const profile = {
fields: {
[SLACK_MEMBER_DIRECTORY_FIELD_ID]: {
value: new URL(`/directory/${member.id}`, ENV.STUDENT_PROFILE_URL),
},
},
};

await slack.users.profile.set({
profile: JSON.stringify(profile),
token: ENV.SLACK_ADMIN_TOKEN,
user: member.slackId as string,
});
}

0 comments on commit b968fe4

Please sign in to comment.