···11+import { CloudTasksClient } from "@google-cloud/tasks";
12import type { google } from "@google-cloud/tasks/build/protos/protos";
23import {
34 and,
···1213 schema,
1314} from "@openstatus/db";
1415import { session, user } from "@openstatus/db/src/schema";
1515-1616-import { CloudTasksClient } from "@google-cloud/tasks";
1716import {
1817 MonitorDeactivationEmail,
1918 MonitorPausedEmail,
2019} from "@openstatus/emails";
2120import { sendWithRender } from "@openstatus/emails/src/send";
2221import { Redis } from "@openstatus/upstash";
2222+import { RateLimiter } from "limiter";
2323import { z } from "zod";
2424import { env } from "../env";
2525···3838 env().GCP_LOCATION,
3939 "workflow",
4040);
4141+4242+const limiter = new RateLimiter({ tokensPerInterval: 50, interval: "minute" });
41434244export async function LaunchMonitorWorkflow() {
4345 // Expires is one month after last connection, so if we want to reach people who connected 3 months ago we need to check for people with expires 2 months ago
···127129 const allResult = [];
128130129131 for (const user of users) {
132132+ await limiter.removeTokens(1);
130133 const workflow = workflowInit({ user });
131134 allResult.push(workflow);
132135 }
···154157 // Let's check if the user is in the workflow
155158 const isMember = await redis.sismember("workflow:users", user.userId);
156159 if (isMember) {
160160+ console.log(`user workflow already started for ${user.userId}`);
157161 return;
158162 }
159163 // check if user has some running monitors
···166170 ),
167171 );
168172 if (nbRunningMonitor > 0) {
173173+ console.log(`user has running monitors for ${user.userId}`);
169174 return;
170175 }
171176 await CreateTask({