← back to Goodquestion Ai
scripts/tweet-image.cjs
59 lines
/**
* Post a tweet with an image as @agentabrams
* Usage: node tweet-image.cjs "Tweet text" /path/to/image.png
*/
require('dotenv').config({ path: require('path').join(__dirname, '..', '.env') });
const { TwitterApi } = require('twitter-api-v2');
const fs = require('fs');
const path = require('path');
const client = new TwitterApi({
appKey: process.env.TWITTER_API_KEY,
appSecret: process.env.TWITTER_API_SECRET,
accessToken: process.env.TWITTER_ACCESS_TOKEN,
accessSecret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});
async function tweetWithImage() {
const text = process.argv[2];
const imagePath = process.argv[3];
if (!text || !imagePath) {
console.error('Usage: node tweet-image.cjs "Tweet text" /path/to/image.png');
process.exit(1);
}
if (!fs.existsSync(imagePath)) {
console.error(`Image not found: ${imagePath}`);
process.exit(1);
}
const stats = fs.statSync(imagePath);
console.log(`Image: ${imagePath} (${(stats.size / 1024).toFixed(0)} KB)`);
console.log(`Text: ${text} (${text.length}/280 chars)\n`);
try {
// Upload media via v1 API
console.log('Uploading image...');
const mediaId = await client.v1.uploadMedia(imagePath, { mimeType: 'image/png' });
console.log(`Media uploaded: ${mediaId}`);
// Post tweet with media via v2 API
console.log('Posting tweet...');
const result = await client.v2.tweet({
text: text,
media: { media_ids: [mediaId] },
});
console.log('Tweet posted!');
console.log(`ID: ${result.data.id}`);
console.log(`URL: https://x.com/agentabrams/status/${result.data.id}`);
} catch (err) {
console.error('Failed:', err.message);
if (err.data) console.error(JSON.stringify(err.data, null, 2));
process.exit(1);
}
}
tweetWithImage();