Image is not uploading using request.post getting undefined value - node.js

const formData = req.file('image')
const options = {
url: 'myurl'',
method: 'POST',
formData : formData
}
request.post(options, async function(err,result,body){
if(err)
{
res.json({
success: false,
message: "There are some error occured in file upload"
});
}
else
{
res.json({success: true});
}
});
I am trying to upload an image using request.post but it does not allow me to upload the image please guide how can I fix it
Please guide
Edit1:
I am using ejs as frontend.
Trying to send that uploaded image from one server(example1.com) to other server(example2.com).
Server1(example1.com) is powered with sails.js.
Thanks

Use enctype='multipart/form-data' in your ejs form.
Since you are sending that image from one backend(example1.com) to other backend(example2.com) using microservervice, first save that image in your first backend(example1.com)
Then pass that image path(example1.com/images/img1.jpg) to the post request. For example
postdata = {
imageurl: 'example1.com/images/img1.jpg',
imagesize: '1200',
}
Only example1.com can be able to access your local image path(For example: c://temp/img1.jpg). So you should upload that image in your server 1(example1.com)
Alternatively convert the image to blob type and send. This way you don't need to save the image in server1(example1.com).

Related

Telegram Bot - How to upload local files with absolute/ dynamic URL

I'm trying to send photos through telegram bot using 'sendPhoto' method with relative url (Image at file level). I'm not using any library, here is my call function:
let axiosImage = async (chatId, caption, res) => {
try {
await axios.post(`${TELEGRAM_API}/sendPhoto`,
{
headers:{'Content-Type': 'multipart/form-data'}
},{
body: {
'chat_id': chatId,
'caption': caption,
'photo': './image.jpeg'
}
})
return res.send()
} catch (e) {
console.log('\nSTATUS RESPONSE: ' + e.response.status)
console.log('\nMESSAGE RESPONSE: ' + e.response.statusText)
}}
but I'm getting this message back: {"ok":false,"error_code":400,"description":"Bad Request: there is no photo in the request"}
I tried with a web url and it sends normally.
What could I be missing? Do I have to upload the local images in some repository?
I had a similar issue recently, I managed to solve the problem using form-data npm package and built-in fs module.
const FormData = require('form-data');
const fs = require('fs');
const axiosImage = async(chatId, caption, res) => {
try {
const formData = new FormData();
formData.append('chat_id', chatId);
formData.append('photo', fs.createReadStream('./image.jpeg'));
formData.append('caption', caption);
const response = await axios.post(`${TELEGRAM_API}/sendPhoto`, formData, {
headers: formData.getHeaders(),
});
return res.send();
} catch (err) {
console.log(err);
}
}
From the Telegram api docs
If the file is already stored somewhere on the Telegram servers, you don't need to reupload it: each file object has a file_id field, simply pass this file_id as a parameter instead of uploading. There are no limits for files sent this way.
Provide Telegram with an HTTP URL for the file to be sent. Telegram will download and send the file. 5 MB max size for photos and 20 MB max for other types of content.
Post the file using multipart/form-data in the usual way that files are uploaded via the browser. 10 MB max size for photos, 50 MB for other files.
What you want to send is a file via file upload (3.). This is the answer to what you are trying to achieve:
https://stackoverflow.com/a/59177066/4668136

Forward POST request from express to mail

I generate a pdf on client side with jspdf and send it to an express server with formData
var blob = pdf.output('blob');
var formData = new FormData();
formData.append('pdf', blob);
$.ajax('http://localhost:8080/test/first',
{
method: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data){console.log(data)},
error: function(data){console.log(data)}
});
The request arrives on the server, which I can see in my console, however, I don't see the body. I am new to node and express, so I am not really clear how to test this. However, the file doesn't need to be saved on server anyway, but just forwarded to a certain email. So I thought maybe, if I manage to forward, I can actually see my pdf as an attachement. Is there a simple way to forward this formData? I already have a sceleton for it, but I am stuck how to proceed.
exports.sendForm = async (body) => {
try {
console.log(body);
// todo send form data to email: test#gmail.com
return;
} catch (err) {
return next(err);
}
};
You can use multer to handle file upload, then you can access the file in route handler from req.file
Then you can send the file as a mail attachment using nodemailer
Multer - https://www.npmjs.com/package/multer
Nodemailer example with attachment - https://nodemailer.com/message/attachments

Facebook API: cannot upload video thumbnail

I'm calling the Facebook API from a Node.js server in order to upload a video. The video has a thumbnail hosted on another server. I want to read the file from the server, pass it as a FormData to /{page-id}/videos.
I'm able to get the file and convert it to base64 data, however, everytime that I call the API I get the following error:
(#100) Invalid image format. It should be an image file data.
Here's my code:
try {
const data = await httpUtilBase.get(thumbnailUrl, { responseType: 'arraybuffer' });
thumbnailData = `data:${data.headers['content-type']};base64,${Buffer.from(data.data).toString('base64')}`;
} catch {
return next(new ErrorResponse('Cannot fetch thumbnail url', httpStatus.BAD_REQUEST));
}
const formData = new FormData();
formData.append('url', url);
formData.append('title', title);
formData.append('published', 'false');
formData.append('thumb', thumbnailData);
formData.append('access_token', facebookUtil.decryptToken(page));
I make the call to /{page-id}/videos just after and it always fails. I don't understand what the format should be.

no_file_data response in slack file upload

I'm using node.js to try to upload a csv file via slackAPI's upload file method. The method is post. I'm unsure how to make this possible because if I use the content argument instead of the file, I get the error:
{ ok: false, error: 'invalid_array_arg' }
If I use the file aargument, I still get the error:
{ ok: false, error: 'invalid_array_arg' }
There are multiple fault points in this code and I've tried to test each one but I'm sure I'm missing some information here. Here's the uploadFile Method that I created:
function uploadFile(file){
console.log(botToken);
axios.post('https://slack.com/api/files.upload', qs.stringify({token: botToken, file: file, channels: 'testing'}))
.then(function (response) {
var serverMessage = response.data;
console.log(serverMessage);
console.log("inside file upload function");
})
}
here's how I call the method:
var file = fs.createReadStream(__dirname + '/' + csvFilePath); // <--make sure this path is correct
console.log(__dirname + '/' + csvFilePath);
uploadFile(file);
And finally the output:
Bot has started!
C:\Users\i502153\WebstormProjects\slackAPIProject/accessLogs/CSV/1548430592860output.csv*
{ ok: false, error: 'invalid_array_arg' }
inside file upload function
What am I doing wrong and how to rectify this?
Links:
https://api.slack.com/methods/files.upload
https://www.npmjs.com/package/axios
Your solution won't work because you are attempting to take a stream object (file) and stringify it into a query string, which is just going to insert the nonsense string "[object]" into the query. It won't actually stream data to Slack.
Axios, unfortunately, doesn't work in node exactly like it does in the browser, and their docs can be a little confusing.
I would suggest an approach like this (untested):
const axios = require('axios');
const FormData = require('form-data');
function uploadFile(file) {
const form = new FormData();
form.append('token', botToken);
form.append('channels, 'testing');
form.append('file', file, 'optionalfilenamehere');
return axios.post('https://slack.com/api/files.upload', form, {
headers: form.getHeaders()
}).then(function (response) {
var serverMessage = response.data;
console.log(serverMessage);
console.log('inside file upload function');
});
}
I adapted this code from the suggestion in ticket https://github.com/axios/axios/issues/1006#issuecomment-320165427, there may be other helpful comments there as well if you run into issues. Good luck!
EDIT: For people reading this later, for a similar approach using request instead of axios, see related question Slack API (files.upload) using NodeJS.

Upload images into a file server and store the url to the image using nodejs

I am implementing a web app using MEAN Stack and Angular 6. There I want to submit a form with file upload. '.png' files should be uploaded.
I want to save the file in a different file server and send the url to the image.Currently I upload files into a folder in my project and save the image in db (I used ng2fileupload and multer for that.). Then it saves like this.
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAAFUCAYAAABssFR8AAAK..."
But I want to save the image url and the image should be retrived by the url. Does anyone can explain a proper method for that?
I faced the same problem a month ago and find out a solution to this problem. Though I haven't used multer in the app.
From my frontend, I will be sending an object to Node API endpoint /event which will look like:-
let img = {
content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...",
filename: 'yourfile.png'
}
At the backend, I'm using Cloudinary to store my images (Its free plan allows 10GB storage) and returns secure https URLs. So install it using npm i cloudinary and require in your api.js file.
And add the below configuration
cloudinary.config({
cloud_name: 'yourapp',
api_key: 'YOUR_KEY',
api_secret: 'YOUR_SECRET_KEY'
});
Last Step:- (Not so optimized code)
Let say I have an event Schema which has images array, where I'll be storing the URLs returned by cloudinary.
app.post('/event', (req, res) => {
try {
if (req.body.images.length > 0) {
// Creating new Event instance
const event = new Event({
images: [],
});
// Looping over every image coming in the request object from frontend
req.body.images.forEach((img) => {
const base64Data = img.content.split(',')[1];
// Writing the images in upload folder for time being
fs.writeFileSync(`./uploads/${img.filename}`, base64Data, 'base64', (err) => {
if (err) {
throw err;
}
});
/* Now that image is saved in upload folder, Cloudnary picks
the image from upload folder and store it at their cloud space.*/
cloudinary.uploader.upload(`./uploads/${img.filename}`, async (result) => {
// Cloudnary returns id & URL of the image which is pushed into the event.images array.
event.images.push({
id: result.public_id,
url: result.secure_url
});
// Once image is pushed into the array, I'm removing it from my server's upload folder using unlinkSync function
fs.unlinkSync(`./uploads/${img.filename}`);
// When all the images are uploaded then I'm sending back the response
if (req.body.images.length === event.images.length) {
await event.save();
res.send({
event,
msg: 'Event created successfully'
});
}
});
});
}
} catch (e) {
res.status(400).send(e);
}
});
P.S. Go ahead and suggest some optimization solution for this code here

Resources