Changelog #102

·

Wait for HTTP callback

Pause runs until an HTTP callback is made to the provided URL.

Matt Aitken

Matt Aitken

CEO, Trigger.dev

Image for Wait for HTTP callback

Last month we introduced our v4 beta which included "Waitpoints" – a new primitive for pausing and resuming runs.

Now when you create a Waitpoint token we give you a URL back that can be passed to a 3rd party. When they're done with the work they can make a POST request to that URL and we'll continue the run with the result.

It's easier to understand with an example. Here we're going to get Replicate to generate an image for us in the background.


import { task, wait } from "@trigger.dev/sdk";
const replicate = new Replicate({
auth: process.env.REPLICATE_API_KEY,
});
export const generateImage = task({
id: "generate-image",
run: async () => {
// You can create this token from your backend or inside a task
const token = await wait.createToken({
timeout: "10m",
});
await replicate.predictions.create({
version:
"27b93a2413e7f36cd83da926f3656280b2931564ff050bf9575f1fdf9bcd7478",
input: {
prompt: "A painting of a cat by Andy Warhol",
},
// pass the token url to Replicate's webhook, so they can "callback"
// 👇
webhook: token.url,
webhook_events_filter: ["completed"],
});
const result = await wait.forToken<Prediction>(token).unwrap();
// unwrap() throws a timeout error or returns the result 👆
return result;
},
});

When Replicate has finished processing the image it will make an HTTP POST request to the URL we gave it. That will complete the Waitpoint and the JSON body is set as the output of the Waitpoint. The run is continued with the output of the Waitpoint.

On the Cloud product we pause the run when you call wait.forToken() (so you stop being charged) and then continue the run when the HTTP callback comes in.

In the dashboard

On the waitpoint tokens page you can view the callback URL for each token. They're also shown in the inspector here and on the run logs page.

Waitpoint tokens page

Just like with regular Waitpoint tokens you can complete and timeout tokens from the inspector:

This has the same result as calling wait.completeToken() or doing an HTTP POST request to the token URL.

unwrap() vs not unwrapping

In the code above you might have noticed we used unwrap() on the wait.forToken() function.

If an error is thrown then unwrap() will throw that error, otherwise the data will just be what you received from HTTP callback. This makes the happy path a lot cleaner. In tasks if you throw an error that isn't caught the attempt will be failed, and retried depending on your retry settings.

If you don't want to use unwrap() you get back a Result type:


const result = await wait.forToken<Prediction>(token);
if (!result.ok) {
// Handle the error
// In this case it's a timeout, since that's the only error that can happen
} else {
// If successful, the data is `result.output`
const prediction = result.output;
}

This is a bit more boilerplate, but it does give you more control. Generally speaking if you want the run to fail or retry then just use unwrap().

What can I do with this?

You can save money with Trigger.dev cloud when you are doing long requests to 3rd parties that support webhook callbacks.

You can also use this yourself by passing the URL to your API and then making a POST callback when you're ready to continue the run.

Ready to start building?

Build and deploy your first task in 3 minutes.

Get started now