试图让 Twitter 机器人同时发布两张图片

Posted

技术标签:

【中文标题】试图让 Twitter 机器人同时发布两张图片【英文标题】:Trying to Get a Twitter Bot to Tweet Two Images at Once 【发布时间】:2020-09-16 12:29:53 【问题描述】:

我正在开发一个 twitter 机器人,它的目标是发布两张图片和一串文本。我正在使用 node.js(第一次,我应该添加)和the Twit package。

我遇到了各种各样的问题,其中很多可能只是因为我是新手,但我真的不知道如何正确输出该死的东西。我已经设法输出文本和单个图像,但我试图一次吐出两个图像。

主机器人块使用以下代码来构建和安排推文:

function mainPostBot() 
console.log("Now assembling a new tweet.");

var leftCard = getRandomNumber(1, 36);
    console.log("The left card is #" + leftCard + ", " + cardNames[leftCard] + ".");
    // Generates a random number for the left card.
var leftImagePath = path.join(__dirname, '/leftImage/' + imageArray[leftCard]);
    console.log("The left image's path is " + leftImagePath);
    // Gives the file path to access the correct image for the left.

var rightCard = getRandomNumber(1, 36);
    console.log("The right card is #" + rightCard + ", " + cardNames[rightCard] + ".");
    // Generates a random number for the right card.
while (leftCard == rightCard) 
    var rightCard = getRandomNumber(1, 36);
    console.log("Whoops! The right card is now #" + rightCard + ", " + cardNames[rightCard] + ".");
    // Generates a random number for the right card in the case of doubles.

var rightImagePath = path.join(__dirname, '/rightImage/' + imageArray[rightCard]);
    console.log("The right image's path is " + rightImagePath);
    // Gives the file path to access the correct image for the left.

console.log('Encoding the images...');
    var b64contentLeft = fs.readFileSync(leftImagePath,  encoding: 'base64' );
    var b64contentRight = fs.readFileSync(rightImagePath,  encoding: 'base64' );
    var bothImages = (b64contentLeft + "," + b64contentRight);
    // This encodes the images in base64, which twitter needs. I guess. I dunno, man.

var tweetText = (jsUcfirst(cardNames[leftCard]) + ' and ' + cardNames[rightCard] + '. (#' + leftCard + " " + cardCorrespond[leftCard] + "/#" + rightCard + " " + cardCorrespond[rightCard] + ")");
// This constructs the grammar of the tweet.
// jsUcfirst capitalizes the first letter of a string so it lets me cheat a sentence start.

var tweetTime = getRandomNumber(1000*60*60*4, 1000*60*60*24*3+1);
    // Generates an amount of time before the next tweet.

sendTweet(tweetText, bothImages, tweetTime);

setTimeout(mainPostBot, tweetTime);


mainPostBot();

cardNames、cardCorrespond 和 imageArray 只是程序顶部的大数组,它们分别列出了图像的名称、有关它们的一些信息以及它们的文件名:

var cardNames = new Array(
    "the Fool", //This one will never be called bc of the number generator and it's fun bc, y'know, Tarot
    "the Rider","the Clover","the Ship","the House","the Tree","the Clouds","the Snake","the Coffin","the Bouquet","the Scythe","the Whip", //"the Nae Nae",
    "the Birds","the Child","the Fox","the Bear","the Stars","the Stork","the Dog","the Tower","the Garden","the Mountain","the Cros-s-roads",
    "the Mice","the Heart","the Ring","the Book","the Letter","the Gentleman","the Lady","the Lily","the Sun","the Moon","the Key","the Fish",
    "the Anchor","the Cross"
    );

var cardCorrespond = new Array(
    " ","9♥","6♦","10♠","K♥","7♥","K♣","Q♣","9♦","Q♠","J♦","J♣","7♦","J♠","9♣","10♣","6♥","Q♥","10♥",
    "6♠","8♠","8♣","Q♦","7♣","J♥","A♣","10♦","7♠","A♥","A♠","K♠","A♦","8♥","8♦","K♦","9♠","6♣"
    );

var imageArray = new Array(
    " ","01.png","02.png","03.png","04.png","05.png","06.png","07.png","08.png","09.png","10.png","11.png","12.png","13.png",
    "14.png","15.png","16.png","17.png","18.png","19.png","20.png","21.png","22.png","23.png","24.png","25.png","26.png",
    "27.png","28.png","29.png","30.png","31.png","32.png","33.png","34.png","35.png","36.png"
    );

一旦 mainPostBot 完全构建了推文,它就会传送到 sendTweet:

function sendTweet(text, images, time)

    console.log('Uploading the images...');

    T.post('media/upload',  media_data: images , function (err, data, response)
        if (err)
            console.log("There's an issue uploading the images.");
            console.log(err);
         else 
            console.log('Images uploaded!');
            console.log("Now tweeting...")

            T.post('statuses/update', 
                status: text,
                media_ids: new Array(data.media_id_string)
            , function(err, data, response)
                if (err) 
                    console.log("An error has occurred during posting.");
                    console.log(err);
                 else 
                    console.log("Post successful!");
                    console.log("The tweet says:" + text);
                    console.log("The next tweet will send in " + msToTime(time) + "!");
                
            );
        
    );

有什么想法吗?当然,我愿意使用其他 npm 包,但我就是不明白为什么它不能按原样工作。感谢阅读,如果您需要任何其他代码,请告诉我。

编辑 1:我的室友也涉足这类事情,他为另一个包 node-twitter 找到了一个潜在的 useful link on github。在那个链接中,一张海报解释说图像应该作为字符串传递,用逗号分隔,所以我在 mainPostBot 和 sendTweet 中添加了一些编辑,主要是在 b64 图像数据的传递中。

编辑 2:这些编辑现在反映在上面的代码中,以及我对整个项目所做的一些其他修复。我到了事情再次顺利进行的地步(发现一个丢失的括号,我很讨厌这个编码的东西),并且有推文发布成功,但就像之前我没有通过第二张图片一样。早些时候帮助过的室友建议只为每种可能的卡片组合抽出静态单张图像,但必须有一个更优雅的解决方案。同样,任何想法都可以节省我一周的怪异卧室修补工作,我很感激任何对此的关注。

【问题讨论】:

【参考方案1】:

花了很多时间修修补补,但我想通了。每张图片都必须单独上传到 Twitter,所以在加载图片后,我将它的 data.media_id_string 保存到一个变量中,然后将这些值加载到数组中的 tweet 中。

我已从 mainPostBot 中删除了我组合 b64contentLeft 和 b64contentRight 的行,并使用返回的数据字符串将其添加到 sendTweet 代码中。现在,我调用 sendTweet() :

sendTweet(tweetText, b64contentLeft, b64contentRight, tweetTime);

sendTweet() 现在看起来像这样:

function sendTweet(text, leftimage, rightimage, time)

    console.log('Uploading the images...');

    T.post('media/upload',  media_data: leftimage , function (err, data, response)
        if (err)
            console.log("There's an issue uploading the left image.");
            console.log(err);
         else 
            console.log('Left image uploaded!');
            var leftID = data.media_id_string;

            T.post('media/upload',  media_data: rightimage , function (err, data, response)
                if (err)
                    console.log("There's an issue uploading the right image.");
                    console.log(err);
                 else 
                    console.log('Right image uploaded!');
                    var rightID = data.media_id_string;
                    var bothImages = ( leftID + "," + rightID );

                    console.log("Now tweeting...")

                    T.post('statuses/update', 
                        status: text,
                        media_ids: new Array(bothImages)
                    , function(err, data, response)
                        if (err) 
                            console.log("An error has occurred during posting.");
                            console.log(err);
                         else 
                            console.log("Post successful!");
                            console.log("The tweet says: " + text);
                            console.log("The next tweet will send in " + msToTime(time) + "!");
                        
                    );
                
            );
        
    );

本质上,如果左图正确上传,它会保存该 ID,然后尝试右图。如果成功,它也会保存该 ID,然后将两者组合成一个用逗号分隔的字符串,作为 bothImages 加载到 media_ids 数组中。

这是一场难以解决的噩梦,但我想确保它被记录在案,以防其他人在这里偶然发现相同的答案。

【讨论】:

以上是关于试图让 Twitter 机器人同时发布两张图片的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Rails 让我的 Twitter Bot 保持清醒?

试图让一个机器人与 Selenium Python 建立不和谐的连接

当有人试图踢高级管理员或他自己时,我怎样才能让机器人说些啥?

试图让我的 Discord 机器人响应“我不是婴儿潮一代 >:(”但它不会响应。我该如何修复代码?

试图让不和谐机器人对某个频道内的所有消息做出反应

为啥我的 Twitter 机器人没有发布它的“.update_status”?