Search code examples
node.jsbackendopenai-api

Node.js backend for OpenAI image generation giving error code 400


I am trying to build a backend for the first time using Node.js. This is what I need: Generate image based on prompt -> Get the image and upload it to supabase storage -> Return public URL to uploaded image. I keep getting an error that implies an authentication error (400) from OpenAI but I know the API key is valid and even made a new one just to be sure. The generation was working when I was making requests to the API directly from the front end but that leaves the API key exposed. I'm not sure what is wrong.

Node.js:

const express = require('express');
const axios = require('axios');
const bodyParser = require('body-parser');
const fs = require('fs');
const FormData = require('form-data');
const { createClient } = require('@supabase/supabase-js');

const app = express();
const port = 3000;
const apiKey = '<HIDDEN>';
const supabaseUrl = '<HIDDEN>';
const supabaseKey = '<HIDDEN>';
const supabaseBucket = 'public/posts';

const config = {
  headers: {
    'Authorization': 'Bearer ' + apiKey,
    'Content-Type': 'application/json'
  }
};

const supabase = createClient(supabaseUrl, supabaseKey);

app.use(bodyParser.json());

// Allow any access control origin
app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
  next();
});

app.post('/generate-image', async (req, res) => {
  try {
    const { text } = req.body;

    // Build the request to the Dall-e API
    const response = await axios.post(
      'https://api.openai.com/v1/images/generations',
      {
        prompt: text,
        size: "256x256",
        api_key: apiKey,
        response_format: "b64_json"
      },
      config
    );

    console.log("image created...");

    // Get the generated image as a base64-encoded string
    console.log("getting image...");
    const imageBase64 = response.data.data[0].value;

    // Upload the image to Supabase storage
    const { data: uploadData } = await supabase.storage
      .from(supabaseBucket)
      .upload(Date.now() + '.png', imageBase64, {
        cacheControl: '3600',
        upsert: false,
        contentType: 'image/png',
      });

    // Return the public URL for the uploaded file
    res.json({
      imageUrl: `${supabaseUrl}/public/${supabaseBucket}/${uploadData.Key}`,
    });
  } catch (error) {
    res.status(500).json({ message: `Failed to generate image ${error}` });
  }
});

app.listen(port, () => {
  console.log(`Server listening on port ${port}`);
});

Request from React Native app:

const generateImage = async (text: any) => {
  try {
    const response = await fetch(
      "https://endpoint.com/generate-image",
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ text }),
      }
    );
    const data = await response.json();
    console.log(data.imageUrl);
    return data.imageUrl;
  } catch (error) {
    console.error(error);
    return null;
  }
};

Response:

{
    "message": "Failed to generate image AxiosError: Request failed with status code 400"
}

Solution

  • You are sending api_key: apiKey in the request body, which the OpenAI API isn't expecting.