fix(email): handle sweego complaints as hard bounces
This commit is contained in:
parent
61984cd1a6
commit
3cc07f5e9f
@ -126,13 +126,13 @@ export class SweegoWebhookService {
|
||||
}
|
||||
|
||||
async processEvent(event: SweegoEvent): Promise<void> {
|
||||
if (event.event_type !== 'soft-bounce' && event.event_type !== 'hard_bounce') {
|
||||
if (event.event_type !== 'soft-bounce' && event.event_type !== 'hard_bounce' && event.event_type !== 'complaint') {
|
||||
Logger.debug({eventType: event.event_type, recipient: event.recipient}, 'Sweego event received (ignored)');
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.event_type === 'hard_bounce') {
|
||||
await this.handleHardBounce(event);
|
||||
if (event.event_type === 'hard_bounce' || event.event_type === 'complaint') {
|
||||
await this.handleHardBounceOrComplaint(event);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ export class SweegoWebhookService {
|
||||
);
|
||||
}
|
||||
|
||||
private async handleHardBounce(event: SweegoEvent): Promise<void> {
|
||||
private async handleHardBounceOrComplaint(event: SweegoEvent): Promise<void> {
|
||||
Logger.warn(
|
||||
{
|
||||
recipient: event.recipient,
|
||||
@ -150,7 +150,7 @@ export class SweegoWebhookService {
|
||||
details: event.details,
|
||||
eventId: event.event_id,
|
||||
},
|
||||
'Processing hard bounce - marking email as invalid',
|
||||
'Processing hard bounce or complaint - marking email as invalid',
|
||||
);
|
||||
|
||||
const user = await this.userRepository.findByEmail(event.recipient);
|
||||
|
||||
@ -170,6 +170,43 @@ describe('SweegoWebhookService', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('marks complaints as unverified', async () => {
|
||||
const userRepo = createMockUserRepository();
|
||||
const gateway = createMockGatewayService();
|
||||
const service = new SweegoWebhookService(userRepo, gateway);
|
||||
|
||||
const mockUser = {
|
||||
id: BigInt(124),
|
||||
email: 'complaint@example.com',
|
||||
emailBounced: false,
|
||||
emailVerified: true,
|
||||
suspiciousActivityFlags: 0,
|
||||
toRow: () => ({}),
|
||||
};
|
||||
(userRepo.findByEmail as ReturnType<typeof vi.fn>).mockResolvedValue(mockUser);
|
||||
(userRepo.patchUpsert as ReturnType<typeof vi.fn>).mockResolvedValue(null);
|
||||
|
||||
const event: SweegoEvent = {
|
||||
event_type: 'complaint',
|
||||
timestamp: '2026-01-29T14:21:46.729251+00:00',
|
||||
recipient: 'complaint@example.com',
|
||||
event_id: 'event-2',
|
||||
};
|
||||
|
||||
await service.processEvent(event);
|
||||
|
||||
expect(userRepo.findByEmail).toHaveBeenCalledWith('complaint@example.com');
|
||||
expect(userRepo.patchUpsert).toHaveBeenCalledWith(
|
||||
mockUser.id,
|
||||
{
|
||||
email_bounced: true,
|
||||
email_verified: false,
|
||||
suspicious_activity_flags: SuspiciousActivityFlags.REQUIRE_REVERIFIED_EMAIL,
|
||||
},
|
||||
mockUser.toRow(),
|
||||
);
|
||||
});
|
||||
|
||||
it('skips already bounced users', async () => {
|
||||
const userRepo = createMockUserRepository();
|
||||
const gateway = createMockGatewayService();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user