The following code will produce the desired result:
It uses Cloud Scheduler to create a scheduled job on the fly and then cancels the job once a certain condition is met
const { CloudSchedulerClient } = require('@google-cloud/scheduler');
const { CloudFunctionsServiceClient } = require('@google-cloud/functions');
exports.delayed_scheduled_function = async (data, context) => {
// This function will be triggered by the Scheduler
// and will execute after the delay time has passed
console.log('Scheduled function has been triggered!');
console.log(`Triggered by ${context.resource}`);
// Check the condition
if (condition_met) {
console.log('Condition met. Cancelling scheduled function...');
// Cancel the scheduled function by deleting the Cloud Scheduler job
const schedulerClient = new CloudSchedulerClient();
const jobName = 'delayed-scheduled-function-job';
const jobPath = schedulerClient.jobPath(
process.env.GOOGLE_CLOUD_PROJECT,
process.env.GOOGLE_CLOUD_SCHEDULER_LOCATION,
jobName
);
await schedulerClient.deleteJob({ name: jobPath });
console.log(`Job ${jobName} has been cancelled.`);
}
};
exports.onCreateTrigger = async (data, context) => {
// Get the current time and calculate the delay time
const current_time = new Date();
const delay_time = new Date(current_time.getTime() + (5 * 60 * 1000)); // Delay execution for 5 minutes
// Create a Cloud Scheduler client and define the job
const schedulerClient = new CloudSchedulerClient();
const parent = schedulerClient.locationPath(
process.env.GOOGLE_CLOUD_PROJECT,
process.env.GOOGLE_CLOUD_SCHEDULER_LOCATION
);
const job = {
name: 'delayed-scheduled-function-job',
schedule: '*/30 6-17 * * 1-5',
timeZone: 'America/Los_Angeles',
httpTarget: {
uri: process.env.CLOUD_FUNCTION_URL,
httpMethod: 'POST',
body: Buffer.from('').toString('base64'),
},
retryConfig: {
retryCount: 5,
maxRetryDuration: { seconds: 600 },
minBackoffDuration: { seconds: 10 },
maxBackoffDuration: { seconds: 30 },
},
pubsubTarget: {},
updateTime: {},
state: 'ENABLED',
userUpdateTime: {},
};
// Create the job and wait for the delay time to pass
const [jobResponse] = await schedulerClient.createJob({
parent,
job,
});
console.log(`Job created: ${jobResponse.name}`);
const executionTime = delay_time.toISOString();
console.log(`Waiting until ${executionTime} to trigger the function...`);
await new Promise((resolve) => setTimeout(resolve, delay_time - current_time));
// Create a Cloud Functions client and execute the function
const functionsClient = new CloudFunctionsServiceClient();
const [operation] = await functionsClient.callFunction({
name: process.env.CLOUD_FUNCTION_NAME,
data: '',
});
const response = await operation.promise();
console.log(`Function executed: ${response.result}`);
};