← back to Dear Bubbe Nextjs
archived/social-posters/twitter-v2-poster.js
91 lines
const { TwitterApi } = require('twitter-api-v2');
const fs = require('fs').promises;
// You need to get these from https://developer.twitter.com
const config = {
appKey: 'YOUR_APP_KEY',
appSecret: 'YOUR_APP_SECRET',
accessToken: 'YOUR_ACCESS_TOKEN',
accessSecret: 'YOUR_ACCESS_SECRET',
};
async function loadConfig() {
try {
const configPath = '/root/Projects/dear-bubbe-nextjs/lib/twitter-api-config.json';
const savedConfig = JSON.parse(await fs.readFile(configPath, 'utf8'));
Object.assign(config, savedConfig);
return true;
} catch (e) {
console.log('No saved Twitter API config found');
console.log('\n⚠️ You need Twitter API v2 credentials!');
console.log('Get them from: https://developer.twitter.com/en/portal/dashboard');
console.log('\n1. Create an app');
console.log('2. Get API Key, API Secret, Access Token, Access Secret');
console.log('3. Save them in twitter-api-config.json');
return false;
}
}
async function postTweet(text) {
console.log('🐦 Posting to Twitter/X via API v2...');
if (!await loadConfig()) {
return false;
}
try {
const client = new TwitterApi({
appKey: config.appKey,
appSecret: config.appSecret,
accessToken: config.accessToken,
accessSecret: config.accessSecret,
});
const tweet = await client.v2.tweet(text);
console.log('✅ Tweet posted!');
console.log('Tweet ID:', tweet.data.id);
console.log('URL: https://twitter.com/DearBubbe/status/' + tweet.data.id);
return true;
} catch (error) {
console.error('❌ Error:', error.message);
return false;
}
}
async function postFromQueue() {
try {
const queuePath = '/root/Projects/dear-bubbe-admin/logs/twitter-queue.json';
const queue = JSON.parse(await fs.readFile(queuePath, 'utf8'));
const toPost = queue.find(t => t.status === 'queued');
if (!toPost) {
console.log('No posts in queue');
return false;
}
console.log('Posting from queue:', toPost.text.substring(0, 50) + '...');
const success = await postTweet(toPost.text);
if (success) {
toPost.status = 'posted';
toPost.postedAt = new Date().toISOString();
await fs.writeFile(queuePath, JSON.stringify(queue, null, 2));
console.log('Queue updated');
}
return success;
} catch (error) {
console.error('Error:', error);
return false;
}
}
module.exports = { postTweet, postFromQueue };
if (require.main === module) {
if (process.argv[2] === 'test') {
postTweet('Testing Bubbe auto-post with API v2! #BubbeAI Visit Bubbe.AI');
} else {
postFromQueue();
}
}