Workflow not found - Backend API

HI,
I have created a backend API workflow by the name upload_file. But when I test I am getting following error:

{
“statusCode”: 404,
“body”: {
“status”: “NOT_FOUND”,
“message”: “Workflow not found upload_file\n”
}
}

I have been on this for a while and not able to understand why it is not working. Please advise as I am stuck. Thanks in advance.
Thanks
Vijay Zutshi

Can you share your backend API settings and settings from where you call it?

Seem you have a \n at the end of the request… probably not the correct name for your endpoint

Thanks Jici for your reply. The \n is not there that is coming from when I tested in Postman. But as required my backend API workflow is as follows: -

Now regarding where I am calling is a Javascript as follows: -

// Create a Blob from the RTF content
var blob = new Blob([fullRtfContent], { type: “application/rtf” });

// Create a FormData object to send the file
var formData = new FormData();
formData.append("file_url", blob, "document.rtf"); // Add the file to the FormData

// Send the file to the Bubble API
fetch("https://inconversationskz.com/version-test/career/api/1.1/wf/upload_file", {
    method: "POST",
    body: formData,
})

Thanks
Vijay Zutshi

Why do you have /career in your url? This is why it’s not working.
Url is
https://inconversationskz.com/version-test/api/1.1/wf/upload_file

I even tried without career as I was just testing various combinations. So when I use https://inconversationskz.com/version-test/api/1.1/wf/upload_file, I get following error:

“statusCode”: 400,
“body”: {
“status”: “MISSING_DATA”,
“message”: “Missing parameter for workflow upload_file: parameter file_url”
}
}

Yes… because you don’t format your request as expected by Backend API.

From what I know, sending a multipart form to backend won’t work. You can use url encoded or json. (It will accept multipart… but I don’t think the file will be parsed correctly, you can see how it will be parsed using detect data) You cannot send a file the way you are trying. It must be an url or base64…

So based on your advise I made following changes: -

So not I am not getting any error. After this action I want to save the file to my dataset as follows:


So how do I set this up so that I can save the file to the database.

Thanks
Vijay

What was the result of the detect request data?

So when I click Detect Data I get as follows:

https://test-15184.bubbleapps.io/version-test/api/1.1/wf/upload_file/initialize

Thanks

Yes, and you send your request while this is waiting to detect the request. Bubble, if possible, will parse the request. You will have the list of field.

But again, from what I understand of your request, you will not be able to save the file this way. Bubble expect an URL or a base64 in a json object formatted like

{
 filename: String
 contents: Base64-encoded binary data
 private: Boolean
 attach_to: String
}

So where should I put this code. Should I put this in my Javascript code that I have created. I will put my whole javascript code as follows: -

try {
// Fetch the content inside the Rich Text Input (without toolbar)
var richText = document.querySelector(“#RTFF .ql-editor”).innerHTML; // Get inner HTML content

// Replace HTML tags with RTF syntax
var rtfContent = richText
    .replace(/<p>/g, "\\par ")          // Convert <p> to new paragraph
    .replace(/<\/p>/g, "")              // Remove closing </p>
    .replace(/<br>/g, "\\line ")        // Convert line break to RTF line
    .replace(/<strong[^>]*>/g, "\\b\\cf1 ")  // Convert <strong> to bold and blue in RTF
    .replace(/<\/strong>/g, "\\b0\\cf0 ")    // Close bold and color
    .replace(/<em[^>]*>/g, "\\i ")      // Convert <em> to italics in RTF
    .replace(/<\/em>/g, "\\i0 ")        // Close italics
    .replace(/<a href="([^"]+)"[^>]*>([^<]+)<\/a>/g, "{\\field{\\*\\fldinst{HYPERLINK \"$1\"}}{\\fldrslt{\\cf1\\ul $2}}}") // Convert <a> to blue hyperlink with underline in RTF
    .replace(/<[^>]+>/g, "");            // Remove any other remaining HTML tags

// Define the RTF header with the color table for blue text
var fullRtfContent = "{\\rtf1\\ansi\\deff0 {\\colortbl;\\red0\\green0\\blue255;} " + rtfContent + "}";

// Create a Blob from the RTF content
var blob = new Blob([fullRtfContent], { type: "application/rtf" });

// Create a FormData object to send the file
var formData = new FormData();
formData.append("file_url", blob, "document.rtf"); // Add the file to the FormData

// Send the file to the Bubble API
fetch("https://inconversationskz.com/version-test/api/1.1/wf/upload_file", {
    method: "POST",
    body: formData,
})
.then(response => {
    if (!response.ok) {
        throw new Error("Network response was not ok: " + response.statusText);
    }
    return response.json();
})
.then(data => {
    console.log("File uploaded successfully:", data);
    // Handle success (e.g., show a success message, update the UI, etc.)
})
.catch(error => {
    console.error("Error uploading file:", error); // Error handling
});

} catch (error) {
console.error("Error generating RTF file: ", error); // Error handling
}

Thanks

The first step will be to convert the blob to base64

After, you have two options
A) send directly the file to Bubble /fileupload endpoint and after, send the url returned by this request to your actual backend request
B) send a JSON instead of a multipart-form with something like

{
    "file": {
        "filename": "filename",
        "contents": "Base64-encoded binary data"
    }
}

HI,
Thanks Jici I have updated my javascript which is as follows: -

try {
// Fetch the content inside the Rich Text Input (without toolbar)
var richText = document.querySelector(“#RTFF .ql-editor”).innerHTML; // Get inner HTML content

// Replace HTML tags with RTF syntax
var rtfContent = richText
    .replace(/<p>/g, "\\par ")          // Convert <p> to new paragraph
    .replace(/<\/p>/g, "")              // Remove closing </p>
    .replace(/<br>/g, "\\line ")        // Convert line break to RTF line
    .replace(/<strong[^>]*>/g, "\\b\\cf1 ")  // Convert <strong> to bold and blue in RTF
    .replace(/<\/strong>/g, "\\b0\\cf0 ")    // Close bold and color
    .replace(/<em[^>]*>/g, "\\i ")      // Convert <em> to italics in RTF
    .replace(/<\/em>/g, "\\i0 ")        // Close italics
    .replace(/<a href="([^"]+)"[^>]*>([^<]+)<\/a>/g, "{\\field{\\*\\fldinst{HYPERLINK \"$1\"}}{\\fldrslt{\\cf1\\ul $2}}}") // Convert <a> to blue hyperlink with underline in RTF
    .replace(/<[^>]+>/g, "");            // Remove any other remaining HTML tags

// Define the RTF header with the color table for blue text
var fullRtfContent = "{\\rtf1\\ansi\\deff0 {\\colortbl;\\red0\\green0\\blue255;} " + rtfContent + "}";

// Create a Blob from the RTF content
var blob = new Blob([fullRtfContent], { type: "application/rtf" });

// Convert Blob to base64
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
    var base64data = reader.result.split(",")[1]; // Get base64 data without the metadata

    // Prepare the API request to upload the file
    var fileName = "document.rtf";
    fetch("https://inconversationskz.com/version-test/api/1.1/wf/upload_file", {
        method: "POST",
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            "file_base64": base64data,  // Send base64-encoded file
            "file_name": fileName        // Send file name
        })
    })
    .then(response => response.json())
    .then(data => {
        console.log("File uploaded successfully:", data);
        // Handle success (e.g., show a success message, update the UI, etc.)
    })
    .catch(error => {
        console.error("Error uploading file:", error); // Error handling
    });
};

} catch (error) {
console.error("Error generating RTF file: ", error); // Error handling
}

Now after this what should I do.

Thanks
Vijay

Your JSON doesn’t follow the requested payload

{
    "file": {
        "filename": "filename",
        "contents": "Base64-encoded binary data"
    }
}

You can change “file” to what you want (file_url was set in your backend WF, so you can use that), but you can’t change filename and contents key. Just values.