Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@stefanbohacek
Last active December 3, 2023 12:57
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save stefanbohacek/b307d5d94d6f38efbf0a1be8e2ebd19b to your computer and use it in GitHub Desktop.
Save stefanbohacek/b307d5d94d6f38efbf0a1be8e2ebd19b to your computer and use it in GitHub Desktop.
/*
A simple Twitter bot that posts random images.
Tutorial: https://botwiki.org/resource/tutorial/random-image-tweet/
*/
const fs = require('fs'),
path = require('path'),
Twit = require('twit'),
config = require(path.join(__dirname, 'config.js'));
/*
Your config.js file should have the following format:
const config = {
consumer_key: 'XXXXX',
consumer_secret: 'XXXXX',
access_token: 'XXXXX',
access_token_secret: 'XXXXX'
}
module.exports = config;
Here's a tutorial on how to get the API keys: https://botwiki.org/resource/tutorial/how-to-create-a-twitter-app/
*/
const T = new Twit(config);
const randomFromArray = (arr) => {
/* Helper function for picking a random item from an array. */
return arr[Math.floor(Math.random() * arr.length)];
}
const tweetRandomImage = () => {
/* First, read the content of the images folder. */
fs.readdir(__dirname + '/images', (err, files) => {
if (err){
console.log('error:', err);
return;
} else {
let images = [];
files.forEach((f) => {
images.push(f);
});
/* Then pick a random image. */
console.log('opening an image...');
const imagePath = path.join(__dirname, '/images/' + randomFromArray(images)),
imageData = fs.readFileSync(imagePath, { encoding: 'base64' });
/* Upload the image to Twitter. */
console.log('uploading an image...', imagePath);
T.post('media/upload', { media_data: imageData }, (err, data, response) => {
if (err){
console.log('error:', err);
} else {
/* Add image description. */
const image = data;
console.log('image uploaded, adding description...');
T.post('media/metadata/create', {
media_id: image.media_id_string,
alt_text: {
text: 'Describe the image'
}
}, (err, data, response) => {
/* And finally, post a tweet with the image. */
T.post('statuses/update', {
// status: 'Optional tweet text.',
media_ids: [image.media_id_string]
},
(err, data, response) => {
if (err){
console.log('error:', err);
} else {
console.log('posted an image!');
/*
After successfully tweeting, we can delete the image.
Keep this part commented out if you want to keep the image and reuse it later.
*/
// fs.unlink(imagePath, (err) => {
// if (err){
// console.log('error: unable to delete image ' + imagePath);
// } else {
// console.log('image ' + imagePath + ' was deleted');
// }
// });
}
});
});
}
});
}
});
}
setInterval(() => {
tweetRandomImage();
}, 10000);
@LuxStatera
Copy link

@fourtonfish thank you!

@stefanbohacek
Copy link
Author

No problem!

@LuxStatera
Copy link

i am also very interested in the code to tweet pictures in order and delete them after they have been tweeted. i feel like this will solve my problem of too many duplicates and also after a few days of posting it will stop and i get an error saying JS stacktrace FATAL ERROR: Ineffective mark-compacts near heap limit allocation failed - javascript heap of of memory. i tried to give it more space with the command export NODE_OPTIONS=--max-old-space-size=14000 but it still gives me that fatal error after a few days. is there a way to allow it to run nonstop?

@stefanbohacek
Copy link
Author

As for the memory issue, hard to tell without seeing the full code, but if your bot only runs on a schedule, would it be an option for you to use cron?

To delete an image after it's tweeted see the fs.unlink section that's commented out above. You could name your files alphabetically (image-001.png, image-002.png, etc) to ensure the correct order.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment