Facebook-chat-api: Doesn't work without terminal console

Created on 16 Nov 2015  路  8Comments  路  Source: Schmavery/facebook-chat-api

facebook-chat-api does seem to have hard dependency on terminal console. I'm trying to build electron app, and it works fine if I launch using command console but gives warning with following is the snapshot of stacktrace, if I execute it dirrectly:

Unhandled rejection Error: EPERM: operation not permitted, write
at Error (native)
at Object.fs.writeSync (fs.js:663:20)
at SyncWriteStream.write (fs.js:1981:6)
at SyncWriteStream.stream.write (D:\Projects\Node\fb-messenger\electron\build\v0.34.3\win32-ia32\resources\app\node_modules\facebook-chat-api\node_modules\npmlog\node_modules\ansi\lib\newlines.js:36:21)
at Cursor.write (D:\Projects\Node\fb-messenger\electron\build\v0.34.3\win32-ia32\resources\app\node_modules\facebook-chat-api\node_modules\npmlog\node_modules\ansi\lib\ansi.js:157:23)
at EventEmitter.log.write (D:\Projects\Node\fb-messenger\electron\build\v0.34.3\win32-ia32\resources\app\node_modules\facebook-chat-api\node_modules\npmlog\log.js:217:15)
at EventEmitter. (D:\Projects\Node\fb-messenger\electron\build\v0.34.3\win32-ia32\resources\app\node_modules\facebook-chat-api\node_modules\npmlog\log.js:191:10)

Is there a way to avoid dependency on npmlog? May be make logger injectible? Or may be just continue without logging in case it is not able to log?

Most helpful comment

@KeNt178

I just created a file stdio-rediret.ts with following content:

var streamWrite = function(chunk: any, encoding: any, callback: Function){
     if(Buffer.isBuffer(chunk)){
        chunk = chunk.toString(encoding);
     }
    console.log(chunk)
    if(callback)callback()
    return true;
};

process.stdout.write = streamWrite;   
process.stderr.write = streamWrite;

And required it at top of my code. In my case it was electron project, so I did it at index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <link href="./styles/main.css" rel="stylesheet">
    <script type="text/javascript">
            require('./stdio-redirect') 
    </script>
    <script src="./program.js" type="text/javascript"></script>
</head>

<body>
    <div id="fb-messenger"></div>
</body>

</html>

Hope this makes sense.

Note that is was typescript project so there's a compilation step involved.

All 8 comments

We intentionally went with npmlog because it's a relatively mature framework that should be able to handle situations like this. Checking their docs, it looks like you should be able to change log.streamto whatever you want to. Let us know if that works for you.

@Schmavery

I have found a work around, replacing write method of stderr/stdout works fine.

var streamWrite = function(chunk: any, encoding: any, callback: Function){
     if(Buffer.isBuffer(chunk)){
        chunk = chunk.toString(encoding);
     }
    console.log(chunk)
    if(callback)callback()
    return true;
};

process.stdout.write = streamWrite;   
process.stderr.write = streamWrite;

Hi @nripendra, could you please detail which file & lines you modified exactly. Thanks

@KeNt178

I just created a file stdio-rediret.ts with following content:

var streamWrite = function(chunk: any, encoding: any, callback: Function){
     if(Buffer.isBuffer(chunk)){
        chunk = chunk.toString(encoding);
     }
    console.log(chunk)
    if(callback)callback()
    return true;
};

process.stdout.write = streamWrite;   
process.stderr.write = streamWrite;

And required it at top of my code. In my case it was electron project, so I did it at index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <link href="./styles/main.css" rel="stylesheet">
    <script type="text/javascript">
            require('./stdio-redirect') 
    </script>
    <script src="./program.js" type="text/javascript"></script>
</head>

<body>
    <div id="fb-messenger"></div>
</body>

</html>

Hope this makes sense.

Note that is was typescript project so there's a compilation step involved.

@nripendra
I've tried to use your technique. I've got the error that the process variable is not defined :( How can you modify the stream method if the process doesn't exist (yet?) ? The process variable is in npmlog module but I don't have access to it.
In your example, you directly require stdio-redirect before anything else. How could the process variable be defined ?
In the case of my chrome extension, I "require" stdio-redirect.js in the background scripts of my manifest.json file.

Thanks for your help

@KeNt178
In my case it is node js app, so process variable is globally available. Not sure how it works for a chrome extension. May be you could use browserify, which adds process object shim. Or use modules like https://www.npmjs.com/package/process

If I keep the node server which runs facebook-chat-api distinct from the chrome extension, the chrome extension can easily connect to it... This error actually happens when I've browserified my app.

I have found a workaround by creating process.stdout & process.stderr as new streams

_log.js_ in npmlog module

'use strict'
var Progress = require('are-we-there-yet')
var Gauge = require('gauge')
var EE = require('events').EventEmitter
var log = exports = module.exports = new EE
var util = require('util')

var ansi = require('ansi')

// workaround
var Stream = require('stream');
var streamWrite = function (chunk, encoding, callback) {
    if (Buffer.isBuffer(chunk)) {
        chunk = chunk.toString(encoding);
    }
    console.log(chunk);
    if (callback)
        callback();
    return true;
};
process.stdout = new Stream();
process.stderr = new Stream();
process.stdout.write = streamWrite;
process.stderr.write = streamWrite;
log.cursor = ansi(process.stderr)
log.stream = process.stderr
...

Now I can use facebook-chat-api but it always returns the "Wrong username/password." error :(

New issue incoming

Was this page helpful?
0 / 5 - 0 ratings