diff --git a/apps/api/src/services/billing/auto_charge.ts b/apps/api/src/services/billing/auto_charge.ts index 5cbad665..ace14c6e 100644 --- a/apps/api/src/services/billing/auto_charge.ts +++ b/apps/api/src/services/billing/auto_charge.ts @@ -5,7 +5,7 @@ import { redlock } from "../redlock"; import { supabase_service } from "../supabase"; import { createPaymentIntent } from "./stripe"; import { issueCredits } from "./issue_credits"; -import { sendNotification } from "../notification/email_notification"; +import { sendNotification, sendNotificationWithCustomDays } from "../notification/email_notification"; import { NotificationType } from "../../types"; import { deleteKey, getValue, setValue } from "../redis"; import { redisRateLimitClient } from "../rate-limiter"; @@ -180,6 +180,26 @@ export async function autoCharge( HOURLY_COUNTER_EXPIRY, ); + try { + // Check for frequent auto-recharges in the past week + const weeklyAutoRechargeKey = `auto-recharge-weekly:${chunk.team_id}`; + const weeklyRecharges = await redisRateLimitClient.incr(weeklyAutoRechargeKey); + // Set expiry for 7 days if not already set + await redisRateLimitClient.expire(weeklyAutoRechargeKey, 7 * 24 * 60 * 60); + + // If this is the second auto-recharge in a week, send notification + if (weeklyRecharges >= 2) { + await sendNotificationWithCustomDays( + chunk.team_id, + NotificationType.AUTO_RECHARGE_FREQUENT, + 7, // Send at most once per week + false + ); + } + } catch (error) { + logger.error(`Error sending frequent auto-recharge notification: ${error}`); + } + await sendNotification( chunk.team_id, NotificationType.AUTO_RECHARGE_SUCCESS, diff --git a/apps/api/src/services/notification/email_notification.ts b/apps/api/src/services/notification/email_notification.ts index 20458ee6..58a38cc0 100644 --- a/apps/api/src/services/notification/email_notification.ts +++ b/apps/api/src/services/notification/email_notification.ts @@ -34,6 +34,10 @@ const emailTemplates: Record< subject: "Auto recharge failed - Firecrawl", html: "Hey there,

Your auto recharge failed. Please try again manually. If the issue persists, please reach out to us at help@firecrawl.com


Thanks,
Firecrawl Team
", }, + [NotificationType.AUTO_RECHARGE_FREQUENT]: { + subject: "Consider upgrading your plan - Firecrawl", + html: "Hey there,

We've noticed frequent auto-recharges on your account. To optimize your costs and get better features, we recommend upgrading to a higher tier plan with:

View our plans at firecrawl.dev/pricing. If none fit your needs, email us at help@firecrawl.com with 'Scale pricing' in the subject and we'll quickly help you move to a scale plan.


Thanks,
Firecrawl Team
", + }, [NotificationType.CONCURRENCY_LIMIT_REACHED]: { subject: "You could be scraping faster - Firecrawl", html: `Hey there, diff --git a/apps/api/src/types.ts b/apps/api/src/types.ts index 6fc69ba6..f051b183 100644 --- a/apps/api/src/types.ts +++ b/apps/api/src/types.ts @@ -159,6 +159,7 @@ export enum NotificationType { AUTO_RECHARGE_SUCCESS = "autoRechargeSuccess", AUTO_RECHARGE_FAILED = "autoRechargeFailed", CONCURRENCY_LIMIT_REACHED = "concurrencyLimitReached", + AUTO_RECHARGE_FREQUENT = "autoRechargeFrequent", } export type ScrapeLog = {