59 lines
1.9 KiB
JavaScript
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 }
|
|
}
|