使用 node.js 编写 Twitter 机器人 - 我做错了什么?

Writing a twitter bot with node.js - what am I doing wrong?

我使用 twit 和 twitter 库的不同教程编写了这个 twitterbot。我希望它在不同的时间间隔执行不同的功能(还没有写这部分)。当我注释掉其余部分时,不同的功能会起作用,但是如果我尝试 运行 将所有内容放在一起,则会出现不同的错误。此外,使用 Rest-API 的函数(replyToTweets,第 106 行)根本不执行任何操作。希望有人能帮忙。谢谢!

var fs = require('fs'),
    path = require('path'),
    Twit = require('twit'),
    config = require(path.join(__dirname, 'config.js')),
    TwitterPackage = require('twitter');

var T = new Twit(config);
var Twitter = new TwitterPackage(config);


// A - For posting a Tweet.
function postTweet() {
    console.log('A beginnt...')
        T.post('statuses/update', {status: 'Bleh..' }, function(err, data, response) {
            console.log(data)
});
};


// B - For posting images
//pick random image from the array
function postRandomImage() {
    console.log('B beginnt...')
    function pick_random_image() {
        var images = [
        'wurst.jpg',
        'wurst.jpg'
    ];
        return images[Math.floor(Math.random() * images.length) ];
    }

    //upload image:
    function upload_random_image() {
        console.log('Bild oeffnen...');
        var image_path = path.join(__dirname, '/bilder/' + pick_random_image()),
            b64content = fs.readFileSync(image_path, { encoding: 'base64' });

        console.log('Bild hochladen...');

        T.post('media/upload', { media_data: b64content }, function (err, data, response) {
            if(err) {
                console.log('ERROR');
                console.log(err);
            }
            else {
                console.log('Bild erfolgreich hochgeladen');

                T.post('statuses/update', {
                    media_ids: new Array(data.media_id_string)
                },
                       function(err, data, response) {
                            if (err) {
                                console.log('ERROR');
                                console.log(err);
                            }
                            else{
                                console.log('Bild gepostet');
                            }
                        }
                );
            }
        });
    }
}


// C - reply to mentions/replies
function replyToMentions(){
    var stream = T.stream('user');

    stream.on('tweet', tweetEvent);

    function tweetEvent(eventMsg) {

        console.log('C beginnt...');

        var replyto = eventMsg.in_reply_to_screen_name;
        var text = eventMsg.text;
        var from = eventMsg.user.screen_name;

        console.log(replyto + ' ' + from);

        if (replyto === 'xxxx') {
            var newtweet = '.@' + from + ' http://gph.is/1l7SWLL?tc=1';
            tweetIt(newtweet);
        }
    }

    function tweetIt(txt) {
        var tweet = { status: txt }

        T.post('statuses/update', tweet, tweeted);

        function tweeted(err, data, response) {
            if (err) {
                console.log('ERROR');
                console.log(err);
            } else {
                console.log('It worked.');
            }
        }
    }
};


//D - use Rest-API to react to tweets that use certain keywords
function replyToTweets() {
    console.log('D beginnt ...');
    Twitter.stream('statuses/filter', {track: 'Wawawawa'}, function(stream) {
        stream.on('data', function(tweet) {
            console.log(tweet.text);

            var statusObj = { status: ".@" + tweet.user.screen_name + "http://gph.is/2mKyBTs?tc=1" }

            Twitter.post('statuses/update', statusObj, function(error, tweetReply, response) {
                if(error){
                    console.log(error);
                }

                console.log(tweetReply.text);
            })
        });

        stream.on('error', function(error) {
            console.log(error);
        });
    });
};


//E - answer a specific question with a specific answer
function replyToQuestion(){
    console.log('E beginnt...');
    var stream = T.stream('user');

    stream.on('tweet', tweetEvent);

    function tweetEvent(eventMsg) {

        console.log('E beginnt...');

        var replyto = eventMsg.in_reply_to_screen_name;
        var text = eventMsg.text;
        var from = eventMsg.user.screen_name;

        console.log(replyto + ' ' + from);

        if (text === '@xxxx Ist Donald Trump noch im Amt?') {
            var newtweet = '@' + from + ' leider ja.';
            tweetIt(newtweet);
        }
    }

    function tweetIt(txt) {
        var tweet = { status: txt }

        T.post('statuses/update', tweet, tweeted);

        function tweeted(err, data, response) {
            if (err) {
                console.log('ERROR');
                console.log(err);
            } else {
                console.log('It worked.');
            }
        }
    }
};




function begin() {
    replyToMentions();
    replyToTweets();
    postTweet();
    postRandomImage();
    replyToQuestion();
};

/*setInterval(
    begin(),
    60000
)
*/

我认为 98% 的人都是异步问题。您可以使用承诺并等待它们在下一个功能之前解决。如果最后一个承诺有错误,您也可以停止下一个功能。 **等待一个函数完成,然后继续下一个函数**。这就是您的函数单独工作而不是串行工作的原因。

这是一个肮脏的代码,但有效,我把它放在这里是为了让您更容易理解使用回调和承诺,这两种方法可以解决您的问题。

没有承诺的更新

让我们假设这个函数:

function A(done){
    console.log('hello from A');
    done();
}

function B(done){
    console.log('hello from B');
    done();
}

function begin(){
    A(function(){
        console.log('A is finished, im going to call B');
        B(function(){
            console.log('B is finished');
        });
    });
}

承诺更新

function A(done){
    console.log('hello from A');
    done();
}

function B(done){
    console.log('hello from B');
    done();
}

function begin(){
    var promises = [];
    promises.push(A);
    Promise.all(promises).then(function(){
        console.log('A is finished, im going to call B');
        promises = [];
        promises.push(B);
        Promise.all(promises).then(function(){
            console.log('B is finished');   
        });
    })
}