ghostguild-org/server/utils/checkSlackJoins.js

59 lines
1.9 KiB
JavaScript

// server/utils/checkSlackJoins.js
import Member from '../models/member.js'
import { connectDB } from './mongoose.js'
import { WebClient } from '@slack/web-api'
const BATCH_SIZE = 15
const BATCH_DELAY_MS = 1000
/**
* Check members with pending Slack invites to see if they've joined the workspace.
* Processes in batches of 15 with 1-second delays (Slack Tier 2 rate limit).
*/
export async function checkSlackJoins(slackBotToken) {
await connectDB()
const client = new WebClient(slackBotToken)
const members = await Member.find({
slackInviteStatus: { $in: ['sent', 'accepted'] }
}).select('_id email slackInviteStatus')
if (members.length === 0) return { checked: 0, joined: 0 }
let joined = 0
for (let i = 0; i < members.length; i += BATCH_SIZE) {
const batch = members.slice(i, i + BATCH_SIZE)
for (const member of batch) {
try {
const response = await client.users.lookupByEmail({ email: member.email })
const userId = response.user?.id
if (userId) {
await Member.findByIdAndUpdate(member._id, {
slackInviteStatus: 'joined',
slackUserId: userId
})
joined++
console.log(`[check-slack-joins] ${member.email} joined Slack (${userId})`)
}
} catch (err) {
// users_not_found is expected for members who haven't joined yet
if (err.data?.error === 'users_not_found') continue
console.error(`[check-slack-joins] Error checking ${member.email}:`, err.message || err)
// Continue processing remaining members
}
}
// Delay between batches (skip after last batch)
if (i + BATCH_SIZE < members.length) {
await new Promise((resolve) => setTimeout(resolve, BATCH_DELAY_MS))
}
}
console.log(`[check-slack-joins] Done: ${joined}/${members.length} members joined`)
return { checked: members.length, joined }
}