问题
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.
request.setContent(object.getDataAsString());
To:
request.setContent(object.getBytes());
And, about S3Request.prototype.setContent
in the file of S3Request.gs
, please modify as follows.
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.
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