Skip to content

Commit

Permalink
create bull job and create url to get recent resources within 24 hour…
Browse files Browse the repository at this point in the history
…s of timestamp
  • Loading branch information
Hamza-Mos committed Aug 6, 2024
1 parent d8d779c commit b772e66
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 0 deletions.
11 changes: 11 additions & 0 deletions apps/member-profile/app/routes/_profile.resources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '@remix-run/react';
import dayjs from 'dayjs';
import { Plus } from 'react-feather';
import { z } from 'zod';

import { isMemberAdmin } from '@oyster/core/admins';
import { track } from '@oyster/core/mixpanel';
Expand Down Expand Up @@ -46,6 +47,7 @@ const ResourcesSearchParams = ListSearchParams.pick({
[whereKeys.search]: ListResourcesWhere.shape.search,
[whereKeys.tags]: ListResourcesWhere.shape.tags.catch([]),
orderBy: ListResourcesOrderBy,
postedAfter: z.string().optional(), // filters by last 24 hrs after this timestamp when set
});

export async function loader({ request }: LoaderFunctionArgs) {
Expand All @@ -60,6 +62,14 @@ export async function loader({ request }: LoaderFunctionArgs) {
tags: url.searchParams.getAll('tags'),
});

const timestamp = searchParams.postedAfter
? new Date(searchParams.postedAfter)
: null;

const postedAfter = timestamp
? dayjs(timestamp).subtract(24, 'hours').toDate()
: undefined;

const { resources: records, totalCount } = await listResources({
memberId: user(session),
pagination: {
Expand All @@ -83,6 +93,7 @@ export async function loader({ request }: LoaderFunctionArgs) {
id: searchParams.id,
search: searchParams.search,
tags: searchParams.tags,
postedAfter,
},
});

Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/infrastructure/bull/bull.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,10 @@ export const StudentBullJob = z.discriminatedUnion('name', [
name: z.literal('student.statuses.new'),
data: z.object({}),
}),
z.object({
name: z.literal('student.resources.daily'),
data: z.object({}),
}),
]);

export const SurveyBullJob = z.discriminatedUnion('name', [
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/infrastructure/bull/use-cases/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const QueueNameFromJobName: Record<BullJob['name'], BullQueue> = {
'one_time_code.expire': 'one_time_code',
'profile.views.notification.monthly': 'profile',
'slack.birthdates.update': 'slack',
'student.resources.daily': 'slack',
'slack.channel.archive': 'slack',
'slack.channel.create': 'slack',
'slack.channel.delete': 'slack',
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/modules/member/member.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { StudentBullJob } from '@/infrastructure/bull/bull.types';
import { registerWorker } from '@/infrastructure/bull/use-cases/register-worker';
import { backfillActiveStatuses } from '@/modules/active-status/use-cases/backfill-active-statuses';
import { createNewActiveStatuses } from '@/modules/active-status/use-cases/create-new-active-statuses';
import { sendResourcesNotification } from '@/modules/member/use-cases/send-resources-notification';
import { onActivationStepCompleted } from './events/activation-step-completed';
import { onMemberActivated } from './events/member-activated';
import { onMemberCreated } from './events/member-created';
Expand Down Expand Up @@ -47,6 +48,9 @@ export const memberWorker = registerWorker(
.with({ name: 'student.statuses.new' }, ({ data }) => {
return createNewActiveStatuses(data);
})
.with({ name: 'student.resources.daily' }, ({ data }) => {
return sendResourcesNotification(data);
})
.exhaustive();
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { sql } from 'kysely';

import { db } from '@oyster/db';

import { type GetBullJobData } from '@/infrastructure/bull/bull.types';
import { job } from '@/infrastructure/bull/use-cases/job';
import { ENV } from '@/shared/env';

function buildResourceMessage(
resources: Array<{
link: string | null;
title: string;
slackId: string | null;
}>
) {
const resourceItems = resources
.map(
(resource) =>
`- [${resource.title}](${resource.link}) by <@${resource.slackId}>`
)
.join('\n');

// generating url for all resources posted within 24 hours of current timestamp
// example: /resources?postedAfter=2024-08-05T12:34:56.789Z
const currentTimestamp = new Date().toISOString();
const url = `/link-to-resource-database?timestamp=${encodeURIComponent(currentTimestamp)}`;

const message = `Some new resources were posted in the Resource Database:
${resourceItems}
Check out these latest resources [here](${url})!
Show some love if any of these are helpful!`;

return message;
}

export async function sendResourcesNotification(
_: GetBullJobData<'student.resources.daily'>
) {
const resources = await db
.selectFrom('resources')
.leftJoin('students', 'students.id', 'resources.postedBy')
.select(['resources.link', 'resources.title', 'students.slackId'])
.whereRef(
'resources.postedAt',
'>=',
sql`CURRENT_TIMESTAMP - INTERVAL '24 hours'`
)
.where('students.slackId', 'is not', null)
.where('resources.title', 'is not', null)
.where('resources.link', 'is not', null)
.execute();

if (!resources.length) {
return;
}

const message = buildResourceMessage(resources);

job('notification.slack.send', {
channel: ENV.RESOURCES_CHANNEL_ID,
message: `${message}`,
workspace: 'regular',
});
}
1 change: 1 addition & 0 deletions packages/core/src/shared/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const ENV = {
MAILCHIMP_SERVER_PREFIX: process.env.MAILCHIMP_SERVER_PREFIX as string,
MEMBER_PROFILE_URL: process.env.MEMBER_PROFILE_URL as string,
REDIS_URL: process.env.REDIS_URL as string,
RESOURCES_CHANNEL_ID: process.env.RESOURCES_CHANNEL_ID as string,
SENTRY_DSN: process.env.SENTRY_DSN as string,
SLACK_ANNOUNCEMENTS_CHANNEL_ID: process.env
.SLACK_ANNOUNCEMENTS_CHANNEL_ID as string,
Expand Down

0 comments on commit b772e66

Please sign in to comment.