VIRAL_HUNTER
A
All
Hit 2×+
Fire 5×+
Legend 10×+
Recent
Evergreen
1M+ Views
Gold Tier
Channel Lists
No saved lists yet.
Enter channels in the config panel
and click + Save to create a list.
Google Sheets Sync
  1. Open sheets.new — create a blank spreadsheet.
  2. Click Extensions → Apps Script.
  3. Delete the placeholder code and paste the script below.
  4. Click Deploy → New deployment → Web app.
    Set Execute as: Me · Who has access: Anyone.
  5. Copy the deployment URL and paste it into the field above, then click Connect.
// ── Viral Hunter · Google Sheets backend ──────────────────────
// Paste this entire file into Apps Script, then deploy as a Web App:
//   Execute as: Me  |  Who has access: Anyone
// ──────────────────────────────────────────────────────────────

const SHEET_NAME = 'Lists';

function doGet(e) {
  const ss     = SpreadsheetApp.getActiveSpreadsheet();
  let   sheet  = ss.getSheetByName(SHEET_NAME);
  const cb     = e.parameter.callback || null; // JSONP support

  // Create the sheet with headers on first run
  if (!sheet) {
    sheet = ss.insertSheet(SHEET_NAME);
    sheet.appendRow(['Name', 'Channels', 'Updated']);
    sheet.setFrozenRows(1);
  }

  const action = (e.parameter.action || 'getLists');

  // ── GET ALL LISTS ──────────────────────────────────────────
  if (action === 'getLists') {
    const data  = sheet.getDataRange().getValues();
    const lists = [];
    for (let i = 1; i < data.length; i++) {
      if (data[i][0]) {
        lists.push({ name: data[i][0], channels: data[i][1] });
      }
    }
    return respond({ ok: true, lists: lists }, cb);
  }

  // ── SAVE / UPDATE A LIST ───────────────────────────────────
  if (action === 'saveList') {
    const name     = e.parameter.name     || '';
    const channels = e.parameter.channels || '';
    if (!name) return respond({ ok: false, error: 'Missing name' }, cb);

    const data = sheet.getDataRange().getValues();
    for (let i = 1; i < data.length; i++) {
      if (data[i][0] === name) {
        sheet.getRange(i + 1, 2, 1, 2).setValues([[channels, new Date().toISOString()]]);
        return respond({ ok: true }, cb);
      }
    }
    sheet.appendRow([name, channels, new Date().toISOString()]);
    return respond({ ok: true }, cb);
  }

  // ── DELETE A LIST ──────────────────────────────────────────
  if (action === 'deleteList') {
    const name = e.parameter.name || '';
    if (!name) return respond({ ok: false, error: 'Missing name' }, cb);

    const data = sheet.getDataRange().getValues();
    for (let i = 1; i < data.length; i++) {
      if (data[i][0] === name) {
        sheet.deleteRow(i + 1);
        return respond({ ok: true }, cb);
      }
    }
    return respond({ ok: false, error: 'List not found' }, cb);
  }

  return respond({ ok: false, error: 'Unknown action: ' + action }, cb);
}

// Helper: returns JSON or JSONP depending on whether callback is present
function respond(obj, callback) {
  const json = JSON.stringify(obj);
  if (callback) {
    return ContentService
      .createTextOutput(callback + '(' + json + ')')
      .setMimeType(ContentService.MimeType.JAVASCRIPT);
  }
  return ContentService
    .createTextOutput(json)
    .setMimeType(ContentService.MimeType.JSON);
}
Scan Configuration

Free key from Google Cloud Console → APIs & Services → Enable YouTube Data API v3 → Credentials → Create API key.

Accepts /@handle, /channel/UCxxx, and /user/name formats. Videos under 3 minutes or tagged #shorts are automatically excluded.

How it works: For each channel, we fetch the last N long-form videos, compute their geometric mean (robust to outliers), then surface every video that beats that baseline — your pool of replicable ideas.
Scanning…
READY
Awaiting targets
Paste your API key and a few channel URLs above, then hit Start Scan to surface every above-average video. Use the tier chips to filter your loot.