Javascript - 将图像发布到 Twitter,不重复

标签 javascript node.js npm twitter bots

我正在使用一个名为 Twit 的 NPM 包制作一个 Twitter 机器人,我想知道如何将图像发布到 Twitter 而不会发布重复的图像。

当前是 image_path 变量

var image_path = path.join(__dirname, '/images/' + random_from_array(images))

正在查看我的图片目录,但我不希望它上传重复的图片。我尝试了很多东西,但被卡住了。任何建议,我很难过。

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

var T = new Twit(config);

function random_from_array(images){
  return images[Math.floor(Math.random() * images.length)];
} 

function upload_random_image(images){
  console.log('Opening an image...');
  var image_path = path.join(__dirname, '/images/' + random_from_array(images)),
      b64content = fs.readFileSync(image_path, { encoding: 'base64' });

  console.log('Uploading an image...');

  T.post('media/upload', { media_data: b64content }, function (err, data, response) {
    if (err){
      console.log('ERROR:');
      console.log(err);
    }
    else{
      console.log('Image uploaded!');
      console.log('Now tweeting it...');

      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('Posted an image!');
          }
        }
      );
    }
  });
}

fs.readdir(__dirname + '/images', function(err, files) {
  if (err){
    console.log(err);
  }
  else{
    var images = [];
    files.forEach(function(f) {
      images.push(f);
    });

    setInterval(function(){
      upload_random_image(images);
    }, 10000);
  }
});

我正在学习本教程

https://botwiki.org/resource/tutorial/random-image-tweet/#posting-images

最佳答案

您可以保留所有已上传图像的列表。有几种方法可以做到这一点:

最简单的解决方案

将上传图片列表保存为全局变量。在上传新图像之前,请检查该图像是否在列表中。如果是,早点回来。如果不是,则将图像放入列表并继续。

const uploadedImages = []
function upload_random_image(images){
  console.log('Opening an image...');
  const image = random_from_array(images)
  // check if image is in the list
  if (uploadedImages.includes(image) {
     return;
  }
  // image is not in the list - insert into the list and continue
  uploadedImages.push(image);
  const image_path = path.join(__dirname, '/images/', image)
  // ...

这种方法的一个缺点是您最终会在上传图像的时间上出现“间隙”——如果图像已经上传,您的程序将不得不等到下一个时间间隔过去后再重试。此外,我们无法知道何时上传了文件夹中的所有图像。

更优化的方法

更好的方法(在我看来)是先随机化图像,然后一次将它们传递给 upload_random_image 函数,它现在将变成一个 upload_image功能。为此,我们需要一个 shuffle 函数 - 有很多在线创建一个的解决方案,或者您可以使用像 lodash 这样的实用程序库。 .假设存在一个 shuffle 函数:

    // ...
    var images = [];
    files.forEach(function(f) {
      images.push(f);
    });
    const shuffled = shuffle(images)
    let index = 0;
    setInterval(function(){
      const image = shuffled[index]
      upload_image(image);
      index += 1; 
    }, 10000);
  }
});

function upload_image(image){
  console.log('Opening an image...');
  var image_path = path.join(__dirname, '/images/' + image)
  // ...
}

现在剩下的问题是我们将在某个时候到达shuffled 数组的末尾。这确实表明我们已经上传了该文件夹中的所有图像并且我们的工作已经完成。为了能够停止,我们需要使用 setInterval 的返回值,即 intervalID。我们将setInterval的返回值保存到一个变量中,并调用clearInterval一旦我们想停止:

    const shuffled = shuffle(images)
    let index = 0;
    const intervalId = setInterval(function(){
      const image = shuffled[index]
      upload_image(image);
      index += 1; 
      if (index === shuffled.length) {
        clearInterval(intervalId)
      }
    }, 10000);

我已将使用 shuffleclearInterval 的示例发布到此 repl .

关于Javascript - 将图像发布到 Twitter,不重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58925753/

相关文章:

node.js - 如何限制使用 puppeteer 渲染的资源

node.js - 将对象作为参数发送到 fork 的 nodejs 进程

javascript - 在模块内部实例化类时超出最大调用堆栈

javascript - 如何从语言环境获取日期格式

javascript - Firebase 数据未在网络中显示

javascript - 如何在旧版 IE 中使用 String.split 捕获组?

javascript - Controller 未使用 Angular $http 服务记录来自 Nodejs 的响应

node.js - 无法通过 npm 自动安装类名包(在 package.json 中定义)

node.js - 是否可以在Azure中运行npx工具来执行包

javascript - Angular-Cli 的子资源完整性