DEV Community

Cover image for Track YC Launches on Autopilot: Apps Script + Gemini 3.6 Flash
ASKAR AITUOV for Tengri

Posted on

Track YC Launches on Autopilot: Apps Script + Gemini 3.6 Flash

Note: While preparing this tutorial, we intended to use the legacy generateContent endpoint. Because Google shifted to the unified Interactions API, check updated endpoints here: [Interactions API Overview].

For builders, product managers, and investors, tracking newly launched startups is critical for competitive intelligence, finding breakout developer tools, and monitoring seed-stage venture trends. But checking launch boards manually every day is tedious.

In my work mapping developer ecosystems and driving DevRel initiatives at BCC Hub in Almaty, Kazakhstan, I constantly look for ways to streamline data collection without accumulating infrastructure bloat. In this tutorial, we will build a daily automated pipeline in Google Apps Script that scrapes the official Y Combinator Launches feed, passes the content to Gemini 3.6 Flash, and writes structured deal flow directly into Google Sheets.

Why Token Economics Matter Here
Scraping dynamic feed pages often loads noisy markup, sidebars, and navigation headers. If you pump raw 100 KB HTML documents into an expensive model, you blow through your monthly budget on useless boilerplate.

We solve this with two best practices:
Pre-processing in JavaScript: Strip <script>, <style>, and raw markup before sending the payload, shrinking token consumption by over 70%.

Gemini Flash Free Tier: Fast inference, robust context handling, and generous zero-cost limits through Google AI Studio. As demonstrated in the companion video tutorial, if you ever experience high demand on the latest models (like 3.7 Flash), you can easily dial the endpoint back to 3.6 Flash to keep your automated pipelines running smoothly.

Setting Up Your Google Sheet
Set up Row 1 of your spreadsheet with these column headers and freeze the row (View > Freeze > 1 row):
Column A: Timestamp
Column B: Company Name
Column C: One-Sentence Pitch
Column D: Category
Column E: AI-Native?

How the Pipeline Works

  1. Secure Key Management with PropertiesService Instead of hardcoding API keys where they might leak in GitHub commits or screen recordings, we fetch credentials dynamically from Apps Script's encrypted storage:
const apiKey = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
Enter fullscreen mode Exit fullscreen mode

2. Feed Scraping & Text Sanitization
UrlFetchApp.fetch() queries [https://www.ycombinator.com/launches](https://www.ycombinator.com/launches). Regex removes embedded JavaScript, CSS styles, and raw HTML tags, leaving a clean text stream of startup announcements.

3. Structured Output Extraction
We instruct Gemini to act as a venture intelligence analyst and enforce JSON output:

const prompt = `Analyze this raw text from Y Combinator's launches page. Extract the latest 3 to 5 featured startup launches from the past 30 days.
Return ONLY a valid JSON array of objects with the following keys:
- "name": Company name
- "pitch": One-sentence value proposition
- "category": Target domain/industry
- "isAiNative": "Yes" or "No"`;
Enter fullscreen mode Exit fullscreen mode

4. Automated Row Insertion
The script parses the returned JSON array and appends one clean row per startup to your Google Sheet.

Step-by-Step Setup

  1. Open your Google Sheet and navigate to Extensions > Apps Script.
  2. Click the Gear icon (Project Settings) in the left sidebar.
  3. Under Script Properties, add a property named GEMINI_API_KEY and paste your key from Google AI Studio.
  4. Replace the editor code with scraper.js (below) and click Save.
  5. Click Run once to authorize permissions for URL fetching and Sheet modifications.
  6. Click the Triggers (clock icon) tab, click + Add Trigger, select trackYCLaunchesDaily, set the event source to Time-driven (Day timer), and select your preferred execution window (e.g., every 12 hours).

Your spreadsheet will now build an automated database of every startup coming out of Y Combinator without manual maintenance or ongoing infrastructure fees. You can even modify the prompt to scrape completely different sites like Forbes or TechCrunch!


/**
 * Daily YC Launch Tracker with Apps Script & Gemini
 * Scrapes Y Combinator's launch feed, extracts top recent launches,
 * and logs structured company intelligence directly into Google Sheets.
 */
function trackYCLaunchesDaily() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const url = "https://www.ycombinator.com/launches";
  const apiKey = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');

  if (!apiKey) {
    throw new Error("GEMINI_API_KEY not found in Script Properties.");
  }

  try {
    // 1. Fetch YC Launches HTML
    const response = UrlFetchApp.fetch(url, {
      headers: { "User-Agent": "Mozilla/5.0 (compatible; AppsScriptYCScraper/1.0)" }
    });
    const html = response.getContentText();

    // 2. Light cleanup to strip script/style tags and compress text for token efficiency
    const cleanHtml = html
      .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
      .replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, '')
      .replace(/<[^>]+>/g, ' ')
      .replace(/\s+/g, ' ');

    const pageSnippet = cleanHtml.substring(0, 8000);

    // 3. Call Gemini Interactions API with structured JSON output request
    const geminiUrl = `https://generativelanguage.googleapis.com/v1beta/interactions?key=${apiKey}`;
    const prompt = `Analyze this raw text from Y Combinator's launches page. Extract the latest 3 to 5 featured startup launches from the past 30 days.
    Return ONLY a valid JSON array of objects with the following keys:
    - "name": Company name
    - "pitch": One-sentence value proposition
    - "category": Target domain/industry (e.g., Developer Tools, Fintech, Healthcare, B2B SaaS)
    - "isAiNative": "Yes" or "No"

    Raw Text:
    ${pageSnippet}`;

    const payload = {
      "model": "gemini-3.6-flash", // Adjusted to 3.6 for high-demand reliability 
      "input": prompt,
      "response_mime_type": "application/json"
    };

    const options = {
      'method': 'post',
      'contentType': 'application/json',
      'payload': JSON.stringify(payload),
      'muteHttpExceptions': true
    };

    const geminiResponse = UrlFetchApp.fetch(geminiUrl, options);
    const data = JSON.parse(geminiResponse.getContentText());

    if (data.error) {
      sheet.appendRow([new Date(), "API Error", data.error.message, "", ""]);
      return;
    }

    const outputText = data.output_text || (data.candidates && data.candidates[0]?.content?.parts[0]?.text);
    if (!outputText) {
      sheet.appendRow([new Date(), "Parse Error", "No output returned from Gemini", "", ""]);
      return;
    }

    // 4. Parse the AI-generated JSON and append each company as a row
    const cleanJson = outputText.replace(/```
{% endraw %}
json|
{% raw %}
```/g, '').trim();
    const startups = JSON.parse(cleanJson);

    const timestamp = new Date();
    startups.forEach(startup => {
      sheet.appendRow([
        timestamp,
        startup.name || "N/A",
        startup.pitch || "N/A",
        startup.category || "N/A",
        startup.isAiNative || "N/A"
      ]);
    });

  } catch (error) {
    sheet.appendRow([new Date(), "Execution Error", error.message, "", ""]);
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)