🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Functions

by @peytoncasper

Guide Claude through deploying serverless browser automation using the official bb CLI

Versionv1.0.0
Downloads1,998
Installs1
TERMINAL
clawhub install functions

πŸ“– About This Skill


name: functions description: Guide Claude through deploying serverless browser automation using the official bb CLI

Browserbase Functions Skill

Guide Claude through deploying serverless browser automation using the official bb CLI.

When to Use

Use this skill when:

  • User wants to deploy automation to run on a schedule
  • User needs a webhook endpoint for browser automation
  • User wants to run automation in the cloud (not locally)
  • User asks about Browserbase Functions
  • Prerequisites

    1. Get Credentials

    Get API key and Project ID from: https://browserbase.com/settings

    2. Set Environment Variables

    Set directly:

    export BROWSERBASE_API_KEY="your_api_key"
    export BROWSERBASE_PROJECT_ID="your_project_id"
    

    Creating a Function Project

    1. Initialize with Official CLI

    pnpm dlx @browserbasehq/sdk-functions init my-function
    cd my-function
    

    This creates:

    my-function/
    β”œβ”€β”€ package.json
    β”œβ”€β”€ index.ts        # Your function code
    └── .env            # Add credentials here
    

    2. Add Credentials to .env

    # Copy from stored credentials
    echo "BROWSERBASE_API_KEY=$BROWSERBASE_API_KEY" >> .env
    echo "BROWSERBASE_PROJECT_ID=$BROWSERBASE_PROJECT_ID" >> .env
    

    Or manually edit .env:

    BROWSERBASE_API_KEY=your_api_key
    BROWSERBASE_PROJECT_ID=your_project_id
    

    3. Install Dependencies

    pnpm install
    

    Function Structure

    import { defineFn } from "@browserbasehq/sdk-functions";
    import { chromium } from "playwright-core";

    defineFn("my-function", async (context) => { const { session, params } = context; // Connect to browser const browser = await chromium.connectOverCDP(session.connectUrl); const page = browser.contexts()[0]!.pages()[0]!; // Your automation await page.goto(params.url || "https://example.com"); const title = await page.title(); // Return JSON-serializable result return { success: true, title }; });

    Key objects:

  • context.session.connectUrl - CDP endpoint to connect Playwright
  • context.params - Input parameters from invocation
  • Development Workflow

    1. Start Dev Server

    pnpm bb dev index.ts
    

    Server runs at http://127.0.0.1:14113

    2. Test Locally

    curl -X POST http://127.0.0.1:14113/v1/functions/my-function/invoke \
      -H "Content-Type: application/json" \
      -d '{"params": {"url": "https://news.ycombinator.com"}}'
    

    3. Iterate

    The dev server auto-reloads on file changes. Use console.log() for debugging - output appears in the terminal.

    Deploying

    Publish to Browserbase

    pnpm bb publish index.ts
    

    Output:

    Function published successfully
    Build ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    Function ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    

    Save the Function ID - you need it to invoke.

    Invoking Deployed Functions

    Via curl

    # Start invocation
    curl -X POST "https://api.browserbase.com/v1/functions/FUNCTION_ID/invoke" \
      -H "Content-Type: application/json" \
      -H "x-bb-api-key: $BROWSERBASE_API_KEY" \
      -d '{"params": {"url": "https://example.com"}}'

    Response: {"id": "INVOCATION_ID"}

    Poll for result

    curl "https://api.browserbase.com/v1/functions/invocations/INVOCATION_ID" \ -H "x-bb-api-key: $BROWSERBASE_API_KEY"

    Via Code

    async function invokeFunction(functionId: string, params: object) {
      // Start invocation
      const invokeRes = await fetch(
        https://api.browserbase.com/v1/functions/${functionId}/invoke,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'x-bb-api-key': process.env.BROWSERBASE_API_KEY!,
          },
          body: JSON.stringify({ params }),
        }
      );
      const { id: invocationId } = await invokeRes.json();

    // Poll until complete while (true) { await new Promise(r => setTimeout(r, 5000)); const statusRes = await fetch( https://api.browserbase.com/v1/functions/invocations/${invocationId}, { headers: { 'x-bb-api-key': process.env.BROWSERBASE_API_KEY! } } ); const result = await statusRes.json(); if (result.status === 'COMPLETED') return result.results; if (result.status === 'FAILED') throw new Error(result.error); } }

    Common Patterns

    Parameterized Scraping

    defineFn("scrape", async ({ session, params }) => {
      const browser = await chromium.connectOverCDP(session.connectUrl);
      const page = browser.contexts()[0]!.pages()[0]!;
      
      await page.goto(params.url);
      await page.waitForSelector(params.selector);
      
      const items = await page.$$eval(params.selector, els => 
        els.map(el => el.textContent?.trim())
      );
      
      return { url: params.url, items };
    });
    

    With Authentication

    defineFn("authenticated-action", async ({ session, params }) => {
      const browser = await chromium.connectOverCDP(session.connectUrl);
      const page = browser.contexts()[0]!.pages()[0]!;
      
      // Login
      await page.goto("https://example.com/login");
      await page.fill('[name="email"]', params.email);
      await page.fill('[name="password"]', params.password);
      await page.click('button[type="submit"]');
      await page.waitForURL('**/dashboard');
      
      // Do authenticated work
      const data = await page.textContent('.user-data');
      return { data };
    });
    

    Error Handling

    defineFn("safe-scrape", async ({ session, params }) => {
      const browser = await chromium.connectOverCDP(session.connectUrl);
      const page = browser.contexts()[0]!.pages()[0]!;
      
      try {
        await page.goto(params.url, { timeout: 30000 });
        await page.waitForSelector(params.selector, { timeout: 10000 });
        
        const data = await page.textContent(params.selector);
        return { success: true, data };
      } catch (error) {
        return { 
          success: false, 
          error: error instanceof Error ? error.message : 'Unknown error' 
        };
      }
    });
    

    CLI Reference

    | Command | Description | |---------|-------------| | pnpm dlx @browserbasehq/sdk-functions init | Create new project | | pnpm bb dev | Start local dev server | | pnpm bb publish | Deploy to Browserbase |

    Troubleshooting

    "Missing API key"

    # Check .env file has credentials
    cat .env

    Or set for current shell

    export BROWSERBASE_API_KEY="your_key" export BROWSERBASE_PROJECT_ID="your_project"

    Dev server won't start

    # Make sure SDK is installed
    pnpm add @browserbasehq/sdk-functions

    Or use npx

    npx @browserbasehq/sdk-functions dev index.ts

    Function times out

  • Max execution time is 15 minutes
  • Add specific timeouts to page operations
  • Use waitForSelector instead of sleep
  • Can't connect to browser

  • Check session.connectUrl is being used correctly
  • Ensure you're using chromium.connectOverCDP() not chromium.launch()
  • ⚑ When to Use

    TriggerAction
    - User wants to deploy automation to run on a schedule
    - User needs a webhook endpoint for browser automation
    - User wants to run automation in the cloud (not locally)
    - User asks about Browserbase Functions

    βš™οΈ Configuration

    1. Get Credentials

    Get API key and Project ID from: https://browserbase.com/settings

    2. Set Environment Variables

    Set directly:

    export BROWSERBASE_API_KEY="your_api_key"
    export BROWSERBASE_PROJECT_ID="your_project_id"
    

    πŸ“‹ Tips & Best Practices

    "Missing API key"

    # Check .env file has credentials
    cat .env

    Or set for current shell

    export BROWSERBASE_API_KEY="your_key" export BROWSERBASE_PROJECT_ID="your_project"

    Dev server won't start

    # Make sure SDK is installed
    pnpm add @browserbasehq/sdk-functions

    Or use npx

    npx @browserbasehq/sdk-functions dev index.ts

    Function times out

  • Max execution time is 15 minutes
  • Add specific timeouts to page operations
  • Use waitForSelector instead of sleep
  • Can't connect to browser

  • Check session.connectUrl is being used correctly
  • Ensure you're using chromium.connectOverCDP() not chromium.launch()