Skip to content

zynorex/capturecraft-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CaptureCraft Figma API

A production-ready Go backend for integrating Figma designs with CaptureCraft. Includes a complete REST API server, SQLite database layer, rate limiting, webhook processing, and real-time synchronization.

🚀 What's New

Production-Ready Backend Infrastructure:

  • ✅ REST API Server with 20+ endpoints
  • ✅ SQLite Database with auto-migration
  • ✅ Rate Limiting (token bucket algorithm)
  • ✅ Webhook Processing & File Sync
  • ✅ Structured Logging with Context Support
  • ✅ OAuth 2.0 Token Management
  • ✅ Comprehensive Documentation & Examples
  • ✅ Docker & docker-compose Setup
  • ✅ Hot-reload Development Mode
  • ✅ Ready for Kubernetes Deployment

📚 Documentation

✨ Features

REST API Server

  • 20+ Endpoints covering all Figma operations
  • Authentication - Bearer token & OAuth 2.0
  • Health Checks - Liveness and readiness probes
  • Consistent Responses - Standardized JSON format
  • Error Handling - Typed errors with HTTP status codes

Database Layer

  • SQLite - Lightweight, embedded database
  • Auto-migration - Schema created on startup
  • Connection Pooling - Configurable pool size
  • 8 Data Models - OAuth tokens, webhooks, exports, metadata, sync jobs, logs

Rate Limiting

  • Token Bucket - Configurable RPM limits
  • Per-user Tracking - Individual user rate limits
  • Exponential Backoff - Retry logic with max wait time
  • Circuit Breaker - Graceful degradation on failures

Webhook Processing

  • Background Service - Processes events in batches
  • Event Types - FILE_UPDATE, FILE_DELETE, LIBRARY_PUBLISH
  • Automatic Caching - Stores file and component data
  • Configurable Intervals - Tune sync frequency

Developer Experience

  • Hot-reload - Automatic restart on code changes (air)
  • Structured Logging - Context-aware logging with multiple levels
  • Docker Compose - One-command local development
  • SQLite Browser - Visual database inspection at :8080
  • Make Targets - Common tasks (build, test, run, lint)

🏃 Quick Start

Development (Docker)

# Start all services with docker-compose
docker-compose up

# API: http://localhost:3000
# Dev API (hot-reload): http://localhost:3001
# SQLite Browser: http://localhost:8080

Development (Direct)

# Setup
go mod download
cp .env.example .env

# Run with hot-reload
make dev-server

# API: http://localhost:3000

Test the API

# Health check
curl http://localhost:3000/health

# Get file with authentication
curl http://localhost:3000/api/files/{fileKey} \
  -H "Authorization: Bearer $FIGMA_ACCESS_TOKEN"

See QUICKSTART.md for complete getting started guide.

📡 API Endpoints

Health & Status

  • GET /health - Server health check
  • GET /status - Detailed server status

Authentication

  • GET /auth/callback - OAuth 2.0 callback handler

Files

  • GET /api/files - List all accessible files
  • GET /api/files/{fileKey} - Get file details
  • GET /api/files/{fileKey}/versions - Get version history
  • GET /api/files/{fileKey}/components - Get all components

Exports

  • GET /api/exports/node - Export single node
  • POST /api/exports/batch - Batch export multiple nodes

Components

  • GET /api/components/search - Search components across files

Webhooks

  • GET /api/webhooks - List active webhooks
  • POST /api/webhooks - Create webhook
  • POST /api/webhooks/event - Process webhook event (internal)

Sync & Cache

  • GET /api/sync/file - Manually sync file
  • GET /api/sync/status - Get sync service status
  • GET /api/cache/clear - Clear local cache

See API.md for complete endpoint documentation with examples.

🛠 Architecture

┌─────────────────────────────┐
│   CaptureCraft Web UI       │
│  (React/Vue/Angular etc)    │
└──────────────┬──────────────┘
               │ HTTP/REST
               │
┌──────────────▼──────────────┐
│  Figma API Server (Go)      │
│  - REST API                 │
│  - Rate Limiting            │
│  - Webhook Processing       │
│  - Sync Service             │
└──────────────┬──────────────┘
         ┌─────┴─────┐
         │           │
    ┌────▼───┐  ┌───▼─────────────┐
    │ Figma  │  │ SQLite Database │
    │  API   │  │ - Tokens        │
    │        │  │ - Webhooks      │
    └────────┘  │ - Cache         │
                │ - Metadata      │
                └─────────────────┘

📦 Project Structure

capturecrafy-api/
├── Core Components
│   ├── main.go              # Application entry point
│   ├── server.go            # REST API server (900 lines, 20+ endpoints)
│   ├── db.go                # SQLite database layer (~560 lines)
│   ├── models.go            # Database models (9 structs)
│   ├── figma-api-client.go  # Figma API client (OAuth, files, exports, webhooks)
│
├── Infrastructure
│   ├── config.go            # Environment configuration
│   ├── logger.go            # Structured logging
│   ├── errors.go            # Custom error types
│   ├── ratelimit.go         # Rate limiting + retry + circuit breaker
│   ├── sync.go              # Webhook processor + sync service
│   ├── utils.go             # Helper utilities
│
├── DevOps & Build
│   ├── Dockerfile           # Multi-stage Docker build
│   ├── docker-compose.yml   # Local dev + prod services
│   ├── .air.toml           # Hot-reload configuration
│   ├── Makefile            # Build automation
│   ├── .env.example        # Configuration template
│   ├── go.mod/go.sum       # Dependencies
│
├── Documentation
│   ├── README.md            # This file
│   ├── QUICKSTART.md        # 5-minute setup guide
│   ├── API.md               # REST API reference (50+ examples)
│   ├── DEPLOYMENT.md        # Production deployment guide
│   ├── INTEGRATION.md       # Frontend integration guide
│   ├── OPTIMIZATION.md      # Performance tuning guide
│
└── Tests
    ├── main_test.go         # Integration tests
    ├── db_test.go           # Database tests
    ├── server_test.go       # API endpoint tests
    └── ...

🔧 Configuration

All configuration via environment variables (no config files needed):

# Server
SERVER_PORT=3000
SERVER_HOST=0.0.0.0
SERVER_READ_TIMEOUT=30s
SERVER_WRITE_TIMEOUT=30s

# Figma API
FIGMA_CLIENT_ID=your_client_id
FIGMA_CLIENT_SECRET=your_client_secret
FIGMA_REDIRECT_URI=http://localhost:3000/auth/callback
FIGMA_ACCESS_TOKEN=optional_personal_token

# Database
DATABASE_DSN=/app/data/capturecrafy.db
DATABASE_MAX_OPEN_CONNS=25
DATABASE_MAX_IDLE_CONNS=5
DATABASE_CONN_MAX_LIFETIME=5m

# Rate Limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_RPM=600
RATE_LIMIT_WINDOW=1m

# Logging
LOG_LEVEL=info
LOG_FORMAT=text

# Sync Service
SYNC_ENABLED=true
SYNC_BATCH_SIZE=50
SYNC_INTERVAL=30s
SYNC_MAX_RETRIES=3

# Webhooks
WEBHOOK_SECRET=optional_secret

See .env.example for all available options.

🚢 Deployment

Docker (Simplest)

docker build -t capturecrafy-api:latest .
docker run -d -p 3000:3000 \
  -e FIGMA_ACCESS_TOKEN=your_token \
  capturecrafy-api:latest

Kubernetes

kubectl apply -f k8s/deployment.yaml

Docker Swarm

docker service create --name figma-api \
  -p 3000:3000 \
  -e FIGMA_ACCESS_TOKEN=your_token \
  capturecrafy-api:latest

Traditional VM/Bare Metal

# Build
go build -o figma-api main.go

# Run with systemd
sudo cp figma-api /usr/local/bin/
sudo tee /etc/systemd/system/figma-api.service > /dev/null <<EOF
[Unit]
Description=Figma API Server
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/figma-api
Restart=always
Environment="FIGMA_ACCESS_TOKEN=your_token"
EOF

# Enable and start
sudo systemctl enable figma-api
sudo systemctl start figma-api

See DEPLOYMENT.md for comprehensive deployment guide.

🧪 Testing

# Run all tests
make test

# Run with coverage report
make coverage

# Run specific test
go test -run TestGetFile -v

# Run benchmarks
make bench

# Load test with Apache Bench
ab -n 1000 -c 100 http://localhost:3000/health

📊 Performance

Benchmarks (on MacBook Pro M1, 16GB RAM):

Operation Latency Memory
GET /health < 1ms < 0.1MB
GET /api/files/:key 45-60ms 2-3MB
GET /api/components/search 80-120ms 3-5MB
POST /api/exports/batch 60-100ms 5-8MB
Rate limit check 0.5-1ms < 0.05MB

See OPTIMIZATION.md for detailed performance analysis and tuning guide.

🔒 Security

  • ✅ OAuth 2.0 for user authentication
  • ✅ Rate limiting to prevent abuse
  • ✅ HTTPS support (via reverse proxy/load balancer)
  • ✅ Input validation on all endpoints
  • ✅ SQL injection prevention (parameterized queries)
  • ✅ CORS configuration per environment
  • ✅ API key rotation support
  • ✅ Encrypted token storage in database

📝 Go Client Library

The project also includes a comprehensive Go client library for direct Figma API integration.

Installation

go get github.com/zynorex/capturecrafy-api

Basic Usage

config := &FigmaConfig{
    ClientID:     "YOUR_CLIENT_ID",
    ClientSecret: "YOUR_CLIENT_SECRET",
    RedirectURI:  "http://localhost:3000/auth/callback",
}

client, err := NewFigmaClient(config)
if err != nil {
    log.Fatal(err)
}

ctx := context.Background()

// Get a file
file, err := client.GetFile(ctx, "fileKey")
if err != nil {
    log.Fatal(err)
}

fmt.Println(file.Name)

See Library section below for complete client documentation.

📚 Library Documentation

A comprehensive Go client for the Figma API, designed to communicate with the CaptureCraft application. This library provides full support for file access, component management, design exports, real-time webhooks, and more.

1. OAuth Setup

config := &FigmaConfig{
    ClientID:     "YOUR_CLIENT_ID",
    ClientSecret: "YOUR_CLIENT_SECRET",
    RedirectURI:  "http://localhost:3000/auth/callback",
}

client, err := NewFigmaClient(config)
if err != nil {
    log.Fatal(err)
}

// Get authorization URL
authURL := client.GetAuthURL("random-state")
// Direct user to authURL...

// After user authorizes, exchange code for token
token, err := client.ExchangeCodeForToken(context.Background(), code)

2. File Access

ctx := context.Background()

// Get a file
file, err := client.GetFile(ctx, "fileKey")
if err != nil {
    log.Fatal(err)
}

fmt.Println(file.Name)
fmt.Println(file.Document)

3. Component Management

// Get all components in a file
components, err := client.GetFileComponents(ctx, "fileKey")
if err != nil {
    log.Fatal(err)
}

for key, component := range components {
    fmt.Printf("%s: %s\n", key, component.Name)
}

4. Design Export

// Export as PNG
pngURL, err := client.ExportPNG(ctx, "fileKey", "nodeID")
if err != nil {
    log.Fatal(err)
}

// Export as SVG
svgURL, err := client.ExportSVG(ctx, "fileKey", "nodeID")

// Export with custom scale
imageURL, err := client.GetNodeAsImageURL(ctx, "fileKey", "nodeID", ExportFormatPNG, 2.0)

5. Webhooks

// Create a webhook
webhook, err := client.CreateWebhook(ctx, "teamID", 
    "https://yourapp.com/webhook", "FILE_UPDATE", "Listen for changes")
if err != nil {
    log.Fatal(err)
}

// In your webhook handler
http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
    HandleWebhookRequest(r, "webhookSecret", func(event *WebhookEvent, err error) {
        if err != nil {
            http.Error(w, "Invalid webhook", http.StatusBadRequest)
            return
        }
        
        // Process file update event
        if event.Event == "FILE_UPDATE" {
            fmt.Printf("File %s was updated at %d\n", 
                event.FileID, event.Timestamp)
        }
    })
})

API Documentation

Client Methods

Authentication

  • GetAuthURL(state string) string - Get OAuth authorization URL
  • ExchangeCodeForToken(ctx context.Context, code string) (*oauth2.Token, error) - Exchange auth code for token
  • SetAccessToken(token string) - Set access token directly

Files

  • GetFile(ctx, fileKey) (*File, error) - Get file by key
  • GetFileVersion(ctx, fileKey, versionID) (*File, error) - Get specific version
  • GetVersionHistory(ctx, fileKey) (*VersionHistory, error) - Get version history
  • GetTeamFiles(ctx, teamID) (*TeamFiles, error) - Get all team files
  • GetProjectFiles(ctx, projectID) (*ProjectFiles, error) - Get project files
  • GetFileNodes(ctx, fileKey, nodeIDs) (map[string]*Node, error) - Get specific nodes
  • GetComments(ctx, fileKey) (*CommentThreads, error) - Get file comments
  • PostComment(ctx, fileKey, message, parentID) (*Comment, error) - Post comment
  • ResolveComment(ctx, fileKey, commentID) error - Mark comment as resolved
  • DeleteComment(ctx, fileKey, commentID) error - Delete comment

Components

  • GetFileComponents(ctx, fileKey) (map[string]*Component, error) - Get all components
  • GetComponent(ctx, componentKey) (*Component, error) - Get single component
  • GetComponentSets(ctx, fileKey) (map[string]*ComponentSet, error) - Get component sets
  • GetComponentUsages(ctx, componentFileKey) (map[string][]string, error) - Get instances
  • GetTeamComponents(ctx, teamID) (map[string]*Component, error) - Get team components
  • SearchComponents(ctx, teamID, query) (map[string]*Component, error) - Search components
  • UpdateComponentDescription(ctx, componentKey, description) error - Update metadata

Exports

  • ExportSVG(ctx, fileKey, nodeID) (string, error) - Export as SVG
  • ExportPNG(ctx, fileKey, nodeID) (string, error) - Export as PNG
  • ExportJPG(ctx, fileKey, nodeID) (string, error) - Export as JPG
  • ExportPDF(ctx, fileKey, nodeID) (string, error) - Export as PDF
  • GetNodeAsImageURL(ctx, fileKey, nodeID, format, scale) (string, error) - Export with scale
  • GetMultipleDesignExports(ctx, fileKey, nodeIDs, format) (*ImageExport, error) - Batch export
  • RenderImageTile(ctx, fileKey, nodeID, tileX, tileY, zLevel) (string, error) - Render tile

Webhooks

  • CreateWebhook(ctx, teamID, url, event, description) (*Webhook, error) - Create webhook
  • ListWebhooks(ctx, teamID) ([]*Webhook, error) - List webhooks
  • GetWebhook(ctx, teamID, webhookID) (*Webhook, error) - Get webhook
  • UpdateWebhook(ctx, teamID, webhookID, url, event) (*Webhook, error) - Update webhook
  • DeleteWebhook(ctx, teamID, webhookID) error - Delete webhook

Utilities

  • ColorToHex(color) string - Convert to hex color
  • ColorToRGB(color) string - Convert to RGB
  • ColorToRGBA(color) string - Convert to RGBA
  • ExportNodeTree(node, results) []*Node - Flatten node tree
  • FindNodeByName(root, name) *Node - Find node by name
  • FindNodeByID(root, id) *Node - Find node by ID
  • GetNodePath(root, target) string - Get node path
  • FilterNodesByType(root, type) []*Node - Filter by type
  • GetBoundingBox(node) (minX, minY, maxX, maxY) - Calculate bounds
  • CountNodesByType(root, type) int - Count nodes

Types

Core Types

File - Represents a Figma design file

type File struct {
    Key             string
    Name            string
    LastModified    string
    ThumbnailURL    string
    Version         string
    Document        *Node
    Components      map[string]*Component
    ComponentSets   map[string]*Component
    Styles          map[string]*Style
}

Node - Represents an element in the design

type Node struct {
    ID              string
    Name            string
    Type            string
    X, Y            float64
    Width, Height   float64
    Children        []*Node
    Fills           []Paint
    Strokes         []Paint
    Effects         []Effect
    // ... more properties
}

Component - Represents a reusable component

type Component struct {
    Key             string
    FileKey         string
    NodeID          string
    Name            string
    Description     string
    ThumbnailURL    string
}

WebhookEvent - Represents a webhook event

type WebhookEvent struct {
    Event           string
    FileID          string
    FileKey         string
    Timestamp       int64
    VersionID       string
    InitiatedBy     *User
    Collections     []Collection
    LibraryChanges  *LibraryChange
}

Environment Variables

Create a .env file:

FIGMA_CLIENT_ID=your_client_id
FIGMA_CLIENT_SECRET=your_client_secret
FIGMA_REDIRECT_URI=http://localhost:3000/auth/callback
FIGMA_ACCESS_TOKEN=optional_access_token
WEBHOOK_SECRET=your_webhook_secret

Examples

See examples.go for comprehensive examples including:

  • OAuth flow
  • File operations
  • Component management
  • Design exports
  • Webhook setup
  • Comment management
  • Node tree navigation
  • Color utilities

Getting Figma API Credentials

  1. Go to Figma Developer Settings
  2. Create a new app
  3. Copy your Client ID and Client Secret
  4. Set up OAuth redirect URI
  5. Use in your configuration

Webhook Events

Supported webhook events:

  • FILE_UPDATE - File content was modified
  • FILE_DELETE - File was deleted
  • FILE_VERSION_UPDATE - New version created
  • LIBRARY_PUBLISH - Components published as library

Error Handling

All methods return errors for better error handling:

file, err := client.GetFile(ctx, "fileKey")
if err != nil {
    switch err.(type) {
    case *url.Error:
        // Network error
    default:
        // API error or parsing error
    }
}

Rate Limiting

Figma API has rate limits. Implement exponential backoff:

retries := 3
backoff := time.Second

for i := 0; i < retries; i++ {
    file, err := client.GetFile(ctx, fileKey)
    if err == nil {
        break
    }
    time.Sleep(backoff)
    backoff *= 2
}

Best Practices

  1. Cache tokens - Store OAuth tokens securely
  2. Use webhooks - Don't poll; use webhooks for updates
  3. Batch operations - Use batch export for multiple nodes
  4. Handle rate limits - Implement backoff strategies
  5. Verify signatures - Always verify webhook signatures
  6. Minimize exports - Export only needed formats/scales

Contributing

Contributions are welcome! Please submit issues and pull requests.

License

MIT

Support

For issues or questions:

About

A comprehensive Go client for the Figma API, designed to communicate with the CaptureCraft application. This library provides full support for file access, component management, design exports, real-time webhooks, and more.

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Contributors