How to upload to S3 Bucket using TinyPng API NodeJs - node.js

What I want to achieve.
I want to compress my images that a user uploads to my server using TinyPng Api and then Upload them to my s3 Bucket.
Code
Here is my code to upload to s3 Bucket.
var upload = multer({
storage: multerS3({
s3: s3,
bucket: 'thecuratorsbucket',
metadata: function (req, file, cb) {
cb(null, {fieldName: file.fieldname});
},
key: function (req, file, cb) {
const name ="images/" + file.originalname.toLowerCase().split(' ').join('-');
const ext = MIME_TYPE_MAP[file.mimetype];
cb(null, name + '-' + Date.now()+ '.' + ext);
// cb(null, Date.now().toString())
}
})
})
router.post('/add-product',checkAuth,upload.array("images[]", 12), adminController.postAddProduct);
TinyPng Code
const source = tinify.fromFile("large.jpg");
source.store({
service: "s3",
aws_access_key_id: "AKIAIOSFODNN7EXAMPLE",
aws_secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
region: "us-west-1",
headers: {
Cache-Control: "public, max-age=31536000"
},
path: "example-bucket/my-images/optimized.jpg"
});
link to api reference
https://tinypng.com/developers/reference/nodejs
Problem
I do not understand how to use the tinyPng code as middelware and upload to my s3 bucket.

Related

Bucket Name Duplicated in AWS S3 File Location

Im uploading image files to my S3 bucket with multer S3. Everthing goes smooth, file does get uploaded but bucket name gets duplicated in returned FILE LOCATION:
Here's the file location is s3: CORRECT in S3
https://MYBUCKET.s3.eu-west-3.amazonaws.com/1669200254736-img-intro-bg.jpg
Here's what I get as file.location in my node app: Bucket name is doubled:
https://MYBUCKET.MYBUCKET.s3.eu-west-3.amazonaws.com/1669200254736-img-intro-bg.jpg'
HERE's MY APP CODE;
const { S3Client } = require('#aws-sdk/client-s3');
const multer = require('multer');
const multerS3 = require('multer-s3');
require('dotenv').config();
const credentials = {
region: process.env.region,
credentials: {
accessKeyId: process.env.accessKeyId,
secretAccessKey: process.env.secretAccessKey,
},
};
const s3 = new S3Client(credentials);
const imageFilter = (req, file, cb) => {
if (file.mimetype.startsWith('image')) {
cb(null, true);
} else {
cb('Please upload only images.', false);
}
};
const uploadFile = multer({
storage: multerS3({
s3: s3,
bucket: 'MYBUCKET',
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, `${Date.now()}-img-${file.originalname}`);
},
}),
fileFilter: imageFilter,
limits: {
fieldSize: '50mb',
},
});
module.exports = uploadFile;
Thank you in advance for your support.
I've been searching online for a few days but of no avail.
Apparently the problem stems form underlying Amazon S3 sdk. The most recent s3 client sdk still has the issue.
Downgrade Amazon sdk to < 3.180.0, untill issue is fixed by AWS.
npm i #aws-sdk/client-s3#3.180.0
Link to Original Issue at Github

Adding multiple images in Amazon S3 bucket

I want to upload multiple images to my S3 bucket. What I wish to do is User can upload zip file of multiple Images. And from the back-end I want to Unzip the folder and place all the images into specific location in S3 bucket.
Currently I'm uploading single images using the following code.
let S3Instance = new S3({
accessKeyId: process.env.AWS_ID,
secretAccessKey: process.env.AWS_SECRET,
});
let Upload = multer({
storage: multers3({
s3: S3Instance,
bucket: process.env.BUCKET || "test-bucket",
metadata: function (req, file, cb) {
cb(null, { fieldName: file.fieldname });
},
key: function (req, file, cb) {
cb(null, uuid() + path.extname(file.originalname));
},
}),
});
I want to achieve this using node.

How I upload a video to aws s3 at the same time create a thumbnail for nodejs and mongodb

I upload videos and images using this code it was succesfull.
aws.config.update({
region: process.env.AWS_BUCKET_REGION,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_KEY,
});
const BUCKET = process.env.AWS_BUCKET_NAME;
const s3 = new aws.S3();
// Multer config
module.exports = multer({
storage: multerS3({
bucket: BUCKET,
s3: s3,
contentType: multerS3.AUTO_CONTENT_TYPE,
acl: "public-read",
key: function (req, file, cb) {
cb(null, Date.now() + file.originalname); //use Date.now() for unique file keys
},
}),
});
and this code
const file =req.file
console.log(file)
let user = new Image({
name: req.body.name,
thumbnail:req.file.location,
});
now I want to upload my video and then the video screenshot is saved bucket

Node.js Multer upload to s3 and local storage

Need to upload my images into local storage and s3
My code:
const fileStorage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, "./public/uploads");
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
/** AWS catalog */
aws.config.update({
secretAccessKey: process.env.SECRET_KEY,
accessKeyId: process.env.ACCESS_KEY,
region: "us-east-1"
});
const s3 = new aws.S3();
const awsStorage = multerS3({
s3: s3,
bucket: process.env.BUCKET_NAME,
key: function(req, file, cb) {
console.log(file);
cb(null, file.originalname);
}
});
var upload = multer({ storage: awsStorage}).array('userPhoto',10);
router.post('/postimages',function(req,res)
{
upload(req,res,function(err) {
});
});
In this case, I can upload to either local storage or S3. I am unable to upload to both places. Please help to solve this issue.
I would suggest you try multer-s3 which will upload the file directly to s3 without saving to your local. if you want to save files to your Local you can do it as well using the same.
I have uploaded files to s3 upto 18Gb without any issues.
Here is the helpful link - https://www.npmjs.com/package/multer-s3

How to Upload image wih destination Path as file.filename to Amazon s3, with Multer and expressjs

I am uploading images to Amazon S3 with Multers3 and express.
The Image is uploading but I am facing challenges uploading images to the Right Path.
For example, before integrating Multer with s3, with this code, the image will be uploaded to public/uploads/postImages/the new filename.jpg
const uploadPath = path.join('public', Post.postImageBasePath)
const imageMineTypes = ['image/jpeg', 'image/png', 'image/gif']
const upload = multer({
dest: uploadPath,
fileFilter: (req, file, callback) => {
callback(null, imageMineTypes.includes(file.mimetype) )
}
})
But after integrating Multer with Amazon S3, with this code, the image is now being uploaded to public/uploads/postImages/original file name.jpg
const uploadPath = path.join('public', Post.postImageBasePath)
const upload = multer({
storage: multerS3({
s3: s3,
bucket: bucketname,
s3BucketEndpoint:true,
endpoint:"http://" + bucketname + ".s3.amazonaws.com",
key: function (req, file, cb) {
cb(null, uploadPath + '/' + file.originalname);
}
})
})
If I want to get the new file name then I can do something like this
req.file.filename but this is only possible inside my upload and that is after the image has been successfully uploaded. if try to do it inside the above code it will show undefined, because the new file name has not yet been generated. below is my code for upload.
router.post('/', upload.single('cover'), async (req, res, next) => {
const fileName = req.file != null ? req.file.filename : null
const post = new Post({
title: req.body.title,
description: req.body.description,
from: req.body.from,
postImage: fileName
})
try {
const newPost = await post.save()
res.redirect('/posts')
} catch {
if (post.postImage != null) {
removePostImage(post.postImage)
}
renderNewPage(res, post, true)
}
});
How do I add dest: uploadPath, path with S3? so that the path will be
public/uploads/postImages/new file name.jpg
This is what i want to achieve
const uploadPath = path.join('public', Post.postImageBasePath)
const imageMineTypes = ['image/jpeg', 'image/png', 'image/gif']
const upload = multer({
storage: multerS3({
dest: uploadPath,
s3: s3,
bucket: bucketname,
s3BucketEndpoint:true,
endpoint:"http://" + bucketname + ".s3.amazonaws.com",
key: function (req, file, cb) {
cb(null, uploadPath + '/' + req.file.filename);
},
fileFilter: (req, file, callback) => {
callback(null, imageMineTypes.includes(file.mimetype) )
}
})
})
In Summary, I want the image path to be the new image name that has been generated

Resources