← Назад
import 'dotenv/config'; const API_KEY = process.env.POPADS_API_KEY; const BASE_V1 = 'https://www.popads.net/api'; const BASE_V2 = 'https://www.popads.net/apiv2'; if (!API_KEY) { console.error('❌ POPADS_API_KEY not set in .env'); process.exit(1); } // ─── API v1 ──────────────────────────────────────────── const v1 = async (action, params = {}, method = 'GET') => { const url = new URL(`${BASE_V1}/${action}`); url.searchParams.set('key', API_KEY); const opts = { method, headers: { Accept: 'application/json' } }; if (method === 'POST') { Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v)); } else { Object.entries(params).forEach(([k, v]) => url.searchParams.set(k, v)); } const res = await fetch(url, opts); if (!res.ok && res.status !== 406) { const text = await res.text(); throw new Error(`PopAds v1 ${res.status}: ${text}`); } return res.json(); }; // ─── API v2 ──────────────────────────────────────────── const v2 = async (method, path, body = null) => { const url = `${BASE_V2}${path}?key=${API_KEY}`; const opts = { method, headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, }; if (body) opts.body = JSON.stringify(body); const res = await fetch(url, opts); const data = await res.json(); return data; }; // ─── v1 Commands ─────────────────────────────────────── const userStatus = () => v1('user_status'); const campaignList = () => v1('campaign_list'); const campaignStart = (id) => v1('campaign_start', { campaign_id: id }, 'POST'); const campaignPause = (id) => v1('campaign_pause', { campaign_id: id }, 'POST'); const campaignTopUp = (id, amount) => v1('campaign_top_up', { campaign_id: id, amount }, 'POST'); const campaignEmptyBudget = (id, amount) => v1('campaign_empty_budget', { campaign_id: id, amount }, 'POST'); const campaignRunout = () => v1('campaign_runout'); const websiteDetails = (id) => v1(`website_details/${id}`); const reportAdvertiser = (params = {}) => { const defaults = { zone: 'America/Vancouver', quick: 'today', groups: 'campaigns', }; return v1('report_advertiser', { ...defaults, ...params }, 'POST'); }; // ─── v2 Commands ─────────────────────────────────────── const getCampaignDetails = (id) => v2('GET', `/campaign/details/${id}`); const createCampaign = (config) => v2('POST', '/campaign/add', config); const updateCampaign = (id, config) => v2('PUT', `/campaign/update/${id}`, config); const patchCampaign = (id, config) => v2('PATCH', `/campaign/update/${id}`, config); const getOptions = (name, country = null) => { const path = country ? `/options/${name}/${country}` : `/options/${name}`; return v2('GET', path); }; // ─── CLI ─────────────────────────────────────────────── const [cmd, ...args] = process.argv.slice(2); const commands = { async status() { console.log('\nπŸ‘€ PopAds Account\n'); const data = await userStatus(); console.log(JSON.stringify(data, null, 2)); }, async campaigns() { console.log('\nπŸ“’ Campaigns\n'); const data = await campaignList(); if (Array.isArray(data)) { data.forEach((c) => { console.log(` β€’ [${c.id}] ${c.name} β€” ${c.status} | budget: $${c.budget || '?'} | bid: $${c.max_bid || '?'}`); }); } else { console.log(JSON.stringify(data, null, 2)); } }, async start() { const [id] = args; if (!id) { console.log('Usage: node popads.js start <campaign_id>'); return; } const r = await campaignStart(id); console.log('βœ… Started:', JSON.stringify(r)); }, async pause() { const [id] = args; if (!id) { console.log('Usage: node popads.js pause <campaign_id>'); return; } const r = await campaignPause(id); console.log('⏸️ Paused:', JSON.stringify(r)); }, async topup() { const [id, amount] = args; if (!id || !amount) { console.log('Usage: node popads.js topup <campaign_id> <amount>'); return; } const r = await campaignTopUp(id, amount); console.log('πŸ’° Topped up:', JSON.stringify(r)); }, async report() { const [quick, group] = args; console.log(`\nπŸ“Š Report (${quick || 'today'}, group: ${group || 'campaigns'})\n`); const data = await reportAdvertiser({ quick: quick || 'today', groups: group || 'campaigns', }); console.log(JSON.stringify(data, null, 2)); }, async details() { const [id] = args; if (!id) { console.log('Usage: node popads.js details <campaign_id>'); return; } const data = await getCampaignDetails(id); console.log(JSON.stringify(data, null, 2)); }, async options() { const [name, country] = args; if (!name) { console.log(` Options: ad-block-values, advertise-type, browsers, categories, connection-speeds, connection-types, countries, devices, form-factors, frequency-cap-days, languages, operating-systems, quality, resolutions, timezones, regions/{country}`); return; } const data = await getOptions(name, country); console.log(JSON.stringify(data, null, 2)); }, async create() { console.log('⚠️ Use node popads.js create-cpi or create-mainstream'); }, // Quick campaign creator β€” CPI SmartLink via BeMob async 'create-cpi'() { const [geo, budget, bid] = args; if (!geo) { console.log('Usage: node popads.js create-cpi <GEO> [budget] [bid]'); return; } const BEMOB_CPI_URL = 'https://27zff.bemobtrcks.com/go/06b83d41-b52e-443d-a1a3-c52adf4bb40c'; console.log(`Creating CPI campaign for ${geo.toUpperCase()}...`); const r = await createCampaign(buildCampaignConfig( `CPI Direct - ${geo.toUpperCase()}`, BEMOB_CPI_URL, geo, budget, bid )); console.log(JSON.stringify(r, null, 2)); }, // Quick campaign creator β€” Mainstream SmartLink via BeMob async 'create-mainstream'() { const [geo, budget, bid] = args; if (!geo) { console.log('Usage: node popads.js create-mainstream <GEO> [budget] [bid]'); return; } const BEMOB_MS_URL = 'https://27zff.bemobtrcks.com/go/8fb53f2a-e310-4aa3-b573-9ba53a7664a8'; console.log(`Creating Mainstream campaign for ${geo.toUpperCase()}...`); const r = await createCampaign(buildCampaignConfig( `Mainstream Direct - ${geo.toUpperCase()}`, BEMOB_MS_URL, geo, budget, bid )); console.log(JSON.stringify(r, null, 2)); }, async help() { console.log(` πŸ”§ PopAds CLI Аккаунт: node popads.js status β€” Баланс, ΠΈΠ½Ρ„ΠΎ node popads.js campaigns β€” Бписок ΠΊΠ°ΠΌΠΏΠ°Π½ΠΈΠΉ Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅: node popads.js start <id> β€” Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ кампанию node popads.js pause <id> β€” ΠŸΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π½Π° ΠΏΠ°ΡƒΠ·Ρƒ node popads.js topup <id> <amount> β€” ΠŸΠΎΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ кампанию node popads.js details <id> β€” Π”Π΅Ρ‚Π°Π»ΠΈ ΠΊΠ°ΠΌΠΏΠ°Π½ΠΈΠΈ (v2) Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅: node popads.js create-cpi <GEO> [budget] [bid] node popads.js create-mainstream <GEO> [budget] [bid] ΠŸΡ€ΠΈΠΌΠ΅Ρ€: node popads.js create-cpi PH 10 0.001 ΠžΡ‚Ρ‡Ρ‘Ρ‚Ρ‹: node popads.js report [quick] [group] quick: today, yesterday, last7days, last30days, thismonth group: campaigns, websites, countries, hours Π‘ΠΏΡ€Π°Π²ΠΎΡ‡Π½ΠΈΠΊΠΈ: node popads.js options β€” Бписок справочников node popads.js options countries β€” Π‘Ρ‚Ρ€Π°Π½Ρ‹ node popads.js options operating-systems β€” ОБ `); }, }; const run = commands[cmd] || commands.help; run().catch((err) => { console.error(`❌ ${err.message}`); process.exit(1); }); export { userStatus, campaignList, campaignStart, campaignPause, campaignTopUp, reportAdvertiser, getCampaignDetails, createCampaign, updateCampaign, patchCampaign, getOptions, };