Save json object as a text file - javascript

I am using an API for a Twitch.tv streaming bot called DeepBot.
Here is the link to it on github https://github.com/DeepBot-API/client-websocket
My goal is to create a text document listing all the information pulled from the bot using the command api|get_users|. The bot's response is always a json object. How can I take the json object from the bot and save it as a text file?
Edit: My code
var WebSocket = require('ws');
var ws = new WebSocket('ws://Ip and Port/');
ws.on('open', function () {
console.log('sending API registration');
ws.send('api|register|SECRET');
});
ws.on('close', function close() {
console.log('disconnected');
});
ws.on('message', function (message) {
console.log('Received: ' + message);
});
ws.on('open', function () {
ws.send('api|get_users|');
});

Well that depends on how your setup is? You posted this under javascript. So I guess you are either:
using a browser, to make the websocket connection, in with case there is no direct way to save a file on the client. But in HTML5 you can store key,value pairs with local storage.
using node js (server side javascript) in witch case the code is as below:
some other setup, that I can't guess. in witch case you might tell a little more about it?
In browser with HTML5 capabilities:
// where msg is an object returned from the API
localStorage.setItem('Some key', JSON.stringify(msg));
In Node JS
var fs = require("fs"); // Has to be installed first with “npm install fs”
// where msg is an object returned from the API
fs.writeFile("some-file.json", JSON.stringify(msg), function (err) {
if (err) throw err;
});
Edit: OK, Thanks for clearing it up.
I believe Blag's solution is the way to go.
Good luck with your project!

If it's for a client side JS save :
Create a file in memory for user to download, not through server
and
Convert JS object to JSON string
Is what you need. ( I don't test it, but it'll look like this : )
var j = {"name":"binchen"};
var s = JSON.stringify(j);
window.location = 'data:text/plain;charset=utf-8,'+encodeURIComponent(s);

Related

NodeJs Microsoft Azure Storage SDK Download File to Stream

I just started working with the Microsoft Azure Storage SDK for NodeJS (https://github.com/Azure/azure-storage-node) and already successfully uploaded my first pdf files to the cloud storage.
However, now I started looking at the documentation, in order to download my files as a node_buffer (so I dont have to use fs.createWriteStream), however the documentation is not giving any examples of how this works. The only thing they are writing is "There are also several ways to download files. For example, getFileToStream downloads the file to a stream:", but then they only show one example, which is using the fs.createWriteStream, which I dont want to use.
I was also not able to find anything on Google that really helped me, so I was wondering if anybody has experience with doing this and could share a code sample with me?
The getFileToStream function need a writable stream as param. If you want all the data wrote to a Buffer instead of a file, you just need to create a custom writable stream.
const { Writable } = require('stream');
let bufferArray = [];
const myWriteStream = new Writable({
write(chunk, encoding, callback) {
bufferArray.push(...chunk)
callback();
}
});
myWriteStream.on('finish', function () {
// all the data is stored inside this dataBuffer
let dataBuffer = Buffer.from(bufferArray);
})
then pass myWriteStream to getFileToStream function
fileService.getFileToStream('taskshare', 'taskdirectory', 'taskfile', myWriteStream, function(error, result, response) {
if (!error) {
// file retrieved
}
});

Node-Red Send Binary

I was just introduced to Node-Red after asking around for some suggestions on an IoT setup. I have a piece of javascript code that is sending data to a web socket. The code that it is sending is in a HEX format and is sent to the web socket.
I am trying to replicate this using node-red and I am having some trouble figuring out which node to use for sending the data.
Vanilla Javascript:
function connectToSocket() {
// Try to connect to the socket
try {
// Create our socket connection
connection = new WebSocket('ws://' + gatewayIP + ':8000');
connection.binaryType = "arraybuffer";
// Failed to create the socket connection
} catch (e) {
// Log error message
logMessage('Failed to connect to socket');
return;
}
}
connection.send('\x02\x00\x01\x04\x26\x2D');
I have tried sending this as a string and json object as msg.payload but it is not triggering the device as I expect it to such as when I run the normal JS function in a browser.
What would be an appropriate format to send this hex string in?
What you want to send is a buffer and the inject node can't generate a buffer at this point. The easiest way to do this will be to insert a function node between the inject and the WebSocket Out node.
The function node should contain something like:
msg.payload = Buffer.from("\x02\x00\x01\x04\x26\x2D");
return msg;
This will swap the payload for a buffer with the right values.
EDIT:
For NodeJS 0.10.x you should use something like as Buffer.from() was introduced in NodeJS 4.x:
msg.payload = new Buffer("\x02\x00\x01\x04\x26\x2D");
return msg;

Capture webpage with node.js and save as image or base64

I have app on Heroku and I want to capture webpage and save as image or base64. Problem is: I have node.js script in that app and I want to use phantomjs, but phantom is not compatible with node.
So, I need to capture webpage and save output (image or base64 string) to variable so my primary (node) app can use that values.
I tried this but I can't figure how to use that: https://www.npmjs.com/package/phantom
This is what I have so far: (source)
app.get('/capture', function(request, response) {
var phantom = require('phantom');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open('https://stackoverflow.com/').then(function(status) {
console.log(status);
page.property('content').then(function(content) {
var base64 = page.renderBase64('PNG');
console.log(base64);
page.close();
ph.exit();
});
});
});
});
});
What I need on my heroku server (beside already installed node), what I need to install in node.js, how to use all that?
Thanks.
So: send request to capture page -> make image -> pass output to JS variable

Getting variables From a config file to the browser

I have a rather complex setup which requires the web browser local storage has the computer's name populated in order for the application to work properly. In order to do this I read from a configuration file:
kiosk-name: Mort
I read the config file when I start my node.js web server:
var filesys = require('fs');
var os = require('os');
filesys.readFile(project_path + '/kiosk.cfg', 'utf8', function(err, data) {
var kioskname;
if (err) {
//console.log(err);
kioskname = os.hostname();
} else {
var configArray = data.split(':');
if('' != configArray[1]) {
kioskname = configArray[1];
} else {
kioskname = os.hostname();
}
}
});
All of this works as designed, using the computer's os.hostname() as a default when the config file is not populated.
The client side features a base page (index.html) which loads a default page (default.html) into an iframe. Based on a websocket messaging system the default page gets replaced by another page from a remote IP. In an older version of the system (prior to implementing a config file) we were able to set the local storage element with the following code:
var win = document.getElementsByTagName('iframe')[0].contentWindow;
win.postMessage(JSON.stringify({key: 'kiosk-name', data: kioskName}), "*");
We identify the iframe when the websocket message is received and then send a post message containing a JSON string to set the local storage element. In this case kioskName is a variable containing a hard-coded value.
The Problem
Now that we wish to read values from a config file we need a way to pass kioskname out to the client-side JavaScript so we can set the local storage element in the iframe.
I attempted putting the file reading function in an export wrapper:
(function(exports){
// file reading code here
return kioskname;
})(typeof exports === 'undefined' ? this['kioskname']={} : exports);
I got an error:
Uncaught ReferenceError: require is not defined
Placing a static value in the export function (with out the require's allows the export function to work properly, but doesn't allow me to read the config file which requires both the os and fs modules.
How do I get the value returned from the config file to a place where I can use it on the client-side to set a local storage element?
This is a creative solution which may not be suitable for every case as it involves utilizing a websocket between the Node.js web server and the client.
Websocket setup to send to client (assumes webserver at 'node_server':
var io = require('socket.io').listen(node_server); // 'attaches' socket.io to this web server
io.sockets.on('connection', function (socket) {
socket.emit('message', 'socket.io connected'); // output a connection message
// receive JSON message and send to the websocket
socket.on('message', function (data) {
var address = node_server.address();
var client = dgram.createSocket("udp4");
var message = new Buffer(data);
// out of the airlock!
client.send(message, 0, message.length, address.port, address.address, function(err, bytes) {
client.close();
});
});
});
Read the config file, then parse and send a message to the socket (done on the server-side):
filesys.readFile(project_path + '/kiosk.cfg', 'utf8', function(err, data) {
var kioskname;
if (err) {
//console.log(err);
kioskname = os.hostname();
} else {
var configArray = data.split(':');
if('' != configArray[1]) {
kioskname = configArray[1];
} else {
kioskname = os.hostname();
}
}
// create JSON string for transmission
KioskName = JSON.stringify({'config':{'kiosk-name': kioskname}});
var send_KioskName = setInterval(function(){ // could be a setTimeout for a one time send
io.sockets.emit('message', KioskName.toString()); // send config file data to browser via socket
}, 30000);
});
NOTE this can be expanded to send multiple pieces of data via JSON to the client should the need arise. A couple of small edits are all that is needed to setup a more detailed JSON object.
Receive the socket message on the client side (this code is loaded by the client), then parse. The resulting object is added to the namespace for this application, making the object available to multiple scripts when required.
CAUTION: You should only use this methodology for objects which do not interfere with objects you may create or destroy in your scripts along the way.
// make sure a string is JSON before using
function isJSON(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
// set up object 'array's
var kioskname = {};
// connect a socket to listen for incoming messages from the Big Giant Head
var socket = io();
socket.on('message', function (data) {
if(isJSON(data)) {
// parse the json
var json = $.parseJSON(data);
// determine how to use this JSON object, multiple objects may be sent
if('config' == Object.keys(json)[0]) {
/*
* send config data where needed - future proofed, just add cases
* and namespaced objects where required
*/
kioskname['name'] = json.config['kiosk-name'];
}
}
});
// attach objects to namespace
window.KIOSK.kioskname = kioskname;
Now we can use the object to set local storage. In our case we post a message to the app's server and it responds with localStorage.setItem():
Post the message:
var currentFrame = document.getElementsByTagName('iframe')[0].contentWindow;
currentFrame.postMessage(JSON.stringify({key: 'user-name', data: KIOSK.kioskname.name}), "*");
By opening a socket and using the JSON string passed through the socket to populate a namespaced object we are able to use server-side information from a configuration file in our application's client.

Write a variable into a buffer

I am very new to node.js and I think I understand the basics of how it functions but I feel like I am not seeing something that is vital to how fs.write and buffers function.
I am trying to send a user defined variable over socket.io and write it into an html file. I have a main site that has the button, when clicked it sends the information to the socket in a variable.
The thing I can't figure out is how to insert the variable into the html file.
I can save strings that I type, into a file:
(e.g.) var writeBuffer = new Buffer ('13');
But not variables that I put in:
(e.g.) var writeBuffer = new Buffer ($(newval));
I even tried different encoding methods, I think I am missing something.
Server.js
var newval = "User String";
var fd = fsC.open(fileName, 'rs+', function (error, fd) {
if (error) { throw error }
var writeBuffer = new Buffer($(newval));
var bufferLength = writeBuffer.length;
fsC.write( fd, writeBuffer, 0, bufferLength, 937,
function (error, written) {
if (error) { throw error }
fsC.close(fd, function() {
console.log('File Closed');
});
}
);
});
If you are using a version of jsdom 4.0.0 or later, it will not work with Node.js. As per the jsdom github readme:
Note that as of our 4.0.0 release, jsdom no longer works with
Node.js™, and instead requires io.js. You are still welcome to install
a release in the 3.x series if you use Node.js™.

Categories