When AutoSend fires deliverability event webhooks (bounces, complaints, deliveries) to our NestJS backend, network retries can deliver duplicate payloads. How do we implement idempotent event processing with Redis?
Why Idempotency Matters for Email Event Webhooks
When handling high-volume email webhooks, network retries or transient 5xx responses can cause AutoSend to retry event notifications. Without idempotency guards, duplicate webhook events can corrupt analytics counters or trigger duplicate database updates.
Implementation with NestJS and Redis:
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { RedisService } from './redis.service';
@Injectable()
export class WebhookIdempotencyGuard implements CanActivate {
constructor(private readonly redis: RedisService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const req = context.switchToHttp().getRequest();
const eventId = req.headers['x-autosend-event-id'] || req.body?.eventId;
if (!eventId) return true; // Fallback if no ID present
const redisKey = `autosend:evt:${eventId}`;
// SETNX with a 24-hour TTL ensures duplicate events within 24h are ignored
const isNew = await this.redis.client.set(redisKey, '1', 'EX', 86400, 'NX');
if (!isNew) {
// Duplicate event — return 200 OK immediately without processing
return false;
}
return true;
}
}
Key Takeaways:
- Always respond with HTTP
200 OKon duplicate events so AutoSend stops retrying. - Use Redis
SETNXwith a TTL to track processedeventIdkeys efficiently.