Add X integration skill (#52)

This commit is contained in:
BaiJunjie
2026-02-04 07:27:04 +09:00
committed by GitHub
parent 3084fab45d
commit c9ca34a518
11 changed files with 1450 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
#!/usr/bin/env npx tsx
/**
* X Integration - Authentication Setup
* Usage: npx tsx setup.ts
*
* Interactive script - opens browser for manual login
*/
import { chromium } from 'playwright';
import * as readline from 'readline';
import fs from 'fs';
import path from 'path';
import { config, cleanupLockFiles } from '../lib/browser.js';
async function setup(): Promise<void> {
console.log('=== X (Twitter) Authentication Setup ===\n');
console.log('This will open Chrome for you to log in to X.');
console.log('Your login session will be saved for automated interactions.\n');
console.log(`Chrome path: ${config.chromePath}`);
console.log(`Profile dir: ${config.browserDataDir}\n`);
// Ensure directories exist
fs.mkdirSync(path.dirname(config.authPath), { recursive: true });
fs.mkdirSync(config.browserDataDir, { recursive: true });
cleanupLockFiles();
console.log('Launching browser...\n');
const context = await chromium.launchPersistentContext(config.browserDataDir, {
executablePath: config.chromePath,
headless: false,
viewport: config.viewport,
args: config.chromeArgs.slice(0, 3), // Use first 3 args for setup (less restrictive)
ignoreDefaultArgs: config.chromeIgnoreDefaultArgs,
});
const page = context.pages()[0] || await context.newPage();
// Navigate to login page
await page.goto('https://x.com/login');
console.log('Please log in to X in the browser window.');
console.log('After you see your home feed, come back here and press Enter.\n');
// Wait for user to complete login
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
await new Promise<void>(resolve => {
rl.question('Press Enter when logged in... ', () => {
rl.close();
resolve();
});
});
// Verify login by navigating to home and checking for account button
console.log('\nVerifying login status...');
await page.goto('https://x.com/home');
await page.waitForTimeout(config.timeouts.pageLoad);
const isLoggedIn = await page.locator('[data-testid="SideNav_AccountSwitcher_Button"]').isVisible().catch(() => false);
if (isLoggedIn) {
// Save auth marker
fs.writeFileSync(config.authPath, JSON.stringify({
authenticated: true,
timestamp: new Date().toISOString()
}, null, 2));
console.log('\n✅ Authentication successful!');
console.log(`Session saved to: ${config.browserDataDir}`);
console.log('\nYou can now use X integration features.');
} else {
console.log('\n❌ Could not verify login status.');
console.log('Please try again and make sure you are logged in to X.');
}
await context.close();
}
setup().catch(err => {
console.error('Setup failed:', err.message);
process.exit(1);
});