Implement verification panel synchronization with BullMQ integration
- Introduced a new `verificationPanelSync` job to handle posting and updating the verification panel in Discord channels via BullMQ. - Enhanced the `syncVerificationPanel` function to manage panel updates and error handling, ensuring proper feedback for synchronization issues. - Updated the WebUI to support verification panel management, including improved error messages for timeout and posting failures. - Added localization entries for new error messages related to verification panel synchronization in both English and German. - Refactored existing verification logic to accommodate the new synchronization process, improving overall functionality and user experience.
This commit is contained in:
@@ -2,6 +2,21 @@ import type { CaptchaProvider, VerificationConfigDashboard, VerificationConfigDa
|
||||
import type { Prisma } from '@prisma/client';
|
||||
import { prisma } from '../prisma';
|
||||
import { getAvailableCaptchaProviders } from '../captcha';
|
||||
import {
|
||||
addJobAndAwait,
|
||||
getVerificationQueue,
|
||||
getVerificationQueueEvents
|
||||
} from '../queues';
|
||||
|
||||
export class VerificationPanelSyncError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public readonly code: 'timeout' | 'not_posted' = 'not_posted'
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'VerificationPanelSyncError';
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureVerificationConfig(guildId: string) {
|
||||
await prisma.guild.upsert({ where: { id: guildId }, update: {}, create: { id: guildId } });
|
||||
@@ -47,6 +62,46 @@ export async function getVerificationDashboard(guildId: string): Promise<{
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Dashboard has no discord.js Client, so panel posting is delegated to the bot
|
||||
* via the `verification` BullMQ queue (`verificationPanelSync`) — same pattern
|
||||
* as self-role panels / giveaways.
|
||||
*/
|
||||
async function syncVerificationPanel(guildId: string): Promise<void> {
|
||||
const { confirmed, result } = await addJobAndAwait<{
|
||||
panelChannelId: string;
|
||||
panelMessageId: string;
|
||||
}>(
|
||||
getVerificationQueue(),
|
||||
getVerificationQueueEvents(),
|
||||
'verificationPanelSync',
|
||||
{ guildId },
|
||||
{
|
||||
jobId: `verification-panel-${guildId}-${Date.now()}`,
|
||||
removeOnComplete: true,
|
||||
removeOnFail: 25
|
||||
},
|
||||
30_000
|
||||
);
|
||||
|
||||
if (!confirmed || !result?.panelMessageId) {
|
||||
throw new VerificationPanelSyncError(
|
||||
confirmed
|
||||
? 'Verification panel job finished without posting a Discord message'
|
||||
: 'The bot did not confirm the verification panel in time. It may still be posting — check the channel shortly.',
|
||||
confirmed ? 'not_posted' : 'timeout'
|
||||
);
|
||||
}
|
||||
|
||||
const config = await prisma.verificationConfig.findUnique({ where: { guildId } });
|
||||
if (!config?.panelMessageId) {
|
||||
throw new VerificationPanelSyncError(
|
||||
'Verification panel job finished without storing a Discord message id',
|
||||
'not_posted'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateVerificationDashboard(
|
||||
guildId: string,
|
||||
patch: VerificationConfigDashboardPatch
|
||||
@@ -71,5 +126,11 @@ export async function updateVerificationDashboard(
|
||||
}
|
||||
|
||||
const updated = await prisma.verificationConfig.update({ where: { guildId }, data });
|
||||
return toDashboard(updated, getAvailableCaptchaProviders());
|
||||
const dashboard = toDashboard(updated, getAvailableCaptchaProviders());
|
||||
|
||||
if (dashboard.enabled && dashboard.channelId && dashboard.verifiedRoleId) {
|
||||
await syncVerificationPanel(guildId);
|
||||
}
|
||||
|
||||
return dashboard;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user