49 lines
1.4 KiB
JavaScript
49 lines
1.4 KiB
JavaScript
#!/usr/bin/env node
|
|
import { TwitterApi } from 'twitter-api-v2';
|
|
import { readFileSync, existsSync } from 'fs';
|
|
import { join } from 'path';
|
|
import { homedir } from 'os';
|
|
|
|
function getCredentials() {
|
|
if (process.env.X_API_KEY && process.env.X_API_SECRET &&
|
|
process.env.X_ACCESS_TOKEN && process.env.X_ACCESS_SECRET) {
|
|
return {
|
|
appKey: process.env.X_API_KEY,
|
|
appSecret: process.env.X_API_SECRET,
|
|
accessToken: process.env.X_ACCESS_TOKEN,
|
|
accessSecret: process.env.X_ACCESS_SECRET,
|
|
};
|
|
}
|
|
const configPath = join(homedir(), '.clawdbot', 'secrets', 'x-api.json');
|
|
if (existsSync(configPath)) {
|
|
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
return {
|
|
appKey: config.consumerKey,
|
|
appSecret: config.consumerSecret,
|
|
accessToken: config.accessToken,
|
|
accessSecret: config.accessTokenSecret,
|
|
};
|
|
}
|
|
console.error('No credentials found.');
|
|
process.exit(1);
|
|
}
|
|
|
|
const text = process.argv.slice(2).join(' ');
|
|
if (!text) { console.error('Usage: x-post "text"'); process.exit(1); }
|
|
|
|
const creds = getCredentials();
|
|
const client = new TwitterApi({
|
|
appKey: creds.appKey,
|
|
appSecret: creds.appSecret,
|
|
accessToken: creds.accessToken,
|
|
accessSecret: creds.accessSecret,
|
|
});
|
|
|
|
try {
|
|
const { data } = await client.v2.tweet(text);
|
|
console.log(`✅ Posted: https://x.com/i/status/${data.id}`);
|
|
} catch (err) {
|
|
console.error('❌ Error:', err.data || err.message || err);
|
|
process.exit(1);
|
|
}
|