CMS Development

Stegemann
Member | Platinum Partner
Member | Platinum Partner

Create a file upload in serverless function

SOLVE

Hi!

 

Im trying to create a serverless function that uploads a file with the hubspot api. I tried alot but can not get it to work. Please help me.

 

exports.main = async (context, sendResponse) => {
  const hs = require('@hubspot/api-client')
  const FormData = require('form-data');
  const HUBSPOT_API_KEY = process.env.HUBSPOT_API_KEY;

  const { file } = context.body;
  const content = Buffer.from(file.split(',')[1], 'base64');

  const hubspot = new hs.Client({
    apiKey: HUBSPOT_API_KEY
  });

  var fileOptions = {
    access: 'PUBLIC_INDEXABLE'
  };

  const formData = new FormData();
  formData.append("folderId", '<folderID>');
  formData.append("options", JSON.stringify(fileOptions));
  formData.append("file", content);

  try {
    const response = await hubspot.apiRequest({
      method: 'POST',
      path: '/filemanager/api/v3/files/upload',
      body: formData
    });

    sendResponse({
      body: {
        message: 'File uploaded successfully.',
      },
      statusCode: 200,
    });
  } catch (error) {
    // Limit log to 4k characters
    const errorMessage = error.message.substring(0, 2000);

    sendResponse({
      body: {
        message: 'An error occurred while uploading the file.',
        error: errorMessage,
      },
      statusCode: 500,
    });
  }
};

 

I have tried alot with the endpoint https://api.hubapi.com/files/v3/files as well but can´t get it to work. 

 

Thanks in advance!

 

/Mats

1 Accepted solution
DHolland
Solution
Participant | Platinum Partner
Participant | Platinum Partner

Create a file upload in serverless function

SOLVE

Here is what I was able to get working. 

 

I am encoding the file on the client then using buffer in the serverless function to convert it back to a file for sending to the hubspot API. 

 

 

Client

 

async function uploadFile(file) {
		async function uploadWithJSON() {
			const toBase64 = (file) =>
				new Promise((resolve, reject) => {
					const reader = new FileReader();
					reader.readAsDataURL(file);
					reader.onload = () => resolve(reader.result);
					reader.onerror = (error) => reject(error);
				});

			const data = {
				file: await toBase64(file),
				name: file.name,
			};

			return JSON.stringify(data);
		}

		var requestOptions = {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: await uploadWithJSON(),
		};

		fetch('/_hcms/api/xxxxxxx', requestOptions)
			.then((response) => response.json())
			.then((result) => {
				console.log('result', result);

				let newState = formData.map((item) => {
					if (item.name === name) {
						item.value = result.response.url;
					}
					return item;
				});
				setFormData(newState);
				setIsUploading(false);
			})
			.catch((error) => console.log('error', error));
	}

 

 

Severless Function

 

// Require axios library to make API requests
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

exports.main = (context, sendResponse) => {
	// sendResponse({ body: { response: body }, statusCode: 200 });

	const form = new FormData();

	var fileOptions = {
		access: 'PUBLIC_NOT_INDEXABLE',
		overwrite: false,
		duplicateValidationStrategy: 'NONE',
		duplicateValidationScope: 'ENTIRE_PORTAL',
	};

	const buffer = Buffer.from(context.body.file.split(',')[1], 'base64');

	form.append('file', buffer, context.body.name);
	form.append('options', JSON.stringify(fileOptions));
	form.append('folderPath', 'xxxxxxx');

	var config = {
		method: 'post',
		maxBodyLength: Infinity,
		url: 'https://api.hubapi.com/files/v3/files',
		headers: {
			Authorization: 'Bearer XXXXXXXXX',
			...form.getHeaders(),
		},
		data: form,
	};

	axios(config)
		.then(function (response) {
			console.log(JSON.stringify(response.data));
			sendResponse({ body: { response: response.data }, statusCode: 200 });
		})
		.catch(function (error) {
			console.log(error);
			sendResponse({
				body: { errormsg: error.message },
				statusCode: 500,
			});
		});
};

 

 

View solution in original post

3 Replies 3
GRajput
Key Advisor | Platinum Partner
Key Advisor | Platinum Partner

Create a file upload in serverless function

SOLVE

Hi @Stegemann 

It looks like you're on the right track with using the HubSpot API and the `form-data` library to upload a file. However, there are a few things that could be causing issues with your code.
First, make sure that you have the correct folder ID specified in `formData.append("folderId", '<folderID>');`. You can find the folder ID by going to the file manager in your HubSpot account and selecting the folder that you want to upload to. The folder ID will be in the URL, after the `folderId=` parameter.
Second, it's important to set the `Content-Type` header for the `formData` object. You can do this using `formData.getHeaders()`, which will return an object with the necessary headers. You can then pass this object to the `headers` option of the `hubspot.apiRequest()` function.
Finally, make sure that your HubSpot API key is valid and has the necessary permissions to upload files.
Here's an updated version of your code with these changes:

exports.main = async (context, sendResponse) => {
const hs = require('@hubspot/api-client')
const FormData = require('form-data');
const HUBSPOT_API_KEY = process.env.HUBSPOT_API_KEY;

const { file } = context.body;
const content = Buffer.from(file.split(',')[1], 'base64');

const hubspot = new hs.Client({
apiKey: HUBSPOT_API_KEY
});

var fileOptions = {
access: 'PUBLIC_INDEXABLE'
};

const formData = new FormData();
formData.append("folderId", '<folderID>');
formData.append("options", JSON.stringify(fileOptions));
formData.append("file", content, { filename: 'myFile.png' }); // replace 'myFile.png' with the actual filename

try {
const response = await hubspot.apiRequest({
method: 'POST',
path: '/filemanager/api/v3/files/upload',
body: formData,
headers: formData.getHeaders() // set the Content-Type header
});

sendResponse({
body: {
message: 'File uploaded successfully.',
},
statusCode: 200,
});
} catch (error) {
// Limit log to 4k characters
const errorMessage = error.message.substring(0, 2000);

sendResponse({
body: {
message: 'An error occurred while uploading the file.',
error: errorMessage,
},
statusCode: 500,
});
}
};

Make sure to replace `<folderID>` with the actual folder ID, and `'myFile.png'` with the actual filename of the file you're uploading. Let me know if this helps!

 

Please mark it as SOLUTION ACCEPTED if you like the solution & Upvote.

Thank you!




Gaurav Rajput
Director, MarTech( Growth Natives)

Book a meeting


DHolland
Solution
Participant | Platinum Partner
Participant | Platinum Partner

Create a file upload in serverless function

SOLVE

Here is what I was able to get working. 

 

I am encoding the file on the client then using buffer in the serverless function to convert it back to a file for sending to the hubspot API. 

 

 

Client

 

async function uploadFile(file) {
		async function uploadWithJSON() {
			const toBase64 = (file) =>
				new Promise((resolve, reject) => {
					const reader = new FileReader();
					reader.readAsDataURL(file);
					reader.onload = () => resolve(reader.result);
					reader.onerror = (error) => reject(error);
				});

			const data = {
				file: await toBase64(file),
				name: file.name,
			};

			return JSON.stringify(data);
		}

		var requestOptions = {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: await uploadWithJSON(),
		};

		fetch('/_hcms/api/xxxxxxx', requestOptions)
			.then((response) => response.json())
			.then((result) => {
				console.log('result', result);

				let newState = formData.map((item) => {
					if (item.name === name) {
						item.value = result.response.url;
					}
					return item;
				});
				setFormData(newState);
				setIsUploading(false);
			})
			.catch((error) => console.log('error', error));
	}

 

 

Severless Function

 

// Require axios library to make API requests
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

exports.main = (context, sendResponse) => {
	// sendResponse({ body: { response: body }, statusCode: 200 });

	const form = new FormData();

	var fileOptions = {
		access: 'PUBLIC_NOT_INDEXABLE',
		overwrite: false,
		duplicateValidationStrategy: 'NONE',
		duplicateValidationScope: 'ENTIRE_PORTAL',
	};

	const buffer = Buffer.from(context.body.file.split(',')[1], 'base64');

	form.append('file', buffer, context.body.name);
	form.append('options', JSON.stringify(fileOptions));
	form.append('folderPath', 'xxxxxxx');

	var config = {
		method: 'post',
		maxBodyLength: Infinity,
		url: 'https://api.hubapi.com/files/v3/files',
		headers: {
			Authorization: 'Bearer XXXXXXXXX',
			...form.getHeaders(),
		},
		data: form,
	};

	axios(config)
		.then(function (response) {
			console.log(JSON.stringify(response.data));
			sendResponse({ body: { response: response.data }, statusCode: 200 });
		})
		.catch(function (error) {
			console.log(error);
			sendResponse({
				body: { errormsg: error.message },
				statusCode: 500,
			});
		});
};

 

 

Stegemann
Member | Platinum Partner
Member | Platinum Partner

Create a file upload in serverless function

SOLVE

Worked great!! 
Thank you so much!

 

/Mats

0 Upvotes