security: remove credential automation from releases

This commit is contained in:
Yun Chan 2026-08-29 19:00:44 +09:00
parent f342ea8640
commit 547d4ad97a
9 changed files with 11 additions and 647 deletions

View file

@ -1,29 +0,0 @@
// scripts/capture-forgejo-release-live.js
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
async function capture() {
const browser = await chromium.launch({ channel: 'msedge', headless: true });
const context = await browser.newContext({ viewport: { width: 1440, height: 960 }, deviceScaleFactor: 2 });
const page = await context.newPage();
console.log('Logging in to Forgejo...');
await page.goto('https://git.chanpaca.net/user/login', { waitUntil: 'networkidle' });
await page.fill('input[name="user_name"]', 'yunchan');
await page.fill('input[name="password"]', 'ONVI2v4J#y');
await page.click('button[type="submit"]');
await page.waitForTimeout(3000);
console.log('Navigating to releases...');
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice/releases', { waitUntil: 'networkidle' });
await page.waitForTimeout(2000);
const shotPath = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/git_server/05_forgejo_v1_0_0_official_release_with_binary.png';
await page.screenshot({ path: shotPath, fullPage: true });
console.log('Saved:', shotPath);
await browser.close();
}
capture().catch(console.error);

View file

@ -1,45 +0,0 @@
// scripts/capture-forgejo-repo.js
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/git_server';
async function captureRepo() {
if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR, { recursive: true });
const browser = await chromium.launch({ channel: 'msedge', headless: true });
const context = await browser.newContext({
viewport: { width: 1440, height: 960 },
});
const page = await context.newPage();
// Login to Forgejo
console.log('Logging in to Forgejo git.chanpaca.net...');
await page.goto('https://git.chanpaca.net/user/login', { waitUntil: 'networkidle', timeout: 30000 });
await page.fill('input[name="user_name"]', 'yunchan');
await page.fill('input[name="password"]', 'ONVI2v4J#y');
await page.click('button:has-text("Sign in"), button:has-text("로그인"), button[type="submit"]');
await page.waitForTimeout(3000);
// Navigate to d3ro-voice repository
console.log('Navigating to https://git.chanpaca.net/yunchan/d3ro-voice...');
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const shotPath = path.join(OUTPUT_DIR, '01_forgejo_d3ro_voice_repo_live.png');
await page.screenshot({ path: shotPath, fullPage: false });
console.log('Screenshot saved to:', shotPath);
// Navigate to releases / tags
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice/releases', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const tagShotPath = path.join(OUTPUT_DIR, '02_forgejo_d3ro_voice_releases_tags.png');
await page.screenshot({ path: tagShotPath, fullPage: false });
console.log('Releases screenshot saved to:', tagShotPath);
await browser.close();
}
captureRepo().catch(console.error);

View file

@ -1,45 +0,0 @@
// scripts/inspect-forgejo-runners.js
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/git_server';
async function inspectRunners() {
const browser = await chromium.launch({ channel: 'msedge', headless: true });
const context = await browser.newContext({ viewport: { width: 1440, height: 960 } });
const page = await context.newPage();
console.log('Logging in to Forgejo...');
await page.goto('https://git.chanpaca.net/user/login', { waitUntil: 'networkidle', timeout: 30000 });
await page.fill('input[name="user_name"]', 'yunchan');
await page.fill('input[name="password"]', 'ONVI2v4J#y');
await page.click('button:has-text("Sign in"), button:has-text("로그인"), button[type="submit"]');
await page.waitForTimeout(3000);
// Check Admin Actions Runners
console.log('Navigating to Admin Actions Runners...');
await page.goto('https://git.chanpaca.net/admin/actions/runners', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const shot1 = path.join(OUTPUT_DIR, '03_forgejo_admin_runners.png');
await page.screenshot({ path: shot1, fullPage: false });
console.log('Admin Runners screenshot saved:', shot1);
// Check Repo Actions tab
console.log('Navigating to Repo Actions...');
await page.goto('https://git.chanpaca.net/yunchan/d3ro-voice/actions', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const shot2 = path.join(OUTPUT_DIR, '04_forgejo_repo_actions.png');
await page.screenshot({ path: shot2, fullPage: false });
console.log('Repo Actions screenshot saved:', shot2);
// Extract runner details from page
await page.goto('https://git.chanpaca.net/admin/actions/runners');
await page.waitForTimeout(1000);
const runnerRows = await page.locator('table tr, .runner-item, .flex-list-item').allInnerTexts();
console.log('RUNNER ROWS FOUND:', JSON.stringify(runnerRows, null, 2));
await browser.close();
}
inspectRunners().catch(console.error);

View file

@ -1,123 +0,0 @@
// scripts/playwright-fill-all-live-ad-portals.js
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/live_portal_signups';
const CREDS = {
email: 'yunchanpaca@gmail.com',
password: 'ONVI2v4J#y',
firstName: 'Yunchan',
lastName: 'Park',
fullName: 'Yunchan Park',
company: 'D3RO Voice AI',
url: 'https://d3ro.app',
};
async function fillAllLiveAdPortals() {
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}
const browser = await chromium.launch({
channel: 'msedge',
headless: true,
});
const context = await browser.newContext({
viewport: { width: 1440, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
});
// 1. AppLovin MAX
try {
console.log('[1/3] Interacting with AppLovin MAX Signup...');
const page = await context.newPage();
await page.goto('https://dash.applovin.com/signup', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const nameInput = page.locator('input[placeholder*="name" i]').first();
const emailInput = page.locator('input[type="email"]').first();
const companyInput = page.locator('input[placeholder*="company" i]').first();
const websiteInput = page.locator('input[placeholder*="applovin.com" i], input[placeholder*="site" i]').first();
const storeUrlInput = page.locator('input[placeholder*="store" i]').first();
const passInputs = page.locator('input[type="password"]');
if (await nameInput.isVisible()) await nameInput.fill(CREDS.fullName);
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
if (await companyInput.isVisible()) await companyInput.fill(CREDS.company);
if (await websiteInput.isVisible()) await websiteInput.fill(CREDS.url);
if (await storeUrlInput.isVisible()) await storeUrlInput.fill('https://d3ro.app/download/desktop');
// Fill both password and confirm password
const count = await passInputs.count();
for (let i = 0; i < count; i++) {
await passInputs.nth(i).fill(CREDS.password);
}
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '02_applovin_max_form_filled_complete.png');
await page.screenshot({ path: shotPath, fullPage: true });
console.log('AppLovin MAX complete screenshot saved:', shotPath);
await page.close();
} catch (err) {
console.error('AppLovin error:', err.message);
}
// 2. Mintegral Developer Signup
try {
console.log('[2/3] Interacting with Mintegral Signup...');
const page = await context.newPage();
await page.goto('https://www.mintegral.com/en/signup', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const emailInput = page.locator('input[type="email"], input[placeholder*="email" i]').first();
const passInputs = page.locator('input[type="password"]');
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
const count = await passInputs.count();
for (let i = 0; i < count; i++) {
await passInputs.nth(i).fill(CREDS.password);
}
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '03_mintegral_signup_filled_complete.png');
await page.screenshot({ path: shotPath, fullPage: false });
console.log('Mintegral complete screenshot saved:', shotPath);
await page.close();
} catch (err) {
console.error('Mintegral error:', err.message);
}
// 3. Unity ID Registration
try {
console.log('[3/3] Interacting with Unity ID Registration...');
const page = await context.newPage();
await page.goto('https://id.unity.com/en/conversations/new', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const emailInput = page.locator('input[type="email"]').first();
const passInput = page.locator('input[type="password"]').first();
const usernameInput = page.locator('input[name*="username" i]').first();
const fullnameInput = page.locator('input[name*="name" i]').first();
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
if (await passInput.isVisible()) await passInput.fill(CREDS.password);
if (await usernameInput.isVisible()) await usernameInput.fill('yunchanpaca');
if (await fullnameInput.isVisible()) await fullnameInput.fill(CREDS.fullName);
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '06_unity_cloud_signup_filled_complete.png');
await page.screenshot({ path: shotPath, fullPage: false });
console.log('Unity ID complete screenshot saved:', shotPath);
await page.close();
} catch (err) {
console.error('Unity error:', err.message);
}
await browser.close();
console.log('--- All Direct Browser Actions Completed! ---');
}
fillAllLiveAdPortals().catch(console.error);

View file

@ -1,214 +0,0 @@
// scripts/playwright-live-ad-portals-signup.js
// Playwright Automation: Navigates to live ad portals, fills publisher registration forms with user credentials, and captures progress.
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/live_portal_signups';
const USER_CREDENTIALS = {
email: 'yunchanpaca@gmail.com',
password: 'ONVI2v4J#y',
firstName: 'Yunchan',
lastName: 'Park',
fullName: 'Yunchan Park',
company: 'D3RO Voice AI',
appName: 'D3RO Voice AI (Desktop & Web AI Assistant)',
appUrl: 'https://d3ro.app',
monthlyImpressions: '100,000+',
country: 'South Korea',
};
async function runLiveAdPortalsSignup() {
if (!fs.existsSync(OUTPUT_DIR)) {
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
}
console.log('--- Launching Playwright Browser Automation for Live Ad Portals Signup ---');
const browser = await chromium.launch({
channel: 'msedge',
headless: true, // headless mode for reliable capture in CLI environment
});
const context = await browser.newContext({
viewport: { width: 1440, height: 960 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0',
});
const results = [];
// ==========================================
// 1. EthicalAds Publisher Application
// ==========================================
try {
console.log('[1/5] Navigating to EthicalAds Publisher Application...');
const page = await context.newPage();
await page.goto('https://www.ethicalads.io/publishers/apply/', { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(2000);
// Fill form fields
const nameInput = page.locator('input[name="name"], input[id*="name"]').first();
const emailInput = page.locator('input[name="email"], input[type="email"], input[id*="email"]').first();
const siteInput = page.locator('input[name*="site"], input[name*="url"], input[id*="url"]').first();
const trafficInput = page.locator('input[name*="views"], input[name*="traffic"], select[name*="traffic"]').first();
if (await nameInput.isVisible()) await nameInput.fill(USER_CREDENTIALS.fullName);
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
if (await siteInput.isVisible()) await siteInput.fill(USER_CREDENTIALS.appUrl);
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '01_ethicalads_signup_filled.png');
await page.screenshot({ path: shotPath, fullPage: true });
results.push({ portal: 'EthicalAds', status: 'Form Filled & Captured', screenshot: shotPath });
await page.close();
} catch (err) {
console.error('EthicalAds signup error:', err.message);
}
// ==========================================
// 2. AppLovin MAX Developer Signup
// ==========================================
try {
console.log('[2/5] Navigating to AppLovin MAX Developer Signup...');
const page = await context.newPage();
await page.goto('https://dash.applovin.com/signup', { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(3000);
const emailInput = page.locator('input[name="email"], input[type="email"]').first();
const nameInput = page.locator('input[name="name"], input[name="fullName"]').first();
const companyInput = page.locator('input[name="company"], input[name="companyName"]').first();
const websiteInput = page.locator('input[name="website"], input[name="url"]').first();
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
if (await nameInput.isVisible()) await nameInput.fill(USER_CREDENTIALS.fullName);
if (await companyInput.isVisible()) await companyInput.fill(USER_CREDENTIALS.company);
if (await websiteInput.isVisible()) await websiteInput.fill(USER_CREDENTIALS.appUrl);
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '02_applovin_max_signup_filled.png');
await page.screenshot({ path: shotPath, fullPage: false });
results.push({ portal: 'AppLovin MAX', status: 'Form Filled & Captured', screenshot: shotPath });
await page.close();
} catch (err) {
console.error('AppLovin signup error:', err.message);
}
// ==========================================
// 3. Mintegral Publisher / Developer Signup
// ==========================================
try {
console.log('[3/5] Navigating to Mintegral Publisher Signup...');
const page = await context.newPage();
await page.goto('https://www.mintegral.com/en/signup', { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(3000);
const emailInput = page.locator('input[type="email"], input[placeholder*="email" i]').first();
const passwordInput = page.locator('input[type="password"]').first();
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
if (await passwordInput.isVisible()) await passwordInput.fill(USER_CREDENTIALS.password);
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '03_mintegral_signup_filled.png');
await page.screenshot({ path: shotPath, fullPage: false });
results.push({ portal: 'Mintegral', status: 'Form Filled & Captured', screenshot: shotPath });
await page.close();
} catch (err) {
console.error('Mintegral signup error:', err.message);
}
// ==========================================
// 4. Playwire Publisher Application Form
// ==========================================
try {
console.log('[4/5] Navigating to Playwire Publisher Application...');
const page = await context.newPage();
await page.goto('https://www.playwire.com/contact-direct', { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(3000);
const firstNameInput = page.locator('input[name*="firstname" i]').first();
const lastNameInput = page.locator('input[name*="lastname" i]').first();
const emailInput = page.locator('input[name*="email" i], input[type="email"]').first();
const websiteInput = page.locator('input[name*="website" i], input[name*="url" i]').first();
if (await firstNameInput.isVisible()) await firstNameInput.fill(USER_CREDENTIALS.firstName);
if (await lastNameInput.isVisible()) await lastNameInput.fill(USER_CREDENTIALS.lastName);
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
if (await websiteInput.isVisible()) await websiteInput.fill(USER_CREDENTIALS.appUrl);
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '04_playwire_application_filled.png');
await page.screenshot({ path: shotPath, fullPage: true });
results.push({ portal: 'Playwire', status: 'Form Filled & Captured', screenshot: shotPath });
await page.close();
} catch (err) {
console.error('Playwire signup error:', err.message);
}
// ==========================================
// 5. BuySellAds (Carbon Ads) Publisher Portal
// ==========================================
try {
console.log('[5/5] Navigating to BuySellAds (Carbon) Publisher Portal...');
const page = await context.newPage();
await page.goto('https://www.buysellads.com/publishers', { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(3000);
const applyButton = page.locator('a:has-text("Apply"), button:has-text("Apply"), a:has-text("Get Started")').first();
if (await applyButton.isVisible()) {
await applyButton.click();
await page.waitForTimeout(2000);
}
const shotPath = path.join(OUTPUT_DIR, '05_buysellads_carbon_publisher_apply.png');
await page.screenshot({ path: shotPath, fullPage: true });
results.push({ portal: 'BuySellAds (Carbon)', status: 'Form Navigated & Captured', screenshot: shotPath });
await page.close();
} catch (err) {
console.error('BuySellAds signup error:', err.message);
}
// ==========================================
// 6. Unity ID / Unity Gaming Services
// ==========================================
try {
console.log('[6/6] Navigating to Unity ID Registration...');
const page = await context.newPage();
await page.goto('https://id.unity.com/en/conversations/new', { waitUntil: 'domcontentloaded', timeout: 30000 });
await page.waitForTimeout(3000);
const emailInput = page.locator('input[name="conversations_create_user_form[email]"], input[type="email"]').first();
const passwordInput = page.locator('input[name="conversations_create_user_form[password]"], input[type="password"]').first();
const usernameInput = page.locator('input[name="conversations_create_user_form[username]"], input[name*="username"]').first();
const fullnameInput = page.locator('input[name="conversations_create_user_form[full_name]"], input[name*="name"]').first();
if (await emailInput.isVisible()) await emailInput.fill(USER_CREDENTIALS.email);
if (await passwordInput.isVisible()) await passwordInput.fill(USER_CREDENTIALS.password);
if (await usernameInput.isVisible()) await usernameInput.fill('yunchanpaca');
if (await fullnameInput.isVisible()) await fullnameInput.fill(USER_CREDENTIALS.fullName);
await page.waitForTimeout(1000);
const shotPath = path.join(OUTPUT_DIR, '06_unity_cloud_signup_filled.png');
await page.screenshot({ path: shotPath, fullPage: false });
results.push({ portal: 'Unity Ads (LevelPlay)', status: 'Form Filled & Captured', screenshot: shotPath });
await page.close();
} catch (err) {
console.error('Unity signup error:', err.message);
}
await browser.close();
fs.writeFileSync(
path.join(OUTPUT_DIR, 'signup_automation_summary.json'),
JSON.stringify(results, null, 2),
'utf8'
);
console.log('--- Playwright Live Ad Portals Signup Automation Finished Successfully! ---');
}
runLiveAdPortalsSignup().catch((err) => {
console.error('Live Ad Portals Signup Automation Error:', err);
process.exit(1);
});

View file

@ -1,73 +0,0 @@
// scripts/playwright-submit-applovin.js
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
const OUTPUT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/live_portal_signups';
const CREDS = {
email: 'yunchanpaca@gmail.com',
password: 'ONVI2v4J#y',
fullName: 'Yunchan Park',
company: 'D3RO Voice AI',
url: 'https://d3ro.app',
};
async function submitAppLovin() {
const browser = await chromium.launch({ channel: 'msedge', headless: true });
const context = await browser.newContext({
viewport: { width: 1440, height: 1080 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36',
});
const page = await context.newPage();
console.log('Navigating to AppLovin MAX...');
await page.goto('https://dash.applovin.com/signup', { waitUntil: 'networkidle', timeout: 30000 });
await page.waitForTimeout(2000);
const nameInput = page.locator('input[placeholder*="name" i]').first();
const emailInput = page.locator('input[type="email"]').first();
const companyInput = page.locator('input[placeholder*="company" i]').first();
const websiteInput = page.locator('input[placeholder*="applovin.com" i], input[placeholder*="site" i]').first();
const storeUrlInput = page.locator('input[placeholder*="store" i]').first();
const passInputs = page.locator('input[type="password"]');
if (await nameInput.isVisible()) await nameInput.fill(CREDS.fullName);
if (await emailInput.isVisible()) await emailInput.fill(CREDS.email);
if (await companyInput.isVisible()) await companyInput.fill(CREDS.company);
if (await websiteInput.isVisible()) await websiteInput.fill(CREDS.url);
if (await storeUrlInput.isVisible()) await storeUrlInput.fill('https://play.google.com/store/apps/details?id=ai.d3ro.voice');
const count = await passInputs.count();
for (let i = 0; i < count; i++) {
await passInputs.nth(i).fill(CREDS.password);
}
// Scroll down
await page.evaluate(() => window.scrollBy(0, 400));
await page.waitForTimeout(1000);
// Check checkboxes
const checkboxes = page.locator('input[type="checkbox"]');
const cbCount = await checkboxes.count();
for (let i = 0; i < cbCount; i++) {
try {
await checkboxes.nth(i).check({ force: true });
} catch {}
}
const submitBtn = page.locator('button:has-text("Sign up"), button:has-text("Create Account"), button[type="submit"]').first();
if (await submitBtn.isVisible()) {
console.log('Clicking Sign up button...');
await submitBtn.click();
await page.waitForTimeout(6000);
}
const shotPath = path.join(OUTPUT_DIR, '02_applovin_max_final_signup_state.png');
await page.screenshot({ path: shotPath, fullPage: true });
console.log('AppLovin MAX final response captured:', shotPath);
await browser.close();
}
submitAppLovin().catch(console.error);

View file

@ -1,118 +0,0 @@
const { chromium } = require('@playwright/test');
const path = require('path');
const fs = require('fs');
const SCREENSHOT_DIR = 'C:/Users/encep/.gemini/antigravity-cli/brain/3ab7ae82-5634-41d5-93a7-3c12c22503e2/screenshots/ad_portals';
const USER_EMAIL = 'yunchanpaca@gmail.com';
const APP_NAME = 'D3RO Voice';
const APP_URL = 'https://d3ro.voice.ai';
async function inspectAndRegisterPortals() {
if (!fs.existsSync(SCREENSHOT_DIR)) {
fs.mkdirSync(SCREENSHOT_DIR, { recursive: true });
}
const browser = await chromium.launch({ channel: 'msedge', headless: true });
const context = await browser.newContext({
viewport: { width: 1440, height: 900 },
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
});
const page = await context.newPage();
const results = [];
// 1. EthicalAds Publisher Portal
console.log('--- Inspecting Portal 1: EthicalAds ---');
try {
await page.goto('https://www.ethicalads.io/publishers/', { timeout: 30000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '01_ethicalads_publisher_landing.png') });
// Look for apply button or form
const applyLink = page.locator('a[href*="apply"], a[href*="contact"], a:has-text("Apply")').first();
if (await applyLink.isVisible()) {
await applyLink.click();
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '01b_ethicalads_apply_form.png') });
}
results.push({ name: 'EthicalAds', status: 'Inspected & Form Captured', type: 'Privacy-First Dev Ads', api: 'REST Decision API (/api/v1/decision/)' });
} catch (err) {
console.error('EthicalAds inspection error:', err.message);
results.push({ name: 'EthicalAds', status: 'Inspected (Fallback)', type: 'Privacy-First Dev Ads', api: 'REST Decision API' });
}
// 2. Playwire Desktop Video & App Monetization Portal
console.log('--- Inspecting Portal 2: Playwire Desktop Revenue Engine ---');
try {
await page.goto('https://www.playwire.com/contact-desktop-video-app-monetization', { timeout: 30000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '02_playwire_desktop_monetization.png') });
results.push({ name: 'Playwire Desktop', status: 'Inspected & Portal Captured', type: 'Desktop Programmatic Header Bidding', api: 'Playwire RAMP Engine' });
} catch (err) {
console.error('Playwire inspection error:', err.message);
results.push({ name: 'Playwire Desktop', status: 'Inspected', type: 'Desktop Programmatic', api: 'RAMP Engine' });
}
// 3. Carbon Ads (BuySellAds)
console.log('--- Inspecting Portal 3: Carbon Ads ---');
try {
await page.goto('https://www.carbonads.net/', { timeout: 30000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '03_carbon_ads_home.png') });
results.push({ name: 'Carbon Ads', status: 'Inspected', type: 'Tech Native Single-Unit', api: 'Carbon Native JSON' });
} catch (err) {
console.error('Carbon Ads error:', err.message);
results.push({ name: 'Carbon Ads', status: 'Inspected', type: 'Tech Native', api: 'Carbon Native' });
}
// 4. Unity Ads & LevelPlay
console.log('--- Inspecting Portal 4: Unity Ads & LevelPlay ---');
try {
await page.goto('https://unity.com/products/unity-ads', { timeout: 30000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '04_unity_ads_landing.png') });
results.push({ name: 'Unity Ads', status: 'Inspected', type: 'Rewarded Video & Mediation', api: 'Unity LevelPlay SDK' });
} catch (err) {
console.error('Unity Ads error:', err.message);
results.push({ name: 'Unity Ads', status: 'Inspected', type: 'Rewarded Video', api: 'LevelPlay SDK' });
}
// 5. AppLovin MAX
console.log('--- Inspecting Portal 5: AppLovin MAX ---');
try {
await page.goto('https://www.applovin.com/max/', { timeout: 30000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '05_applovin_max_landing.png') });
results.push({ name: 'AppLovin MAX', status: 'Inspected', type: 'Real-time In-App Bidding', api: 'MAX Mediation Adapter' });
} catch (err) {
console.error('AppLovin error:', err.message);
results.push({ name: 'AppLovin MAX', status: 'Inspected', type: 'In-App Bidding', api: 'MAX Adapter' });
}
// 6. PubMatic OpenWrap
console.log('--- Inspecting Portal 6: PubMatic ---');
try {
await page.goto('https://pubmatic.com/', { timeout: 30000 });
await page.waitForTimeout(2000);
await page.screenshot({ path: path.join(SCREENSHOT_DIR, '06_pubmatic_landing.png') });
results.push({ name: 'PubMatic', status: 'Inspected', type: 'Programmatic Header Bidding SSP', api: 'OpenWrap Prebid' });
} catch (err) {
console.error('PubMatic error:', err.message);
results.push({ name: 'PubMatic', status: 'Inspected', type: 'SSP Header Bidding', api: 'OpenWrap' });
}
await browser.close();
console.log('--- Portal Inspection Results ---');
console.log(JSON.stringify(results, null, 2));
fs.writeFileSync(
path.join(SCREENSHOT_DIR, 'portal_inspection_summary.json'),
JSON.stringify(results, null, 2),
'utf-8'
);
}
inspectAndRegisterPortals().catch((err) => {
console.error('Portal script failed:', err);
process.exit(1);
});