简体   繁体   中英

How to PUT media on https://api.linkedin.com/mediaUpload/ with NodeJs

When I call the route https://api.linkedin.com/v2/assets?action=registerUpload with axios

I have a response like this

{
    "value": {
        "uploadMechanism": {
            "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
                "uploadUrl": "https://api.linkedin.com/mediaUpload/C4E22AQGSNx_ko_tzLw/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQK-VkaHKm7-NQAAAXMad6RKlbsQGW9Vi3JI0iFnlEKhTdhVcSZxyxUJ5g&app=17412253&sync=1&v=beta&ut=0MQzOzxqQ7m9k1",
                "headers": {
                    "media-type-family": "STILLIMAGE"
                }
            }
        },
        "asset": "urn:li:digitalmediaAsset:C4E22QSGSNx_ko_tzLw",
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C4E22AQGSNx_ko_tzLw,urn:li:digitalmediaMediaArtifactClass:feedshare-uploadedImage)"
    }
}

I want to upload an image from my server with the upload link

 var newFile = fs.createReadStream(__dirname+"/temp/lion.png");

 const form_data = new FormData();
 form_data.append('file', newFile);
 const request_config = {
      headers: {
        'Authorization': `Bearer ${access_token}`,
        "Content-Type": "multipart/form-data"
      },
      data: {content : form_data['_streams']['1']}
    };

    const res = await  axios.put('https://api.linkedin.com/mediaUpload/C4E2OIQNQE5ILcQCU_lLA/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQIy5jpkZ0ut2AAAAXMadpS8A97cK9wOSjzagaNHo97bRPCYVZt7f5E4yQ&app=17411153&sync=1&v=beta&ut=2JZ18aO4E6m9k1', form_data, request_config);
    

But I have this response from the server

"Error: Request failed with status code 400\n    at createError (/home/node/app/node_modules/axios/lib/core/createError.js:16:15)\n    at settle (/home/node/app/node_modules/axios/lib/core/settle.js:17:12)\n    at IncomingMessage.handleStreamEnd (/home/node/app/node_modules/axios/lib/adapters/http.js:236:11)\n    at IncomingMessage.emit (events.js:198:15)\n    at endReadableNT (_stream_readable.js:1139:12)\n    at processTicksAndRejections (internal/process/task_queues.js:81:17)"

7 Months old question, but still an issue today, was trying to figure this thing for few hours.

Could have been much easier if only Linkedin would add (like a normal API) the information they expect to get, like the Content-Type header, or what encoding.

I have a URL I need to upload as an image, so I have do some extra steps, but the general idea is you need to include the Content-Type of your image, use the URL they give you to send the file, and get the file as ArrayBuffer, as well as not forget to use the PUT method.

to get ArrayBuffer, and get the content type of the file:

axios.get(imageUrl, {responseType: 'arraybuffer'}).then((imageData) => {
    const contentType = imageData.headers['content-type'];
    //The ArrayBuffer is at imageData.data
})

NOTE- Don't forget to include supportedUploadMechanism: ['SYNCHRONOUS_UPLOAD'], so the it will upload synchronously, and you won't have to send another request to make sure the upload was done successfully.

const registerUploadRequest = {
        owner:                    this.owner,
        recipes:                  ['urn:li:digitalmediaRecipe:feedshare-image'],
        serviceRelationships:     [
          {
            identifier:       'urn:li:userGeneratedContent',
            relationshipType: 'OWNER',
          },
        ],
        supportedUploadMechanism: ['SYNCHRONOUS_UPLOAD'],
      };

After I got the image data I need, I send request to /assets?action=registerUpload so I can get the id of the asset, as well as the URL I need to upload it to:

return this.post('/assets?action=registerUpload', {registerUploadRequest}).then((result) => {
        const url     = result.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl,
              assetId = result.value.asset.replace('urn:li:digitalmediaAsset:', '');
})

Note - we need the id to use the asset after upload.

After I finally got all the data I need, I simply PUT the ArrayBuffer to the url given, with the correct content-type.

return axios.put(url, imageData.data, {
          headers: {
            'Authorization': `Bearer ${this.accessToken}`,
            'Content-Type':  contentType,
          },
        })

And you are done.

IMPORTANT - they do not send any response in the data object, if the request was successful the image uploaded, if it failed, it didn't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM