# CDP API

## Overview

Scrapeless Scraping Browser extends the standard CDP (Chrome DevTools Protocol) functionality with a series of powerful custom functions to enhance browser automation capabilities. This documentation covers CDP functions for CAPTCHA handling, Signal communication, and Agent operations.

---

## Captcha API

### Overview

Scrapeless Scraping Browser includes advanced CAPTCHA solution capabilities that can automatically handle mainstream CAPTCHA types appearing on web pages.

**Supported CAPTCHA Types:**
- reCaptcha
- Cloudflare Turnstile

### Events

Scraping Browser provides three core events to monitor the CAPTCHA solving process:

| Event Name              | Description           |
|------------------------|----------------------|
| `Captcha.detected`     | CAPTCHA detected     |
| `Captcha.solveFinished`| CAPTCHA solved       |
| `Captcha.solveFailed`  | CAPTCHA solve failed |

**Event Response Data Structure:**

| Field     | Type    | Description                                                              |
|-----------|---------|--------------------------------------------------------------------------|
| `type`    | string  | CAPTCHA type: `recaptcha` `turnstile`                          |
| `success` | boolean | Solution result                                                           |
| `message` | string  | Status message: `"NOT_DETECTED"` `"SOLVE_FINISHED"` `"SOLVE_FAILED"` `"INVALID"` |
| `token?`  | string  | Token returned on success (optional)                                      |

**Implementation Example:**

<Tabs>
  <Tab title="Node.js (Puppeteer)">
```typescript
// Listen for CAPTCHA solving events
const client = await page.createCDPSession();

client.on('Captcha.detected', (result) => {
  console.log('Captcha detected:', result);
});

await new Promise((resolve, reject) => {
  client.on('Captcha.solveFinished', (result) => {
    if (result.success) resolve();
  });
  client.on('Captcha.solveFailed', () =>
    reject(new Error('Captcha solve failed'))
  );
  setTimeout(() =>
      reject(new Error('Captcha solve timeout')),
    5 * 60 * 1000
  );
});
```
  </Tab>
  <Tab title="Python (Playwright)">
```python
page = await browser.contexts[0].new_page()
client = await page.context.new_cdp_session(page)

client.on('Captcha.detected', lambda c: print('Captcha detected:', c))
client.on('Captcha.solveFinished', lambda _: print('Captcha solved!'))
client.on('Captcha.solveFailed', lambda _: print('Captcha failed!'))

```
  </Tab>
</Tabs>

### Methods

| Method | Description |
|--------|-------------|
| `Captcha.setToken` | Set authentication token for CAPTCHA service |
| `Captcha.setConfig` | Configure all CAPTCHA solver parameters |
| `Captcha.solve` | Manually trigger CAPTCHA solving process |

#### `Captcha.setToken`

Set authentication token for CAPTCHA solving service.

<Tabs>
  <Tab title="Node.js (Puppeteer)">
```typescript
await client.send('Captcha.setToken', {
    apiKey: 'your-token'
});
```
  </Tab>
  <Tab title="Python (Playwright)">
```python
await client.send('Captcha.setToken', {
    'apiKey': 'your_token'
})
```
  </Tab>
</Tabs>

#### `Captcha.setConfig`

Configure all parameters for the CAPTCHA solver.

<Tabs>
  <Tab title="Node.js (Puppeteer)">
```typescript
await page.goto('http://example.com')
// It must be set after `page.goto`
await client.send('Captcha.setConfig', {
  config: JSON.stringify({
    autoSolve: true,
    enabledForRecaptcha: true,    // Enable reCAPTCHA solving
    enabledForRecaptchaV3: true,  // Enable reCAPTCHA v3 solving
    enabledForTurnstile: true    // Enable Turnstile solving
  })
});
```
  </Tab>
  <Tab title="Python (Playwright)">
```python
await page.goto('http://example.com')
# It must be set after `page.goto`
await client.send('Captcha.setConfig', {
    'config': json.dumps({
        'autoSolve': True,
        'enabledForRecaptcha': True,
        'enabledForRecaptchaV3': True,
        'enabledForTurnstile': True
    })
})
```
  </Tab>
</Tabs>

#### `Captcha.solve`

Manually trigger CAPTCHA solving process.

<Tabs>
  <Tab title="Node.js (Puppeteer)">
```typescript
const result = await client.send('Captcha.solve', {
    detectTimeout: 10 * 1000,
    options: JSON.stringify([{
        type: 'rcaptcha',
        disabled: true,  // Disable rCaptcha solving
    }])
});
console.log(result);  // { type: 'recaptcha', success: true, message: 'solve_finished', token: 'xxx' }
```
  </Tab>
  <Tab title="Python (Playwright)">
```python
import json

options = [{'type': 'rcaptcha', 'disabled': True}]
result = await client.send('Captcha.solve', {
'detectTimeout': 10_000,
'options': json.dumps(options)
})
print(result)  # { 'type': 'recaptcha', 'success': True, 'message': 'solve_finished', 'token': 'xxx' }
```
  </Tab>
</Tabs>

---

## Signal API

### Overview

Signal API provides bidirectional communication capabilities for browser automation scripts, enabling real-time data exchange and event coordination through CDP protocol.

**Core Capabilities:**
- **Bidirectional Communication**: Send and receive signals through event channels
- **Timeout Control**: Configurable wait timeout (1s ~ 5min)
- **Global Sharing**: All events are globally visible, no session isolation
- **Event Queue**: First-send-then-wait pattern, supports event caching (up to 100 events)

**Response Status Codes:**

| Status Code | Meaning | Scenario |
|-------------|---------|----------|
| 200 | Success | Operation successful or data received |
| 400 | Parameter Error | Parameter validation failed |
| 408 | Timeout | Wait timeout, no data received |
| 500 | Server Error | Internal exception |

### Methods

| Method | Description |
|--------|-------------|
| `Signal.send` | Send data to specified event channel |
| `Signal.wait` | Wait for data from specified event channel |
| `Signal.list` | List pending event names |
| `Signal.stats` | View queue statistics |
| `Signal.clear` | Clear specified or all events |

#### `Signal.send`

Send signal data to a specified event channel.

**CDP Method Call:**

```typescript
await client.send('Signal.send', {
  event: 'string',
  data: {}
});
```

**Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `event` | string | ✅ | Event channel name (1-256 characters) |
| `data` | object | ✅ | Event data payload |

**Usage Examples:**

Example 1: Send MFA verification code
```typescript
await client.send('Signal.send', {
  event: 'mfa_code',
  data: { code: '123456' }
});
```

Example 2: Send CAPTCHA result
```typescript
await client.send('Signal.send', {
  event: 'captcha_result',
  data: {
    solution: 'XKCD',
    token: 'captcha-token-xyz'
  }
});
```

**Response Format:**

Success:
```json
{
  "status": 200
}
```

Error:
```json
{
  "status": 400,
  "error": "event must not be empty"
}
```

#### `Signal.wait`

Wait for signal data from a specified event channel.

**CDP Method Call:**

```typescript
await client.send('Signal.wait', {
  event: 'string',
  timeout: 60000
});
```

**Parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `event` | string | ✅ | - | Event channel name |
| `timeout` | integer | ❌ | 60000 | Timeout in milliseconds (1000-300000) |

**Usage Examples:**

Example 1: Wait for MFA code (default timeout)
```typescript
const result = await client.send('Signal.wait', {
  event: 'mfa_code'
});
```

Example 2: Wait for CAPTCHA (custom timeout 30 seconds)
```typescript
const result = await client.send('Signal.wait', {
  event: 'captcha_result',
  timeout: 30000
});
```

**Response Format:**

Success (data received):
```json
{
  "status": 200,
  "data": { "code": "123456" },
  "event": "mfa_code"
}
```

Timeout (no data received):
```json
{
  "status": 408,
  "data": null,
  "event": "mfa_code"
}
```

Parameter Error:
```json
{
  "status": 400,
  "error": "timeout must be between 1000 and 300000"
}
```

#### `Signal.list`

List pending event names in the queue.

**CDP Method Call:**

```typescript
// List all events
const list = await client.send('Signal.list');
console.log('Pending events:', list.events);
// Output: ["mfa_code", "captcha_result", "order_status"]

// Check if specific event exists
if (list.events.includes('mfa_code')) {
  console.log('MFA code exists in queue');
}
```

**Parameters:**

No parameters required.

**Response Format:**

```json
{
  "status": 200,
  "events": ["mfa_code", "captcha_result", "order_status"]
}
```

**Description:**
- Returns an array of all pending event names
- Deduplicated unique event names
- Sorted by first occurrence time

#### `Signal.stats`

View queue statistics.

**CDP Method Call:**

```typescript
const client = await page.target().createCDPSession();

// Get statistics
const stats = await client.send('Signal.stats');
console.log('Pending events:', stats.events);
console.log('Waiting subscribers:', stats.waiters);

// Check if queue is backlogged
if (stats.events > 50) {
  console.warn('⚠️ Queue backlog is too high!');
}
```

**Response Format:**

```json
{
  "status": 200,
  "events": 12,
  "waiters": 3
}
```

**Field Description:**

| Field | Type | Description |
|-------|------|-------------|
| `status` | integer | Status code (200) |
| `events` | integer | Total number of pending events in queue |
| `waiters` | integer | Number of waiting subscribers |

#### `Signal.clear`

Clear specified or all events.

**CDP Method Call:**

```typescript
// Clear specific event
await client.send('Signal.clear', {
  event: 'mfa_code'
});

// Clear all events
await client.send('Signal.clear');
```

**Parameters:**

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `event` | string | ❌ | Event name, omit to clear all events |

**Usage Examples:**

Clear specific event:
```typescript
await client.send('Signal.clear', {
  event: 'mfa_code'
});
```

Clear all events:
```typescript
await client.send('Signal.clear');
```

**Response Format:**

```json
{
  "status": 200,
  "cleared": 5
}
```

**Field Description:**

| Field | Type | Description |
|-------|------|-------------|
| `status` | integer | Status code (200) |
| `cleared` | integer | Number of events cleared |

---

## Agent API

### Overview

Agent API provides browser automation utilities for simulating user interactions and retrieving page information.

### Methods

| Method | Description |
|--------|-------------|
| `Agent.click` | Simulate a mouse click |
| `Agent.liveURL` | Get live URL of current session page |

#### `Agent.click`

Simulates a mouse click.

<Tabs>
  <Tab title="Node.js (Puppeteer)">
```typescript
await client.send('Agent.click', {
 selector: 'button',
});
```
  </Tab>
  <Tab title="Python (Playwright)">
```python
await client.send('Agent.click', {
 'selector': 'button',
})
```
  </Tab>
</Tabs>

#### `Agent.liveURL`

Get live URL of current session page.

<Tabs>
  <Tab title="Node.js (Puppeteer)">
```typescript
await page.goto("https://www.scrapeless.com", {
    waitUntil: "networkidle0",
    timeout: 30000,
});

const client = await page.createCDPSession();
const result = await client.send("Agent.liveURL");
console.log(result);
```
  </Tab>
  <Tab title="Python (Playwright)">
```python
await page.goto("https://www.scrapeless.com", timeout=60000, wait_until="load")

client = await page.target.createCDPSession()
result = await client.send('Agent.liveURL')
print(result)
```
  </Tab>
</Tabs>

