Nick: init
This commit is contained in:
@@ -24,6 +24,14 @@ const emailTemplates: Record<
|
||||
subject: "Rate Limit Reached - Firecrawl",
|
||||
html: "Hey there,<br/><p>You've hit one of the Firecrawl endpoint's rate limit! Take a breather and try again in a few moments. If you need higher rate limits, consider upgrading your plan. Check out our <a href='https://firecrawl.dev/pricing'>pricing page</a> for more info.</p><p>If you have any questions, feel free to reach out to us at <a href='mailto:hello@firecrawl.com'>hello@firecrawl.com</a></p><br/>Thanks,<br/>Firecrawl Team<br/><br/>Ps. this email is only sent once every 7 days if you reach a rate limit.",
|
||||
},
|
||||
[NotificationType.AUTO_RECHARGE_SUCCESS]: {
|
||||
subject: "Auto recharge successful - Firecrawl",
|
||||
html: "Hey there,<br/><p>Your account was successfully recharged with 1000 credits because your remaining credits were below the threshold.</p><br/>Thanks,<br/>Firecrawl Team<br/>",
|
||||
},
|
||||
[NotificationType.AUTO_RECHARGE_FAILED]: {
|
||||
subject: "Auto recharge failed - Firecrawl",
|
||||
html: "Hey there,<br/><p>Your auto recharge failed. Please try again manually. If the issue persists, please reach out to us at <a href='mailto:hello@firecrawl.com'>hello@firecrawl.com</a></p><br/>Thanks,<br/>Firecrawl Team<br/>",
|
||||
},
|
||||
};
|
||||
|
||||
export async function sendNotification(
|
||||
@@ -31,18 +39,20 @@ export async function sendNotification(
|
||||
notificationType: NotificationType,
|
||||
startDateString: string,
|
||||
endDateString: string,
|
||||
chunk: AuthCreditUsageChunk
|
||||
chunk: AuthCreditUsageChunk,
|
||||
bypassRecentChecks: boolean = false
|
||||
) {
|
||||
return withAuth(sendNotificationInternal)(
|
||||
team_id,
|
||||
notificationType,
|
||||
startDateString,
|
||||
endDateString,
|
||||
chunk
|
||||
chunk,
|
||||
bypassRecentChecks
|
||||
);
|
||||
}
|
||||
|
||||
async function sendEmailNotification(
|
||||
export async function sendEmailNotification(
|
||||
email: string,
|
||||
notificationType: NotificationType,
|
||||
) {
|
||||
@@ -72,90 +82,92 @@ export async function sendNotificationInternal(
|
||||
notificationType: NotificationType,
|
||||
startDateString: string,
|
||||
endDateString: string,
|
||||
chunk: AuthCreditUsageChunk
|
||||
chunk: AuthCreditUsageChunk,
|
||||
bypassRecentChecks: boolean = false
|
||||
): Promise<{ success: boolean }> {
|
||||
if (team_id === "preview") {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const fifteenDaysAgo = new Date();
|
||||
fifteenDaysAgo.setDate(fifteenDaysAgo.getDate() - 15);
|
||||
if (!bypassRecentChecks) {
|
||||
const fifteenDaysAgo = new Date();
|
||||
fifteenDaysAgo.setDate(fifteenDaysAgo.getDate() - 15);
|
||||
|
||||
const { data, error } = await supabase_service
|
||||
.from("user_notifications")
|
||||
.select("*")
|
||||
.eq("team_id", team_id)
|
||||
.eq("notification_type", notificationType)
|
||||
.gte("sent_date", fifteenDaysAgo.toISOString());
|
||||
|
||||
if (error) {
|
||||
Logger.debug(`Error fetching notifications: ${error}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
if (data.length !== 0) {
|
||||
// Logger.debug(`Notification already sent for team_id: ${team_id} and notificationType: ${notificationType} in the last 15 days`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
const { data: recentData, error: recentError } = await supabase_service
|
||||
.from("user_notifications")
|
||||
.select("*")
|
||||
.eq("team_id", team_id)
|
||||
.eq("notification_type", notificationType)
|
||||
.gte("sent_date", startDateString)
|
||||
.lte("sent_date", endDateString);
|
||||
|
||||
if (recentError) {
|
||||
Logger.debug(`Error fetching recent notifications: ${recentError}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
if (recentData.length !== 0) {
|
||||
// Logger.debug(`Notification already sent for team_id: ${team_id} and notificationType: ${notificationType} within the specified date range`);
|
||||
return { success: false };
|
||||
} else {
|
||||
console.log(`Sending notification for team_id: ${team_id} and notificationType: ${notificationType}`);
|
||||
// get the emails from the user with the team_id
|
||||
const { data: emails, error: emailsError } = await supabase_service
|
||||
.from("users")
|
||||
.select("email")
|
||||
.eq("team_id", team_id);
|
||||
|
||||
if (emailsError) {
|
||||
Logger.debug(`Error fetching emails: ${emailsError}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
for (const email of emails) {
|
||||
await sendEmailNotification(email.email, notificationType);
|
||||
}
|
||||
|
||||
const { error: insertError } = await supabase_service
|
||||
const { data, error } = await supabase_service
|
||||
.from("user_notifications")
|
||||
.insert([
|
||||
{
|
||||
team_id: team_id,
|
||||
notification_type: notificationType,
|
||||
sent_date: new Date().toISOString(),
|
||||
},
|
||||
]);
|
||||
.select("*")
|
||||
.eq("team_id", team_id)
|
||||
.eq("notification_type", notificationType)
|
||||
.gte("sent_date", fifteenDaysAgo.toISOString());
|
||||
|
||||
if (process.env.SLACK_ADMIN_WEBHOOK_URL && emails.length > 0) {
|
||||
sendSlackWebhook(
|
||||
`${getNotificationString(notificationType)}: Team ${team_id}, with email ${emails[0].email}. Number of credits used: ${chunk.adjusted_credits_used} | Number of credits in the plan: ${chunk.price_credits}`,
|
||||
false,
|
||||
process.env.SLACK_ADMIN_WEBHOOK_URL
|
||||
).catch((error) => {
|
||||
Logger.debug(`Error sending slack notification: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (insertError) {
|
||||
Logger.debug(`Error inserting notification record: ${insertError}`);
|
||||
if (error) {
|
||||
Logger.debug(`Error fetching notifications: ${error}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
if (data.length !== 0) {
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
const { data: recentData, error: recentError } = await supabase_service
|
||||
.from("user_notifications")
|
||||
.select("*")
|
||||
.eq("team_id", team_id)
|
||||
.eq("notification_type", notificationType)
|
||||
.gte("sent_date", startDateString)
|
||||
.lte("sent_date", endDateString);
|
||||
|
||||
if (recentError) {
|
||||
Logger.debug(`Error fetching recent notifications: ${recentError}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
if (recentData.length !== 0) {
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log(`Sending notification for team_id: ${team_id} and notificationType: ${notificationType}`);
|
||||
// get the emails from the user with the team_id
|
||||
const { data: emails, error: emailsError } = await supabase_service
|
||||
.from("users")
|
||||
.select("email")
|
||||
.eq("team_id", team_id);
|
||||
|
||||
if (emailsError) {
|
||||
Logger.debug(`Error fetching emails: ${emailsError}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
for (const email of emails) {
|
||||
await sendEmailNotification(email.email, notificationType);
|
||||
}
|
||||
|
||||
const { error: insertError } = await supabase_service
|
||||
.from("user_notifications")
|
||||
.insert([
|
||||
{
|
||||
team_id: team_id,
|
||||
notification_type: notificationType,
|
||||
sent_date: new Date().toISOString(),
|
||||
},
|
||||
]);
|
||||
|
||||
if (process.env.SLACK_ADMIN_WEBHOOK_URL && emails.length > 0) {
|
||||
sendSlackWebhook(
|
||||
`${getNotificationString(notificationType)}: Team ${team_id}, with email ${emails[0].email}. Number of credits used: ${chunk.adjusted_credits_used} | Number of credits in the plan: ${chunk.price_credits}`,
|
||||
false,
|
||||
process.env.SLACK_ADMIN_WEBHOOK_URL
|
||||
).catch((error) => {
|
||||
Logger.debug(`Error sending slack notification: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (insertError) {
|
||||
Logger.debug(`Error inserting notification record: ${insertError}`);
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ export function getNotificationString(
|
||||
return "Limit reached (100%)";
|
||||
case NotificationType.RATE_LIMIT_REACHED:
|
||||
return "Rate limit reached";
|
||||
case NotificationType.AUTO_RECHARGE_SUCCESS:
|
||||
return "Auto-recharge successful";
|
||||
case NotificationType.AUTO_RECHARGE_FAILED:
|
||||
return "Auto-recharge failed";
|
||||
default:
|
||||
return "Unknown notification type";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user