← back to Dear Bubbe Nextjs
archived/social-posters/x-simple-poster.js
150 lines
const https = require('https');
const fs = require('fs').promises;
// Simple X.com poster using just cookies
async function postToX(text) {
console.log('🐦 Posting to X.com...');
// Your tokens
const auth_token = '29242b900adcea897a68bf3c6f5ba838bc5b90ad2162404f2a02090757d7dd75042da41274308247b3296bd5cdfe262dee726059fcf260ea7caf13c41bb8bebf6f79acff9bb8b9dc6cdca30b0846bc65ec6f30c5212f03270cb1467cefbb5e44a9a18297';
const ct0 = '2162404f2a02090757d7dd75042da41274308247b3296bd5cdfe262dee726059fcf260ea7caf13c41bb8bebf6f79acff9bb8b9dc6cdca30b0846bc65ec6f30c5212f03270cb1467cefbb5e44a9a18297';
// Build the cookie string
const cookies = [
`auth_token=${auth_token}`,
`ct0=${ct0}`,
'guest_id=v1%3A172000000000000000',
'lang=en',
'twid=u%3D1858337066252591104',
'des_opt_in=Y',
'_twitter_sess=BAh7CSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCKN3M5eTAToMY3NyZl9p%250AZCIlMzJmOGU5MzQ0ZGFkMjA1MDk3MDE2ZWI4YjA5Y2FkNDg6B2lkIiU4YjE0%250ANmJkZTM1Y2E0MmY0YmE0YTVlMDJhNzM3MGY2Yg%253D%253D--c8c6e41e83bdcfd4b89f3e29b8a529e5ceaa2b8f'
].join('; ');
const postData = JSON.stringify({
variables: {
tweet_text: text,
dark_request: false,
media: {
media_entities: [],
possibly_sensitive: false
},
semantic_annotation_ids: []
},
features: {
communities_web_enable_tweet_community_results_fetch: true,
c9s_tweet_anatomy_moderator_badge_enabled: true,
responsive_web_edit_tweet_api_enabled: true,
graphql_is_translatable_rweb_tweet_is_translatable_enabled: true,
view_counts_everywhere_api_enabled: true,
longform_notetweets_consumption_enabled: true,
responsive_web_twitter_article_tweet_consumption_enabled: true,
tweet_awards_web_tipping_enabled: false,
longform_notetweets_rich_text_read_enabled: true,
longform_notetweets_inline_media_enabled: true,
responsive_web_graphql_exclude_directive_enabled: true,
verified_phone_label_enabled: false,
freedom_of_speech_not_reach_fetch_enabled: true,
standardized_nudges_misinfo: true,
tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true,
responsive_web_graphql_timeline_navigation_enabled: true,
responsive_web_enhance_cards_enabled: false
}
});
return new Promise((resolve, reject) => {
const options = {
hostname: 'x.com',
path: '/i/api/graphql/oB-5XsHNAbjvARJEc8CZFw/CreateTweet',
method: 'POST',
headers: {
'authority': 'x.com',
'accept': '*/*',
'accept-language': 'en-US,en;q=0.9',
'authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA',
'content-type': 'application/json',
'cookie': cookies,
'origin': 'https://x.com',
'referer': 'https://x.com/compose/post',
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'x-client-uuid': '4f3a9647-ac5e-4e9b-9d7f-' + Date.now(),
'x-csrf-token': ct0,
'x-twitter-active-user': 'yes',
'x-twitter-auth-type': 'OAuth2Session',
'x-twitter-client-language': 'en'
}
};
const req = https.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Status:', res.statusCode);
console.log('Response:', data.substring(0, 200));
if (res.statusCode === 200) {
console.log('✅ Posted successfully!');
resolve(true);
} else {
console.log('❌ Failed to post');
resolve(false);
}
});
});
req.on('error', (e) => {
console.error('Error:', e);
reject(e);
});
req.write(postData);
req.end();
});
}
// Post from queue
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:', toPost.text.substring(0, 50) + '...');
const success = await postToX(toPost.text);
if (success) {
toPost.status = 'posted';
toPost.postedAt = new Date().toISOString();
await fs.writeFile(queuePath, JSON.stringify(queue, null, 2));
}
return success;
} catch (error) {
console.error('Error:', error);
return false;
}
}
if (require.main === module) {
if (process.argv[2] === 'test') {
postToX('Test post from Bubbe AI - ' + new Date().toLocaleString());
} else {
postFromQueue();
}
}
module.exports = { postToX, postFromQueue };