Upload Image (PNG file) from Google App Script to S3 Bucket

强颜欢笑 提交于 2020-06-27 16:53:08

问题


Trying to upload a png file using S3-for-Google-Apps-Script to S3 bucket:

// get the image blob
const imgBlob = UrlFetchApp.fetch('imageUrl').getBlob();
  
// init S3 instance
const s3 = S3.getInstance(awsAccessKeyId, awsSecretKey);

// upload the image to S3 bucket
s3.putObject(bucketName, 'test.png', imgBlob, { logRequests:true });

File is uploading in S3 but not in perfect way! It's look like:

If I download the image and open getting the error:

"It may be damaged or use a file format that Preview doesn’t recognize."

So, how can I upload a png file to amazon S3 bucket from google-apps-script?


BTW, I can correctly upload the image when 'base64' is used to s3.putObject():

const base64 = Utilities.base64Encode(imgBlob.getBytes());
s3.putObject(bucketName, 'test.png', base64, { logRequests:true });
// go to S3 and clicking on the link I can see the base64 string

But this is uploading as String e.g. when I go S3 & click on test.png I see like: "iVBORw0KGgoAAAANSUhEUgAAAgAAAAI ... II=" but I want to see the actual Image not String!


回答1:


I believe your situation and goal as follows.

  • In your situation, the base64 data of the image can be uploaded. But, the uploaded data is not the image. It's the string data.
  • In your goal, you want to upload the image file of the publicly shared image using the image URL.

For this, how about this answer?

Issue and workaround:

When I saw the script of "S3-for-Google-Apps-Script", it seems that the URL cannot be directly used for s3.putObject(). And, the inputted blob is converted to the string type using getDataAsString(). I think that this is the reason of your issue.

In this answer, I would like to propose to modify the GAS library of "S3-for-Google-Apps-Script" for using the byte array to payload.

Usage:

At first, please copy the GAS project of S3-for-Google-Apps-Script, and please modify this as follows.

Modified script:

About S3.prototype.putObject in the file of S3.gs, please modify as follows.

From:
request.setContent(object.getDataAsString());
To:
request.setContent(object.getBytes());

And, about S3Request.prototype.setContent in the file of S3Request.gs, please modify as follows.

From:
if (typeof content != 'string') throw 'content must be passed as a string'
To:
// if (typeof content != 'string') throw 'content must be passed as a string'

And, about S3Request.prototype.getContentMd5_ in the file of S3Request.gs, please modify as follows.

From:
return Utilities.base64Encode(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, this.content, Utilities.Charset.UTF_8));
To:
return Utilities.base64Encode(Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, this.content));

Sample script:

And, for above modified script, please test the following script.

const imageUrl = "###";  // Please set the image URL.
const s3 = S3.getInstance(awsAccessKeyId, awsSecretKey);  // Please set them.

const imageBlob = UrlFetchApp.fetch(imageUrl).getBlob();
s3.putObject(bucketName, 'test.png', imageBlob, { logRequests:true });
  • By this, your token can be created by the modified library and use it.
  • When I checked this official document, I thought that the byte array might be able to be used.

References:

  • PutObject
  • S3-for-Google-Apps-Script


来源:https://stackoverflow.com/questions/61491801/upload-image-png-file-from-google-app-script-to-s3-bucket

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!