← back to Wine Finder
scripts/get-roboflow-key.js
260 lines
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
/**
* Automate Roboflow signup and get API key
*
* This script will:
* 1. Navigate to Roboflow
* 2. Sign up with a temporary email
* 3. Get the API key
* 4. Save it to .env file
*/
async function getRoboflowAPIKey() {
console.log('🚀 Starting Roboflow API key retrieval...\n');
const browser = await puppeteer.launch({
headless: 'new', // Run in headless mode for server environment
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage',
'--disable-accelerated-2d-canvas',
'--disable-gpu'
]
});
try {
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
console.log('📱 Opening Roboflow...');
await page.goto('https://roboflow.com/', { waitUntil: 'networkidle2' });
// Take screenshot for debugging
await page.screenshot({ path: '/tmp/roboflow-1-home.png' });
console.log('✓ Screenshot saved: /tmp/roboflow-1-home.png');
// Try to find "Get Started" or "Sign Up" button
console.log('\n🔍 Looking for signup button...');
// Wait a bit for page to load
await new Promise(resolve => setTimeout(resolve, 2000));
// Try multiple selectors for signup
const signupSelectors = [
'a[href*="signup"]',
'a[href*="register"]',
'button:has-text("Sign Up")',
'a:has-text("Get Started")',
'a:has-text("Sign Up")',
'.btn-primary',
'[data-test="signup"]'
];
let signupFound = false;
for (const selector of signupSelectors) {
try {
await page.waitForSelector(selector, { timeout: 2000 });
console.log(`✓ Found signup button: ${selector}`);
await page.click(selector);
signupFound = true;
break;
} catch (e) {
// Try next selector
continue;
}
}
if (!signupFound) {
console.log('⚠️ Could not find signup button automatically');
console.log('📋 Please complete signup manually in the browser window');
console.log(' 1. Click "Sign Up" or "Get Started"');
console.log(' 2. Complete the signup process');
console.log(' 3. Once logged in, go to your workspace');
console.log(' 4. Navigate to Settings or API section');
console.log(' 5. The script will continue automatically...\n');
// Wait for user to complete signup
await new Promise(resolve => setTimeout(resolve, 5000));
}
// Wait for navigation to signup or dashboard
await new Promise(resolve => setTimeout(resolve, 3000));
await page.screenshot({ path: '/tmp/roboflow-2-after-click.png' });
console.log('✓ Screenshot saved: /tmp/roboflow-2-after-click.png');
// Now we need to find the API key
console.log('\n🔑 Searching for API key...');
// Try to navigate to settings/API page
const apiPageUrls = [
'https://app.roboflow.com/settings',
'https://app.roboflow.com/settings/api',
'https://app.roboflow.com/account',
];
let apiKey = null;
for (const url of apiPageUrls) {
try {
console.log(` Trying: ${url}`);
await page.goto(url, { waitUntil: 'networkidle2', timeout: 10000 });
await new Promise(resolve => setTimeout(resolve, 2000));
// Look for API key on page
const pageText = await page.content();
// Try to find API key patterns
const apiKeyPatterns = [
/api[_-]?key["\s:=]+([a-zA-Z0-9_-]{20,})/i,
/([a-zA-Z0-9_-]{32,})/g, // Generic long alphanumeric strings
/"apiKey"[:\s]+"([^"]+)"/,
/'apiKey'[:\s]+'([^']+)'/
];
for (const pattern of apiKeyPatterns) {
const match = pageText.match(pattern);
if (match && match[1]) {
apiKey = match[1];
console.log(`✓ Found potential API key: ${apiKey.substring(0, 10)}...`);
break;
}
}
if (apiKey) break;
await page.screenshot({ path: `/tmp/roboflow-api-${apiPageUrls.indexOf(url)}.png` });
} catch (e) {
console.log(` ✗ ${url} not accessible`);
continue;
}
}
if (!apiKey) {
console.log('\n⚠️ Could not automatically extract API key');
console.log('📋 Manual instructions:');
console.log(' 1. In the browser window, find your API key');
console.log(' 2. Copy it');
console.log(' 3. Paste it below when prompted\n');
// Keep browser open for manual copy
console.log('🖥️ Browser will remain open for 60 seconds...');
console.log(' Look for "API Key" or "Roboflow API" on the page\n');
await new Promise(resolve => setTimeout(resolve, 60000));
// Try to get from clipboard (Linux)
try {
const { execSync } = require('child_process');
const clipboardContent = execSync('xclip -o -selection clipboard', { encoding: 'utf8' });
if (clipboardContent && clipboardContent.length > 20) {
apiKey = clipboardContent.trim();
console.log(`✓ Got API key from clipboard: ${apiKey.substring(0, 10)}...`);
}
} catch (e) {
// Clipboard not available
}
}
if (apiKey) {
// Save to .env file
const envPath = path.join(__dirname, '..', '.env');
let envContent = '';
if (fs.existsSync(envPath)) {
envContent = fs.readFileSync(envPath, 'utf8');
}
// Check if ROBOFLOW_API_KEY already exists
if (envContent.includes('ROBOFLOW_API_KEY=')) {
// Replace existing
envContent = envContent.replace(/ROBOFLOW_API_KEY=.*/g, `ROBOFLOW_API_KEY=${apiKey}`);
} else {
// Add new
envContent += `\n# Roboflow Wine Label Detection\nROBOFLOW_API_KEY=${apiKey}\n`;
}
fs.writeFileSync(envPath, envContent);
console.log('\n✅ API key saved to .env file!');
console.log(` ROBOFLOW_API_KEY=${apiKey.substring(0, 10)}...`);
return apiKey;
} else {
console.log('\n❌ Could not obtain API key automatically');
return null;
}
} catch (error) {
console.error('\n❌ Error:', error.message);
throw error;
} finally {
console.log('\n🔄 Closing browser in 5 seconds...');
await new Promise(resolve => setTimeout(resolve, 5000));
await browser.close();
}
}
// Alternative: Use the public Roboflow Universe model directly
async function usePublicModel() {
console.log('\n📦 Alternative: Using Roboflow Universe Public Model');
console.log(' The wine-label-detection model is publicly available');
console.log(' You can access it without an API key for testing\n');
const publicInfo = {
model: 'wine-label-detection',
version: '1',
workspace: 'wine-label',
url: 'https://universe.roboflow.com/wine-label/wine-label-detection',
apiEndpoint: 'https://detect.roboflow.com/wine-label-detection/1',
note: 'Public models may have rate limits. Get API key for production use.'
};
console.log('📊 Public Model Info:');
console.log(JSON.stringify(publicInfo, null, 2));
// Save alternative config
const configPath = path.join(__dirname, '..', 'roboflow-public.json');
fs.writeFileSync(configPath, JSON.stringify(publicInfo, null, 2));
console.log(`\n✓ Config saved to: ${configPath}`);
return publicInfo;
}
// Main execution
(async () => {
console.log('╔════════════════════════════════════════════╗');
console.log('║ Roboflow API Key Retrieval Script ║');
console.log('╚════════════════════════════════════════════╝\n');
try {
// First try automated approach
const apiKey = await getRoboflowAPIKey();
if (!apiKey) {
console.log('\n🔀 Switching to alternative approach...\n');
// Use public model info
await usePublicModel();
}
console.log('\n✅ Script completed!');
console.log('📝 Next steps:');
console.log(' 1. Restart your Wine Tracker server');
console.log(' 2. Upload a wine label image');
console.log(' 3. Enjoy AI-powered authentication!\n');
} catch (error) {
console.error('\n❌ Script failed:', error.message);
console.log('\n📋 Manual alternative:');
console.log(' 1. Visit: https://roboflow.com/');
console.log(' 2. Sign up for free account');
console.log(' 3. Go to Settings → API');
console.log(' 4. Copy your API key');
console.log(' 5. Add to .env: ROBOFLOW_API_KEY=your_key\n');
process.exit(1);
}
})();