返回技能库

Fireflies.ai

Fireflies.ai 的 GraphQL API 集成,使用托管的 OAuth。可访问会议记录、摘要、用户、联系人,以及 AI 驱动的会议分析。 当用户想要检索会议记录、搜索对话、使用 AskFred 分析会议内容,或管理会议录音时使用此技能。 对于其他第三方应用,请使用 api-gateway 技能 (https://clawhub.ai/byungkyu/api-gateway)。 需要网络访问和有效的 Maton API 密钥。

作者:byungkyu · 最新版本:1.0.0

收藏:2 · 下载:1.6k

说明文档

# Fireflies

Access the Fireflies.ai GraphQL API with managed OAuth authentication. Retrieve meeting transcripts, summaries, users, contacts, channels, and use AI-powered meeting analysis with AskFred.

## Quick Start

```bash
# Get current user
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': '{ user { user_id name email is_admin } }'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/fireflies/graphql', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

## Base URL

```
https://gateway.maton.ai/fireflies/graphql
```

All requests are sent to a single GraphQL endpoint. The gateway proxies requests to `api.fireflies.ai/graphql` and automatically injects your OAuth token.

## Authentication

All requests require the Maton API key in the Authorization header:

```
Authorization: Bearer $MATON_API_KEY
```

**Environment Variable:** Set your API key as `MATON_API_KEY`:

```bash
export MATON_API_KEY="YOUR_API_KEY"
```

### Getting Your API Key

1. Sign in or create an account at [maton.ai](https://maton.ai)
2. Go to [maton.ai/settings](https://maton.ai/settings)
3. Copy your API key

## Connection Management

Manage your Fireflies OAuth connections at `https://ctrl.maton.ai`.

### List Connections

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=fireflies&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Create Connection

```bash
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'fireflies'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Get Connection

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

**Response:**
```json
{
  "connection": {
    "connection_id": "a221f04a-6842-4254-ae9a-424bb63ad745",
    "status": "ACTIVE",
    "creation_time": "2026-02-11T00:45:25.802991Z",
    "last_updated_time": "2026-02-11T00:46:04.771700Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "fireflies",
    "metadata": {}
  }
}
```

Open the returned `url` in a browser to complete OAuth authorization.

### Delete Connection

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Specifying Connection

If you have multiple Fireflies connections, specify which one to use with the `Maton-Connection` header:

```bash
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': '{ user { user_id name email } }'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/fireflies/graphql', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Maton-Connection', 'a221f04a-6842-4254-ae9a-424bb63ad745')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

If omitted, the gateway uses the default (oldest) active connection.

## GraphQL API

Fireflies uses GraphQL, which means all requests are POST requests to a single `/graphql` endpoint with a JSON body containing the query.

### Request Format

```bash
POST /fireflies/graphql
Content-Type: application/json

{
  "query": "{ ... }",
  "variables": { ... }
}
```

---

## Queries

### Get Current User

```graphql
{
  user {
    user_id
    name
    email
    is_admin
    num_transcripts
    minutes_consumed
    recent_transcript
    recent_meeting
  }
}
```

**Response:**
```json
{
  "data": {
    "user": {
      "user_id": "01KH5131Z0W4TS7BBSEP66CV6V",
      "name": "John Doe",
      "email": "john@example.com",
      "is_admin": true,
      "num_transcripts": null,
      "minutes_consumed": 0
    }
  }
}
```

### List Users

```graphql
{
  users {
    user_id
    name
    email
    is_admin
    num_transcripts
    minutes_consumed
  }
}
```

### List Transcripts

```graphql
{
  transcripts {
    id
    title
    date
    duration
    host_email
    organizer_email
    privacy
    transcript_url
    audio_url
    video_url
    dateString
    calendar_type
    meeting_link
  }
}
```

**With Variables (filtering):**

```json
{
  "query": "query($limit: Int, $skip: Int) { transcripts(limit: $limit, skip: $skip) { id title date duration } }",
  "variables": {
    "limit": 10,
    "skip": 0
  }
}
```

### Get Transcript by ID

```graphql
query($id: String!) {
  transcript(id: $id) {
    id
    title
    date
    duration
    host_email
    privacy
    transcript_url
    audio_url
    summary {
      overview
      short_summary
      action_items
      outline
      keywords
      meeting_type
    }
    sentences {
      text
      speaker_name
      start_time
      end_time
    }
    participants
    speakers {
      name
    }
  }
}
```

### List Channels

```graphql
{
  channels {
    id
    title
    created_at
    updated_at
    is_private
    created_by
  }
}
```

### Get Channel by ID

```graphql
query($id: String!) {
  channel(id: $id) {
    id
    title
    created_at
    is_private
    members
  }
}
```

### List Contacts

```graphql
{
  contacts {
    email
    name
    picture
    last_meeting_date
  }
}
```

### List User Groups

```graphql
{
  user_groups {
    id
    name
  }
}
```

### List Bites (Soundbites)

```graphql
{
  bites {
    id
    name
    transcript_id
    thumbnail
    preview
    status
    summary
    start_time
    end_time
    media_type
    created_at
  }
}
```

### Get Bite by ID

```graphql
query($id: String!) {
  bite(id: $id) {
    id
    name
    transcript_id
    summary
    start_time
    end_time
    captions
  }
}
```

### List Active Meetings

```graphql
{
  active_meetings {
    id
    title
    date
  }
}
```

### AskFred Threads

Query meeting content using AI.

**List Threads:**
```graphql
{
  askfred_threads {
    id
    title
    created_at
  }
}
```

**Get Thread by ID:**
```graphql
query($id: String!) {
  askfred_thread(id: $id) {
    id
    title
    messages {
      content
      role
    }
  }
}
```

---

## Mutations

### Upload Audio

```graphql
mutation($input: AudioUploadInput!) {
  uploadAudio(input: $input) {
    success
    title
    message
  }
}
```

**Variables:**
```json
{
  "input": {
    "url": "https://example.com/audio.mp3",
    "title": "Meeting Recording"
  }
}
```

### Delete Transcript

```graphql
mutation($id: String!) {
  deleteTranscript(id: $id) {
    success
    message
  }
}
```

### Update Meeting Title

```graphql
mutation($id: String!, $title: String!) {
  updateMeetingTitle(id: $id, title: $title) {
    success
  }
}
```

### Update Meeting Privacy

```graphql
mutation($id: String!, $privacy: String!) {
  updateMeetingPrivacy(id: $id, privacy: $privacy) {
    success
  }
}
```

### Update Meeting Channel

```graphql
mutation($id: String!, $channelId: String!) {
  updateMeetingChannel(id: $id, channelId: $channelId) {
    success
  }
}
```

### Set User Role

```graphql
mutation($userId: String!, $role: String!) {
  setUserRole(userId: $userId, role: $role) {
    success
  }
}
```

### Create Bite

```graphql
mutation($input: CreateBiteInput!) {
  createBite(input: $input) {
    id
    name
  }
}
```

### AskFred Mutations

**Create Thread:**
```graphql
mutation($input: CreateAskFredThreadInput!) {
  createAskFredThread(input: $input) {
    id
    title
  }
}
```

**Continue Thread:**
```graphql
mutation($id: String!, $question: String!) {
  continueAskFredThread(id: $id, question: $question) {
    id
    messages {
      content
      role
    }
  }
}
```

**Delete Thread:**
```graphql
mutation($id: String!) {
  deleteAskFredThread(id: $id) {
    success
  }
}
```

### Live Meeting Mutations

**Update Meeting State (pause/resume):**
```graphql
mutation($id: String!, $state: String!) {
  updateMeetingState(id: $id, state: $state) {
    success
  }
}
```

**Create Live Action Item:**
```graphql
mutation($meetingId: String!, $text: String!) {
  createLiveActionItem(meetingId: $meetingId, text: $text) {
    success
  }
}
```

**Create Live Soundbite:**
```graphql
mutation($meetingId: String!, $name: String!) {
  createLiveSoundbite(meetingId: $meetingId, name: $name) {
    success
  }
}
```

**Add Bot to Live Meeting:**
```graphql
mutation($meetingLink: String!) {
  addToLiveMeeting(meetingLink: $meetingLink) {
    success
  }
}
```

---

## Code Examples

### JavaScript

```javascript
const query = `{
  user {
    user_id
    name
    email
  }
}`;

const response = await fetch(
  'https://gateway.maton.ai/fireflies/graphql',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ query })
  }
);
const data = await response.json();
console.log(data.data.user);
```

### Python

```python
import os
import requests

query = '''
{
  transcripts {
    id
    title
    date
    duration
  }
}
'''

response = requests.post(
    'https://gateway.maton.ai/fireflies/graphql',
    headers={
        'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
        'Content-Type': 'application/json'
    },
    json={'query': query}
)
data = response.json()
for transcript in data['data']['transcripts']:
    print(f"{transcript['title']}: {transcript['duration']}s")
```

## Notes

- Fireflies uses GraphQL, not REST - all requests are POST to `/graphql`
- User IDs are ULIDs (e.g., `01KH5131Z0W4TS7BBSEP66CV6V`)
- Timestamps are Unix timestamps (milliseconds)
- The `summary` field on transcripts contains AI-generated content: overview, action_items, outline, keywords
- AskFred allows natural language queries across meeting transcripts
- Rate limits: 50 API calls/day on free plan, more on Business plan
- IMPORTANT: All GraphQL queries and mutations must be sent as POST requests with Content-Type: application/json
- IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments

## Error Handling

| Status | Meaning |
|--------|---------|
| 400 | Invalid GraphQL query or missing connection |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions |
| 429 | Rate limited |
| 500 | Internal server error |

**GraphQL Errors:**
```json
{
  "errors": [
    {
      "message": "Cannot query field \"id\" on type \"User\".",
      "code": "GRAPHQL_VALIDATION_FAILED"
    }
  ]
}
```

### Troubleshooting: API Key Issues

1. Check that the `MATON_API_KEY` environment variable is set:

```bash
echo $MATON_API_KEY
```

2. Verify the API key is valid by listing connections:

```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```

### Troubleshooting: Invalid App Name

1. Ensure your URL path starts with `fireflies`. For example:

- Correct: `https://gateway.maton.ai/fireflies/graphql`
- Incorrect: `https://gateway.maton.ai/gr...