Thanks to visit codestin.com
Credit goes to trigger.mintlify.dev

Skip to main content

Overview

This example demonstrates how to use Trigger.dev to generate images from source image URLs using Replicate, the nano-banana-image-to-image model.

Task code

trigger/generateImage.tsx
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { task, wait } from "@trigger.dev/sdk";
import Replicate, { Prediction } from "replicate";

// Initialize clients
const replicate = new Replicate({
  auth: process.env.REPLICATE_API_TOKEN,
});

const s3Client = new S3Client({
  region: "auto",
  endpoint: process.env.R2_ENDPOINT,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID ?? "",
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY ?? "",
  },
});

const model = "google/nano-banana";

export const generateImageAndUploadToR2 = task({
  id: "generate-image-and-upload-to-r2",
  run: async (payload: { prompt: string; imageUrl: string }) => {
    const { prompt, imageUrl } = payload;

    const token = await wait.createToken({
      timeout: "10m",
    });

    // Use Flux with structured prompt
    const output = await replicate.predictions.create({
      model: model,
      input: { prompt, image_input: [imageUrl] },
      // pass the provided 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 👆

    if (!result.ok) {
      throw new Error("Failed to create prediction");
    }

    const generatedImageUrl = result.output.output;

    const image = await fetch(generatedImageUrl);
    const imageBuffer = Buffer.from(await image.arrayBuffer());

    const base64Image = Buffer.from(imageBuffer).toString("base64");

    const timestamp = Date.now();
    const filename = `generated-${timestamp}.png`;

    // Generate unique key for R2
    const sanitizedFileName = filename.replace(/[^a-zA-Z0-9.-]/g, "_");
    const r2Key = `uploaded-images/${timestamp}-${sanitizedFileName}`;

    const uploadParams = {
      Bucket: process.env.R2_BUCKET,
      Key: r2Key,
      Body: imageBuffer,
      ContentType: "image/png",
      // Add cache control for better performance
      CacheControl: "public, max-age=31536000", // 1 year
    };

    const uploadResult = await s3Client.send(new PutObjectCommand(uploadParams));

    // Construct the public URL using the R2_PUBLIC_URL env var
    const publicUrl = `${process.env.R2_PUBLIC_URL}/${r2Key}`;

    return {
      success: true,
      publicUrl,
      originalPrompt: prompt,
      sourceImageUrl: imageUrl,
    };
  },
});

Environment variables

You will need to set the following environment variables:
TRIGGER_SECRET_KEY=<your-trigger-secret-key>
REPLICATE_API_TOKEN=<your-replicate-api-token>
R2_ENDPOINT=<your-r2-endpoint>
R2_ACCESS_KEY_ID=<your-r2-access-key-id>
R2_SECRET_ACCESS_KEY=<your-r2-secret-access-key>
R2_BUCKET=<your-r2-bucket>
R2_PUBLIC_URL=<your-r2-public-url>