Skip to content

Commit

Permalink
fix: improve messages and midnight task scheduling
Browse files Browse the repository at this point in the history
  • Loading branch information
rutmanz committed Sep 9, 2024
1 parent 764850c commit 1a1b041
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 47 deletions.
4 changes: 2 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ export default tseslint.config(
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
caughtErrorsIgnorePattern: '^_'
}
],
'prefer-const': 'warn',
'@typescript-eslint/ban-ts-comment': ['warn', { 'ts-ignore': 'allow-with-description' }]
Expand Down
7 changes: 0 additions & 7 deletions src/lib/sockets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ export function startWS(server: HttpServer) {
path: '/ws'
})
logger.info('Websocket server started')

io.on('connection', (socket) => {
socket.emit('hello', 'world')
socket.on('hello', (data) => {
socket.broadcast.emit('hello', data)
})
})
}

export function emitCluckChange(data: WSCluckChange) {
Expand Down
2 changes: 1 addition & 1 deletion src/slack/blocks/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default {
autoSignoutDM(v: { slack_id: string; time_in: Date }) {
return Message()
.text(
`Hey <@${v.slack_id}>! You signed into the lab today at ${v.time_in.toLocaleTimeString()} but forgot to sign out, so we didn't log your hours for today :( Make sure you always sign out before you leave. Hope you had fun and excited to see you in the lab again!`
`Hey <@${v.slack_id}>! You signed into the lab today at ${v.time_in.toLocaleTimeString('en-us', { hour: 'numeric', hour12: true, minute: '2-digit' })} but forgot to sign out, so we didn't log your hours for today :( Make sure you always sign out before you leave. Hope you had fun and excited to see you in the lab again!`
)
.buildToObject()
}
Expand Down
19 changes: 14 additions & 5 deletions src/tasks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ import { syncSlackMembers } from '~tasks/slack'
import { announceNewCerts, updateProfileCerts } from '~tasks/certs'
import { updateSheet } from '~spreadsheet'
import { syncFallbackPhotos } from './photos'
import { setupAutoLogout } from './midnight'
import schedule from 'node-schedule'
import { logoutAll } from './midnight'

type TaskFunc = (reason: string) => Promise<void>
type TaskFunc = ((reason: string) => Promise<void>) & { label: string }
type Func = (() => void) | (() => Promise<void>)

const tasks: Record<string, TaskFunc> = {}

function createTaskFunc(task: Func): TaskFunc {
const label = 'task/' + task.name
return async (reason: string) => {
const func = async (reason: string) => {
try {
await task()
} catch (e) {
Expand All @@ -23,6 +24,8 @@ function createTaskFunc(task: Func): TaskFunc {
logger.info({ name: label }, 'Task ran successfully')
return
}
func.label = label
return func
}
function scheduleTask(task: Func, interval_seconds: number, runOnInit: boolean, offset_seconds: number): TaskFunc {
const cb = createTaskFunc(task)
Expand All @@ -39,18 +42,24 @@ function scheduleTask(task: Func, interval_seconds: number, runOnInit: boolean,
return cb
}

function scheduleCronTask(task: TaskFunc, cron_exp: string) {
schedule.scheduleJob(task.label, cron_exp, (date) => task('scheduled run'))

Check warning on line 46 in src/tasks/index.ts

View workflow job for this annotation

GitHub Actions / Lint

'date' is defined but never used. Allowed unused args must match /^_/u

Check warning on line 46 in src/tasks/index.ts

View workflow job for this annotation

GitHub Actions / ESLint Report Analysis

src/tasks/index.ts#L46

[@typescript-eslint/no-unused-vars] 'date' is defined but never used. Allowed unused args must match /^_/u.
return task
}

export function scheduleTasks() {
// Offset is to combat Slack's rate limits
const isProd = process.env.NODE_ENV === 'prod'

tasks['Sync Sheet'] = scheduleTask(updateSheet, 60 * 5, isProd, 0)
tasks['Announce Certs'] = scheduleTask(announceNewCerts, 60 * 60, isProd, 60) // Just in case the cert announcement isn't automatically run on changes
tasks['Sync Usergroups'] = scheduleTask(updateSlackUsergroups, 60 * 60, isProd, 2 * 60)
tasks['Update Profile Certs'] = scheduleTask(updateProfileCerts, 60 * 60 * 24, isProd, 5 * 60)
tasks['Link Fallback Photos'] = createTaskFunc(syncFallbackPhotos)
setupAutoLogout()
tasks['Logout All'] = scheduleCronTask(createTaskFunc(logoutAll), '0 0 * * *')

// Slack is silly and can only handle 5 items in the overflow menu
scheduleTask(syncSlackMembers, 60 * 60, isProd, 0) // can be run from the admin members page
scheduleTask(updateProfileCerts, 60 * 60 * 24, isProd, 5 * 60)
}

export async function runTask(key: string) {
Expand Down
63 changes: 31 additions & 32 deletions src/tasks/midnight.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
import { Prisma } from '@prisma/client'
import schedule from 'node-schedule'
import logger from '~lib/logger'
import prisma from '~lib/prisma'
import { emitCluckChange } from '~lib/sockets'
import { slack_client } from '~slack'
import responses from '~slack/blocks/responses'

export function setupAutoLogout() {
schedule.scheduleJob('Midnight Logout', '0 0 * * *', async (date) => {
const loggedIn = await prisma.hourLog.findMany({
where: {
state: 'pending',
type: 'lab'
},
select: { time_in: true, Member: { select: { slack_id: true } } }
})
for (const log of loggedIn) {
try {
const slack_id = log.Member.slack_id
if (slack_id) {
await slack_client.chat.postMessage({
...responses.autoSignoutDM({ slack_id, time_in: log.time_in }),
channel: log.Member.slack_id
})
}
} catch (e) {
logger.warn(e)
export async function logoutAll() {
const loggedIn = await prisma.hourLog.findMany({
where: {
state: 'pending',
type: 'lab'
},
select: { time_in: true, Member: { select: { slack_id: true, email: true } } }
})
for (const log of loggedIn) {
try {
const slack_id = log.Member.slack_id
emitCluckChange({ email: log.Member.email, logging_in: false })
if (slack_id) {
await slack_client.chat.postMessage({
...responses.autoSignoutDM({ slack_id, time_in: log.time_in }),
channel: slack_id
})
}
} catch (e) {
logger.warn(e)
}
}
await prisma.hourLog.updateMany({
where: {
state: 'pending',
type: 'lab'
},
data: {
state: 'cancelled',
time_out: new Date(),
duration: new Prisma.Decimal(0)
}
await prisma.hourLog.updateMany({
where: {
state: 'pending',
type: 'lab'
},
data: {
state: 'cancelled',
time_out: new Date(),
duration: new Prisma.Decimal(0)
}
})
})
}

0 comments on commit 1a1b041

Please sign in to comment.