Hello,
Trying to POST a file (in form pdf) to Files API using the Node SDK, but getting back the following error:
" [Symbol(Response internals)]: {
url: '
https://api.hubapi.com/filemanager/api/v3/files/upload
',
status: 415,
statusText: 'Unsupported Media Type',
}"
CODE:
--------------------------------------------------------------
async
function
uploadFile
(
filePath
) {
console
.
log
(
"calling uploadFile() for file: "
,
filePath
);
const
formData
=
new
FormData
();
formData
.
append
(
"folderPath"
,
'/'
);
var
options
=
{
access
:
'PUBLIC_INDEXABLE'
,
ttl
:
'P3M'
,
overwrite
:
true
,
duplicateValidationStrategy
:
'NONE'
,
duplicateValidationScope
:
'ENTIRE_PORTAL'
};
formData
.
append
(
"options"
,
JSON
.
stringify
(
options
));
formData
.
append
(
"file"
,
fs
.
createReadStream
(
filePath
));
const
response
=
await
hubspotClient
.
apiRequest
({
method
:
'POST'
,
path
:
'/filemanager/api/v3/files/upload'
,
body
:
formData
,
defaultJson
:
true
,
headers
: {
"Content-Type"
:
"application/json"
}
});
console
.
log
(
response
);
}
--------------------------------------------------------------
I have seen many other threads in this community around this error, but they all just suggest setting the Content-Type header, but I am already doing that.
Any help would be greatly appreciated.
Thanks!
@himanshurauthan
was able to get this working by doing a straight REST call with Axios instead of using the node sdk wrapper:
async
function
uploadFileAxios
(
filePath
) {
let
data
=
new
FormData
();
data
.
append
(
'file'
,
fs
.
createReadStream
(
filePath
));
data
.
append
(
'folderPath'
,
'nda'
);
data
.
append
(
'options'
,
'{"access": "PRIVATE","ttl": "P3M","overwrite": true,"duplicateValidationStrategy": "NONE","duplicateValidationScope": "ENTIRE_PORTAL"}'
);
let
config
=
{
method
:
'post'
,
maxBodyLength
:
Infinity
,
headers
: {
'Authorization'
:
`Bearer
${
HUBSPOT_ACCESS_TOKEN
}
`
,
...
data
.
getHeaders
()
},
data
:
data
};
axios
.request
(
config
)
.then
((
response
)
=>
{
console
.
log
(
JSON
.
stringify
(
response
.
data
));
})
.catch
((
error
)
=>
{
console
.
log
(
error
);
});
}
@himanshurauthan
was able to get this working by doing a straight REST call with Axios instead of using the node sdk wrapper:
async
function
uploadFileAxios
(
filePath
) {
let
data
=
new
FormData
();
data
.
append
(
'file'
,
fs
.
createReadStream
(
filePath
));
data
.
append
(
'folderPath'
,
'nda'
);
data
.
append
(
'options'
,
'{"access": "PRIVATE","ttl": "P3M","overwrite": true,"duplicateValidationStrategy": "NONE","duplicateValidationScope": "ENTIRE_PORTAL"}'
);
let
config
=
{
method
:
'post'
,
maxBodyLength
:
Infinity
,
headers
: {
'Authorization'
:
`Bearer
${
HUBSPOT_ACCESS_TOKEN
}
`
,
...
data
.
getHeaders
()
},
data
:
data
};
axios
.request
(
config
)
.then
((
response
)
=>
{
console
.
log
(
JSON
.
stringify
(
response
.
data
));
})
.catch
((
error
)
=>
{
console
.
log
(
error
);
});
}
Hello
@cwalker2
It seems that the server is rejecting the file you are trying to upload because the media type (MIME type) of the file is not supported by the API.
You mentioned that you are uploading a PDF file, so you should set the Content-Type header to "application/pdf" instead of "application/json", which is the current value in your code. The "Content-Type": "application/json" header is used to indicate that the request body is in JSON format, but in your case, you are sending a multipart/form-data request with a PDF file.
Try updating your code to set the correct Content-Type header and see if it resolves the issue
const response = await hubspotClient.apiRequest({
method: 'POST',
path: '/filemanager/api/v3/files/upload',
body: formData,
defaultJson: true,
headers: {
"Content-Type": "multipart/form-data"
Hello @himanshurauthan , I really appreciate the quick reply/suggestion. I just tried with content-type header set, but instead of a 415 I get a '400 bad request'.
```
const response = await hubspotClient . apiRequest ({
method : 'POST' ,
path : '/filemanager/api/v3/files/upload' ,
body : formData ,
defaultJson : true ,
headers : {
"Content-Type" : "multipart/form-data"
}
});
```
Response:
------------
{ url: 'https://api.hubapi.com/filemanager/api/v3/files/upload ', status: 400, statusText: 'Bad Request', headers: Headers { [Symbol(map)]: [Object: null prototype] }, }
Anything else you think I could try? Many thanks
...ormData(); data.append('file', fs.createReadStream(filePath)); data.append('folderPath', 'nda'); data.append('options', '{"access": "PRIVATE","ttl": "P3M","overwrite": true ,"d...
...ormData(); data.append('file', fs.createReadStream(filePath)); data.append('folderPath', 'nda'); data.append('options', '{"access": "PRIVATE","ttl": "P3M","overwrite": true ,"d...
Developers
Feb 26, 2024
//START END-USER CONFIGURATION
//------------------------------
//selectors for hover card triggers
var allHoverCardTriggers = '.author-name-link,.friend-list .friend a,.username a,.avatar,.user-avatar,.author-img, .authors a, .messageauthorusername a, a.lia-user-name-link, .js-latest-post-by-from a, .user-online-list li a, a.UserAvatar, .customUsersOnline a, #authors a,.dashboard-followers a.user-name, .dashboard-following a.user-name,.author-login-wrapper a, .hb-leaderboard a, .author-img-floated';
// Forward calling page's URL params to endpoint URL as well, helps with testing!
var params = (new URL(location.href)).searchParams;
var userApiUrl = '/plugins/custom/hubspot/hubspot/hovercardendpoint?' + ((params.set('user_id', '') == []._) && params.toString());
if($('.hover-card-container').length<1){
$('body').append('');
var cardWrapper = $('.hover-card-container');
var error = false;
var thisUserID = '';
var thisUserLogin = '';
var userLink ='';
var cardTimer;
var leaveTimer;
function mouseenter(Elem) {
var thisEl = Elem;
cardTimer = setTimeout(function(){
var docWidth = $(document).width();
var rightSide = false;
var userLink = thisEl.attr('href');
if($('.ViewProfilePage').length && $('img.lia-user-avatar-profile',thisEl).length){thisUserID = '';}
else if(thisEl.attr('href')=='#' || thisEl.attr('href')=='' || !userLink.match('viewprofilepage')){
return false;}
else{
var thisLen = (userLink).split('/');
thisUserID = (thisLen)[thisLen.length-1];
var thisCard = $('.profileCard[data-user='+thisUserID+']',cardWrapper);
var cardId = 'userProfileCard-'+ thisUserID;
var addAttr = thisEl.attr('aria-describedby',cardId);
var thisElTopOffset = Math.round(thisEl.offset().top+(thisEl.height()/2)+30);
var thisElbottomoffset = "auto";
var className = "";
var winHeight = $(window).height();
var elOffset = thisEl.offset();
var scrollTop = $(window).scrollTop();
var elementOffset = thisEl.offset().top;
var distanceTop = (elementOffset - scrollTop);
var distanceBottom = (winHeight + scrollTop) - (elOffset.top + thisEl.outerHeight(true));
var distanceLeft = Math.round(thisEl.offset().left);
var bodyHight = $('body').height();
var topParam = '';
var bottomparam = '';
var position = '';
var className = 'topArrow';
cardId
if(distanceBottom < 300 ){
if(distanceLeft < 59){
thisCard.removeClass('bottomArrow');
var className = 'leftArrow';
var distanceLeft = (distanceLeft)+(39);
var thisElTopOffset = (thisElTopOffset)-(150);
}else{
var thisElTopOffset = (thisElTopOffset)-(301); var className = 'bottomArrow'; thisCard.removeClass('topArrow');
thisCard.removeClass('leftArrow');
var distanceLeft = (distanceLeft)-(45);
else{
if(distanceLeft < 59){
thisCard.removeClass('topArrow');
var className = 'leftArrow';
var distanceLeft = (distanceLeft)+(39);
var thisElTopOffset = (thisElTopOffset)-(150);
}else{
thisCard.removeClass('leftArrow');
thisCard.removeClass('bottomArrow').addClass('topArrow');
var distanceLeft = (distanceLeft)-(45);
if(thisCard.length && $('.profileCard[data-user='+thisUserID+'] .preloader',cardWrapper).length<1){
$('.profileCard',cardWrapper).hide();
thisCard.addClass(className);
rightSide?thisCard.addClass('rightArrow'):thisCard.removeClass('rightArrow');
thisCard.delay(0).css({'top':(thisElTopOffset),'left':distanceLeft,'bottom':thisElbottomoffset}).fadeIn();
} else {
var ajaxReturn = '';
//just in case
thisCard.remove();
//hover card wrapper markup
var rightArrowClass = rightSide?'rightArrow':'';
if(thisElTopOffset != "auto"){
topParam = 'px';
if(thisElbottomoffset != "auto"){
bottomparam = 'px';
var profileCardHtml = '
';
$.when(
//get the background
$.ajax({
type: 'GET',
url: userApiUrl+thisUserID,
dataType: 'html',
success: function(data) {
$('.profileCard',cardWrapper).hide();
ajaxReturn = data;
.done(function(){
cardWrapper.append(profileCardHtml);
$('.profileCard[data-user='+thisUserID+']',cardWrapper).eq(0).empty().html(ajaxReturn);
if($('.profileCard[data-user='+thisUserID+'] .preloader',cardWrapper).length){
$('.profileCard[data-user='+thisUserID+'] .preloader',cardWrapper).parents('div.profileCard').remove();
.fail(function(){
//uh oh - bail out!
$('.profileCard',cardWrapper).hide();
}, 360);
function mouseleave(e) {
clearTimeout(cardTimer);
// glowingblue: When the user leaves the hovercard trigger, wait because the leaving could be
// to interact with the hovercard, if we don't wait it will just disappear...because
// we left the trigger, right...so we'll have another handler that check if the mouse is
// over the hovercard and if so clears this timer, so the card doesn't close here
leaveTimer = setTimeout(function() {
if ($('.profileCard[data-user="'+thisUserID+'"]',cardWrapper).length) {
$('.profileCard[data-user="'+thisUserID+'"]',cardWrapper).fadeOut('fast');
} else {
$(".profileCard").fadeOut('fast');
}, 2400);
$(document).on("mouseenter focusin", allHoverCardTriggers, function(event) {
if(!($(this).parents().hasClass('custom-header'))&& !($(this).parents().hasClass('green-wrap'))){
(leaveTimer !== []._) && clearTimeout(leaveTimer);
mouseenter($(this));
event.stopPropagation();
$(document).on("mouseleave focusout", allHoverCardTriggers, function(event) {
(leaveTimer !== []._) && clearTimeout(leaveTimer);
mouseleave(event);
event.stopPropagation();
// glowingblue: Add handlers for when the users interacts with the hovercard, no closing!
$('.hover-card-container').on('mouseenter', function(e) {
(leaveTimer !== []._) && clearTimeout(leaveTimer);
$('.hover-card-container').on('mouseleave', function(e) {
(leaveTimer !== []._) && clearTimeout(leaveTimer);
if ( $(e.target).is('.profileCard[style*="block"]') ) {
leaveTimer = setTimeout(function() {
$(e.target).fadeOut('fast');
}, 2400);
// glowingblue: add one global root level click handler to also close any visible hovercards
// if the user taps/clicks outside the hovercard
$(document).on('mousedown', function(e) {
if ( !$(e.target).parents('.hover-card-container').length ) {
(leaveTimer != []._) && clearTimeout(leaveTimer);
$('.hover-card-container .profileCard[style*="block"]').each(function() {
$(this).fadeOut('fast');
})(LITHIUM.jQuery);
(function($) {
document.cookie = "advocacyToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.cookie = "Crowdvocate_jwt_token=; domain=.hubspot.com; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
document.cookie = "Crowdvocate_user_ck=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
})(LITHIUM.jQuery);
(function($) {
document.addEventListener('gdpr.allow', function() {
if (document.querySelector('.lia-cookie-banner-alert-accept a')) {
document.querySelector('.lia-cookie-banner-alert-accept a').click();
})(LITHIUM.jQuery);
;(function($){
var langMap = {
'en':'hubspot_community_en',
'es':'hubspot_community_es',
'fr':'hubspot_community_fr',
'ja':'hubspot_community_jp',
'pt-br':'hubspot_community_pt',
'de':'hubspot_community_de'
var nodeType = "board";
var langScope = langMap['en'];
var isSearchPage = jQuery('body').hasClass('SearchPage');
var isIdeasLandingPage = jQuery('body').hasClass('ideaslandingpage');
if (nodeType === "community" && !isSearchPage && !isIdeasLandingPage) {
var inputFormFilter = '
';
var inputFormLocation = '
';
$('form.SearchForm').append(inputFormFilter).append(inputFormLocation);
} else if (nodeType === "community" && isIdeasLandingPage) {
var searchUrl = "/t5/forums/searchpage/tab/message?filter=location&location=idea-board:HubSpot_Ideas&collapse_discussion=true";
var query = jQuery('.SearchForm .lia-search-input-message').val();
jQuery(document).on('submit', 'form.SearchForm', function(e) {
e.preventDefault();
var newQ = "&q=" + document.querySelector('.SearchForm .lia-search-input-wrapper input.search-input').value;
window.location = window.location.origin + searchUrl + newQ;
})(LITHIUM.jQuery)
LITHIUM.InformationBox({"updateFeedbackEvent":"LITHIUM:updateAjaxFeedback","componentSelector":"#informationbox_7e6229e602a8e7","feedbackSelector":".InfoMessage"});
LITHIUM.InformationBox({"updateFeedbackEvent":"LITHIUM:updateAjaxFeedback","componentSelector":"#informationbox_7e6229e602a8e7_0","feedbackSelector":".InfoMessage"});
LITHIUM.InformationBox({"updateFeedbackEvent":"LITHIUM:updateAjaxFeedback","componentSelector":"#informationbox_7e6229e602a8e7_1","feedbackSelector":".InfoMessage"});
LITHIUM.InformationBox({"updateFeedbackEvent":"LITHIUM:updateAjaxFeedback","componentSelector":"#informationbox_7e6229e602a8e7_2","feedbackSelector":".InfoMessage"});
LITHIUM.AjaxFeedback(".lia-inline-ajax-feedback", "LITHIUM:hideAjaxFeedback", ".lia-inline-ajax-feedback-persist");
LITHIUM.Placeholder();
LITHIUM.AutoComplete({"options":{"triggerTextLength":0,"updateInputOnSelect":true,"loadingText":"Searching...","emptyText":"No Matches","successText":"Results:","defaultText":"Enter a search word","disabled":false,"footerContent":[{"scripts":"\n\n;(function($){LITHIUM.Link=function(params){var $doc=$(document);function handler(event){var $link=$(this);var token=$link.data('lia-action-token');if($link.data('lia-ajax')!==true&&token!==undefined){if(event.isPropagationStopped()===false&&event.isImmediatePropagationStopped()===false&&event.isDefaultPrevented()===false){event.stop();var $form=$('