How efficiently post a tweet with a remote image with Nodejs Stream? - node.js

I need to download a remote image, that its path is saved on the wineTweet.label attribut.
And then POST a tweet with this image.
My implementation is working, but I first save the image to a file and then read it before posting it.
Here is the code :
var file = fs.createWriteStream("file.jpg");
https.get(wineTweet.label, function (response) {
response.pipe(file);
file.on('finish', function () {
var data = require('fs').readFileSync('file.jpg');
// Make post request on media endpoint. Pass file data as media parameter
client.post('media/upload', {media: data}, function (error, media, response) {
if (!error) {
// If successful, a media object will be returned. // Lets tweet it
var status = {
status : 'I am a tweet',
media_ids: media.media_id_string // Pass the media id string
}
client.post('statuses/update', status, function (error, tweet, response) {
if (!error) {
console.log(tweet);
});
}
});
});
});
How to directly connect ReadingStream to the POST request ?

Just use the response directly, which is already a Readable stream, instead of writing/reading a temporary file:
https.get(wineTweet.label, function(res) {
// Make post request on media endpoint. Pass file data as media parameter
client.post('media/upload', {media: res}, function(error, media, response) {
if (!error) {
// If successful, a media object will be returned. // Lets tweet it
var status = {
status : 'I am a tweet',
media_ids: media.media_id_string // Pass the media id string
};
client.post('statuses/update', status, function(error, tweet, response) {
if (!error)
console.log(tweet);
});
}
});
});
On an unrelated note, you should handle errors appropriately instead of ignoring them.

Related

Post image on twitter using puppeteer

Is it possible to post an image on twitter using nodejs and puppeteer? It find it hard because when you click on the image button on twitter it opens your archive.
It's definetely possible to post image on Twitter automatically (using Node.js). Twitter API Client for node called 'twit' suits for it. You can find the package on github or npm.
// post a tweet with media
var b64content = fs.readFileSync('/path/to/img', { encoding: 'base64' })
// first we must post the media to Twitter
T.post('media/upload', { media_data: b64content }, function (err, data, response) {
// now we can assign alt text to the media, for use by screen readers and
// other text-based presentations and interpreters
var mediaIdStr = data.media_id_string
var altText = "Small flowers in a planter on a sunny balcony, blossoming."
var meta_params = { media_id: mediaIdStr, alt_text: { text: altText } }
T.post('media/metadata/create', meta_params, function (err, data, response) {
if (!err) {
// now we can reference the media and post a tweet (media will attach to the tweet)
var params = { status: 'loving life #nofilter', media_ids: [mediaIdStr] }
T.post('statuses/update', params, function (err, data, response) {
console.log(data)
})
}
})
})
// post media via the chunked media upload API.
// You can then use POST statuses/update to post a tweet with the media attached as in the example above using `media_id_string`.
// Note: You can also do this yourself manually using T.post() calls if you want more fine-grained
// control over the streaming. Example: https://github.com/ttezel/twit/blob/master/tests/rest_chunked_upload.js#L20
//
var filePath = '/absolute/path/to/file.mp4'
T.postMediaChunked({ file_path: filePath }, function (err, data, response) {
console.log(data)
})

Unable to send photo using Form Submit

I've a photo and a paid upload service : http://example.com/in.php .
I'm not able to upload a given jpeg file using this code. It is telling me that invalid file format uploaded. But using file linux command I can see it is JPEG format. Is there any problem in this code?
fs.readFile('/tmp/photo.jpg'', 'utf8', function(err, contents) {
var b64 = new Buffer(contents);
var s = b64.toString('base64');
var request = require('request')
request.post('http://example.com/in.php', {
form: {
method:'base64',
key:'cplbhvnmvdn4bjxxchzgqyjz7rf9fy8w',
body:s,
}
}, function (err, res, body) {
console.log("body=",body);
console.log("res=",res);
})
});
I see no mistakes in your process of converting jpeg to base64. However, I would suggest a workaround to use a small image-to-base64 node package.
Also, there's a higher chance of something being wrong in the post request, maybe the upload service API is not accepting the base64 format, maybe the API key is not authorized. Please read their API docs carefully and do as it says & also console log the error code you are receiving.
After all, try something like this with Axios.
const image2base64 = require('image-to-base64');
image2base64("path/to/file.jpg") // you can also to use url
.then(
(response) => {
console.log(response); //cGF0aC90by9maWxlLmpwZw==
axios.post('http://example.com/in.php', base64, {
headers: {
"Content-Type": "multipart/form-data"
},
}).then((response) => {
console.log(response)
}).catch(function (error) {
console.log("Error in uploading.");
});
},
}
)
.catch(
(error) => {
console.log(error); //Exepection error....
}
)

node.js server and AWS asynchronous call issue

I have a simple node Express app that has a service that makesa call to a node server. The node server makes a call to an AWS web service. The AWS simply lists any S3 buckets it's found and is an asynchronous call. The problem is I don't seem to be able to get the server code to "wait" for the AWS call to return with the JSON data and the function returns undefined.
I've read many, many articles on the web about this including promises, wait-for's etc. but I think I'm not understanding the way these work fully!
This is my first exposer to node and I would be grateful if somebody could point me in the right direction?
Here's some snippets of my code...apologies if it's a bit rough but I've chopped and changed things many times over!
Node Express;
var Httpreq = new XMLHttpRequest(); // a new request
Httpreq.open("GET","http://localhost:3000/listbuckets",false);
Httpreq.send(null);
console.log(Httpreq.responseText);
return Httpreq.responseText;
Node Server
app.get('/listbuckets', function (req, res) {
var bucketData = MyFunction(res,req);
console.log("bucketData: " + bucketData);
});
function MyFunction(res, req) {
var mydata;
var params = {};
res.send('Here are some more buckets!');
var request = s3.listBuckets();
// register a callback event handler
request.on('success', function(response) {
// log the successful data response
console.log(response.data);
mydata = response.data;
});
// send the request
request.
on('success', function(response) {
console.log("Success!");
}).
on('error', function(response) {
console.log("Error!");
}).
on('complete', function() {
console.log("Always!");
}).
send();
return mydata;
}
Use the latest Fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make HTTP calls. It has built-in support with Promise.
fetch('http://localhost:3000/listbuckets').then(response => {
// do something with the response here
}).catch(error => {
// Error :(
})
I eventually got this working with;
const request = require('request');
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
parseString(body, function (err, result) {
console.log(JSON.stringify(result));
});
// from within the callback, write data to response, essentially returning it.
res.send(body);
}
else {
// console.log(JSON.stringify(response));
}
})

How do I send multiple images to tumblr via their API with Node?

Tumblr's documentation says that you can send an array or "(URL-encoded binary contents)" in order to post a photo message.
What does "URL-encoded binary contents" actually mean and how do I accomplish this with Node?
I have this function that I've been using to get files from a URL:
function getImage (url) {
return new RSVP.Promise((resolve, reject) => {
Request.get({
url: url,
encoding: null,
}, (err, response, body) => {
if (!err && response && response.statusCode == 200 && body) {
const buff = Buffer.from(body);
return resolve(buff.toString());
// I've tried all kinds of stuff here:
// return resolve(buff.toString('hex')); //nope
// return resolve(buff.toString('binary')); //nope
// return resolve(buff.toString('base64')); //nope
// return resolve(encodeURIComponent(buff.toString('hex')); //nope
// etc.
}
});
});
};
I then use the result of that function to populate the data parameter of the POST request. I am able to use my POST function to send regular text posts, and image posts if I specify the source (url) of the image rather than the data itself. So I don't think it's an OAuth problem.
The error message I get is:
{
'meta': {
'status': 400,
'msg': 'Bad Request',
},
'response': { 'errors': ['Nice image, but we don\'t support that format. Try resaving it as a gif, jpg, or png.'] },
};
I am sending it JPEGs and GIFs, just not in the way they want it. How do I go from the result of a GET to whatever it is that tumblr wants?

AZURE Mobile Service forwarding POST request in insert script of table

I'm trying to use Azure Mobile Service to process / handle GET and POST requests on an empty data table. (really just using the mobile service as a pass through)
As part of this I'm trying to forward the request to another url and receive the response back and return it via mobile service. I've figured out the GET part shown below but I'm having trouble the POST part.
GET Part:(Which works)
function read(query, user, request)
{
var p = request.parameters;
var httpRequest = require('request');
var url = 'http://someURL/'+ p.ssoid;
httpRequest.get(url, function(err, response, body)
{
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,JSON.parse(body) );
}
});
}
Post Code:(Does not work)
function insert(item, user, request)
{
var p = request.parameters;
require('request').post({
uri:'http://someURL/',
headers:{'content-type': 'application/json'},
body:p.body
},function(err,res,body){
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,"Success");
}
});
}
I know the POST requires a body with the post information, but how to I get it to pass forward?
On an insert, the body of the request will be stored in the item argument (assuming you're passing a JSON object). So your function would look something like this:
function insert(item, user, request)
{
var p = request.parameters;
require('request').post({
uri : 'http://someURL/',
headers : {'Content-Type': 'application/json'},
body : item
}, function(err, res, body){
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,"Success");
}
});
}
On a related note, if you're using the mobile service as a simple pass-through, you can also consider using a custom API instead of a table, where you can also apply your logic without having any (empty) table behind it.
function insert(item, user, request)
{
var p = request.parameters;
require('request').post({
uri : 'http://someURL/',
headers : {'Content-Type': 'application/json'},
body : JSON.stringify(item)
}, function(err, res, body){
if (err)
{
request.respond(500, "INTERNAL SERVER ERROR");
}
else
{
request.respond(200,"Success");
}
});
}

Resources