Skip to content

pexip/go-infinity-sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Beta Notice: The go-infinity-sdk is currently in Beta and is not recommended for production deployments. Please use with caution.

Pexip Infinity Go SDK

A comprehensive Go client library for the Pexip Infinity Management API, providing easy access to all four API categories: Configuration, Status, History, and Command APIs.

Features

  • Full API Coverage: Complete support for all Pexip Infinity Management API endpoints
  • Type-Safe: Strongly typed Go structs for all API requests and responses
  • Authentication: Support for Basic Auth, Token Auth, Bearer Auth, and custom authentication
  • Retry Mechanism: Built-in exponential backoff with jitter for reliable API calls
  • Context Support: All operations support Go context for cancellation and timeouts
  • Comprehensive Testing: Extensive test coverage with mocks using testify/mock
  • Flexible Configuration: Configurable base URLs, HTTP clients, and authentication methods

Installation

go get github.com/pexip/go-infinity-sdk/v38

Quick Start

Basic Setup

package main

import (
    "context"
    "fmt"
    "log"

    infinity "github.com/pexip/go-infinity-sdk/v38"
)

func main() {
    // Create a new client with basic authentication and retry configuration
    client, err := infinity.New(
        infinity.WithBaseURL("https://your-pexip-server.com"),
        infinity.WithBasicAuth("admin", "your-password"),
        // Optional: customize retry behavior (default is 3 retries with exponential backoff)
        infinity.WithMaxRetries(2),
    )
    if err != nil {
        log.Fatal(err)
    }

    // Get system status
    ctx := context.Background()
    status, err := client.Status.GetSystemStatus(ctx)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("System Status: %s, Version: %s\n", status.Status, status.Version)
}

Authentication Options

Basic Authentication

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithBasicAuth("admin", "password"),
)

Token Authentication

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithTokenAuth("your-api-token"),
)

Bearer Authentication

import "github.com/pexip/go-infinity-sdk/v38/auth"

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithAuth(auth.NewBearerAuth("your-bearer-token")),
)

Custom Authentication

import "github.com/pexip/go-infinity-sdk/v38/auth"

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithAuth(auth.NewCustomAuth("X-API-Key", "your-api-key")),
)

Retry Configuration

The SDK includes a robust retry mechanism with exponential backoff to handle transient failures:

Default Retry Behavior

// Default configuration is applied automatically
client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithBasicAuth("admin", "password"),
    // Retries up to 3 times with exponential backoff
)

Custom Retry Configuration

import "time"

retryConfig := &infinity.RetryConfig{
    MaxRetries:   5,                      // Maximum number of retries
    BackoffMin:   500 * time.Millisecond, // Minimum backoff duration
    BackoffMax:   30 * time.Second,       // Maximum backoff duration
    Multiplier:   2.0,                    // Backoff multiplier
    JitterFactor: 0.1,                    // Jitter factor (0.0-1.0)
}

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithBasicAuth("admin", "password"),
    infinity.WithRetryConfig(retryConfig),
)

Convenience Options

// Disable retries completely
client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithBasicAuth("admin", "password"),
    infinity.WithNoRetries(),
)

// Set only max retries (uses default for other settings)
client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithBasicAuth("admin", "password"),
    infinity.WithMaxRetries(1),
)

The retry mechanism automatically retries on:

  • HTTP Status Codes: 429, 500, 502, 503, 504
  • Network Errors: Connection refused, timeouts, DNS failures

It will NOT retry on:

  • Client Errors: 4xx status codes (400, 401, 403, 404, etc.)
  • Context Cancellation: Respects context timeouts and cancellation

API Examples

Configuration API

Managing Conferences

package main

import (
    "context"
    "fmt"
    "log"

    infinity "github.com/pexip/go-infinity-sdk/v38"
    "github.com/pexip/go-infinity-sdk/v38/config"
)

func main() {
    client, err := infinity.New(
        infinity.WithBaseURL("https://your-pexip-server.com"),
        infinity.WithBasicAuth("admin", "password"),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Create a new conference
    createReq := &config.ConferenceCreateRequest{
        Name:        "My Test Conference",
        Description: "A test conference for demonstration",
        ServiceType: "conference",
        AllowGuests: true,
        GuestsMuted: false,
    }

    conference, err := client.Config.CreateConference(ctx, createReq)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Created conference: %s (ID: %d)\n", conference.Name, conference.ID)

    // List conferences with pagination and search
    listOpts := &config.ListOptions{}
    listOpts.Limit = 10
    listOpts.Offset = 0
    listOpts.Search = "test"

    conferences, err := client.Config.ListConferences(ctx, listOpts)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Found %d conferences\n", len(conferences.Objects))
    for _, conf := range conferences.Objects {
        fmt.Printf("- %s (ID: %d)\n", conf.Name, conf.ID)
    }

    // Update a conference
    updateReq := &config.ConferenceUpdateRequest{
        Description: "Updated description",
    }

    updatedConf, err := client.Config.UpdateConference(ctx, conference.ID, updateReq)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Updated conference description: %s\n", updatedConf.Description)

    // Delete the conference
    err = client.Config.DeleteConference(ctx, conference.ID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("Conference deleted successfully")
}

Managing Locations

// Create a location
createLocReq := &config.LocationCreateRequest{
    Name:        "New York Office",
    Description: "Main office location",
}

location, err := client.Config.CreateLocation(ctx, createLocReq)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Created location: %s (ID: %d)\n", location.Name, location.ID)

// List all locations
locations, err := client.Config.ListLocations(ctx, nil)
if err != nil {
    log.Fatal(err)
}

for _, loc := range locations.Objects {
    fmt.Printf("Location: %s - %s\n", loc.Name, loc.Description)
}

Status API

System and Conference Status

package main

import (
    "context"
    "fmt"
    "log"

    infinity "github.com/pexip/go-infinity-sdk/v38"
    "github.com/pexip/go-infinity-sdk/v38/status"
)

func main() {
    client, err := infinity.New(
        infinity.WithBaseURL("https://your-pexip-server.com"),
        infinity.WithBasicAuth("admin", "password"),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Get system status
    sysStatus, err := client.Status.GetSystemStatus(ctx)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("System Status: %s\n", sysStatus.Status)
    fmt.Printf("Version: %s\n", sysStatus.Version)
    fmt.Printf("Uptime: %d seconds\n", sysStatus.Uptime)
    fmt.Printf("CPU Load: %.2f%%\n", sysStatus.CPULoad)
    fmt.Printf("Memory Usage: %d/%d MB\n", 
        sysStatus.UsedMemory/1024/1024, 
        sysStatus.TotalMemory/1024/1024)

    // List active conferences
    conferences, err := client.Status.ListConferences(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("\nActive Conferences: %d\n", len(conferences.Objects))
    for _, conf := range conferences.Objects {
        fmt.Printf("- %s: %d participants (Started: %t)\n", 
            conf.Name, conf.ParticipantCount, conf.Started)
    }

    // List participants with pagination
    participantOpts := &status.ListOptions{}
    participantOpts.Limit = 20
    participants, err := client.Status.ListParticipants(ctx, participantOpts)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("\nActive Participants: %d\n", len(participants.Objects))
    for _, participant := range participants.Objects {
        fmt.Printf("- %s (%s) in %s - Muted: %t\n", 
            participant.DisplayName, 
            participant.Role,
            participant.ConferenceName,
            participant.IsMuted)
    }

    // List worker nodes
    workers, err := client.Status.ListWorkers(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("\nWorker Nodes: %d\n", len(workers.Objects))
    for _, worker := range workers.Objects {
        fmt.Printf("- %s (%s): CPU %.1f%%, Memory %.1f%%, %d conferences\n", 
            worker.HostName, 
            worker.Status,
            worker.CPU,
            worker.Memory,
            worker.Conferences)
    }

    // List system alarms
    alarms, err := client.Status.ListAlarms(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("\nSystem Alarms: %d\n", len(alarms.Objects))
    for _, alarm := range alarms.Objects {
        status := "ACTIVE"
        if alarm.Cleared {
            status = "CLEARED"
        }
        fmt.Printf("- [%s] %s: %s (%s)\n", 
            alarm.Level, 
            alarm.Name, 
            alarm.Details,
            status)
    }
}

History API

Conference and Participant History

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    infinity "github.com/pexip/go-infinity-sdk/v38"
    "github.com/pexip/go-infinity-sdk/v38/history"
)

func main() {
    client, err := infinity.New(
        infinity.WithBaseURL("https://your-pexip-server.com"),
        infinity.WithBasicAuth("admin", "password"),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Get conference history for the last 24 hours
    yesterday := time.Now().Add(-24 * time.Hour)
    listOpts := &history.ListOptions{}
    listOpts.Limit = 50
    listOpts.StartTime = &yesterday
    listOpts.Search = "weekly"

    conferences, err := client.History.ListConferences(ctx, listOpts)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Conference History (last 24h): %d conferences\n", len(conferences.Objects))
    for _, conf := range conferences.Objects {
        duration := time.Duration(conf.DurationSeconds) * time.Second
        fmt.Printf("- %s: %v duration, %d participants\n", 
            conf.Name, 
            duration,
            conf.TotalParticipants)
    }

    // Get participant history for a specific conference
    if len(conferences.Objects) > 0 {
        confID := conferences.Objects[0].ID
        participants, err := client.History.ListParticipantsByConference(ctx, confID, nil)
        if err != nil {
            log.Fatal(err)
        }

        fmt.Printf("\nParticipants in conference %d:\n", confID)
        for _, participant := range participants.Objects {
            duration := time.Duration(participant.DurationSeconds) * time.Second
            fmt.Printf("- %s (%s): %v duration, %s reason\n",
                participant.DisplayName,
                participant.Role,
                duration,
                participant.DisconnectReason)
        }

        // Get media stream details for the first participant
        if len(participants.Objects) > 0 {
            participantID := participants.Objects[0].ID
            streams, err := client.History.ListMediaStreamsByParticipant(ctx, participantID, nil)
            if err != nil {
                log.Fatal(err)
            }

            fmt.Printf("\nMedia streams for participant %d:\n", participantID)
            for _, stream := range streams.Objects {
                fmt.Printf("- %s %s: %s codec, %d kbps\n",
                    stream.StreamType,
                    stream.Direction,
                    stream.Codec,
                    stream.Bitrate/1000)
            }
        }
    }
}

Command API

Conference and Participant Control

package main

import (
    "context"
    "fmt"
    "log"

    infinity "github.com/pexip/go-infinity-sdk/v38"
    "github.com/pexip/go-infinity-sdk/v38/command"
)

func main() {
    client, err := infinity.New(
        infinity.WithBaseURL("https://your-pexip-server.com"),
        infinity.WithBasicAuth("admin", "password"),
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx := context.Background()

    // Get current participants to demonstrate commands
    participants, err := client.Status.ListParticipants(ctx, nil)
    if err != nil {
        log.Fatal(err)
    }

    if len(participants.Objects) == 0 {
        fmt.Println("No active participants found")
        return
    }

    participant := participants.Objects[0]
    participantUUID := participant.UUID
    conferenceID := participant.ConferenceID

    fmt.Printf("Managing participant: %s (UUID: %s)\n", participant.DisplayName, participantUUID)

    // Mute a participant
    result, err := client.Command.MuteParticipant(ctx, participantUUID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Mute result: %s - %s\n", result.Status, result.Message)

    // Send a message to the participant
    result, err = client.Command.SendMessageToParticipant(ctx, participantUUID, "Welcome to the conference!")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Message sent: %s\n", result.Status)

    // Spotlight the participant
    result, err = client.Command.SpotlightParticipant(ctx, participantUUID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Spotlight result: %s\n", result.Status)

    // Promote participant to chair
    result, err = client.Command.PromoteParticipant(ctx, participantUUID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Promotion result: %s\n", result.Status)

    // Lock the conference
    result, err = client.Command.LockConference(ctx, conferenceID)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Conference lock result: %s\n", result.Status)

    // Send message to all participants in the conference
    result, err = client.Command.SendMessageToConference(ctx, conferenceID, "This conference is now locked")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Conference message result: %s\n", result.Status)

    // Transfer participant to another conference
    transferOpts := &command.TransferOptions{
        Role: "guest",
    }
    result, err = client.Command.TransferParticipant(ctx, participantUUID, "other-conference", transferOpts)
    if err != nil {
        log.Printf("Transfer failed (expected if 'other-conference' doesn't exist): %v\n", err)
    } else {
        fmt.Printf("Transfer result: %s\n", result.Status)
    }

    // Start a conference programmatically
    result, err = client.Command.StartConference(ctx, "scheduled-meeting")
    if err != nil {
        log.Printf("Start conference failed (expected if conference doesn't exist): %v\n", err)
    } else {
        fmt.Printf("Conference start result: %s\n", result.Status)
    }
}

Advanced Usage

Custom HTTP Client

import (
    "net/http"
    "time"
)

// Create a custom HTTP client with timeout and custom transport
httpClient := &http.Client{
    Timeout: 60 * time.Second,
    Transport: &http.Transport{
        MaxIdleConns:        100,
        MaxIdleConnsPerHost: 10,
        IdleConnTimeout:     90 * time.Second,
    },
}

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithHTTPClient(httpClient),
    infinity.WithBasicAuth("admin", "password"),
)

Custom HTTP Transport

For more fine-grained control over HTTP transport settings (proxies, TLS configuration, connection pooling), you can use WithTransport:

import (
    "crypto/tls"
    "net/http"
    "net/url"
    "time"
)

// Example 1: Custom transport with proxy and TLS settings
proxyURL, _ := url.Parse("http://proxy.company.com:8080")
customTransport := &http.Transport{
    Proxy: http.ProxyURL(proxyURL),
    TLSClientConfig: &tls.Config{
        InsecureSkipVerify: true, // Only for testing!
    },
    MaxIdleConns:        50,
    MaxIdleConnsPerHost: 10,
    IdleConnTimeout:     30 * time.Second,
    DisableCompression:  true,
}

client, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithTransport(customTransport),
    infinity.WithBasicAuth("admin", "password"),
)

// Example 2: Transport with client certificates
cert, _ := tls.LoadX509KeyPair("client.crt", "client.key")
tlsTransport := &http.Transport{
    TLSClientConfig: &tls.Config{
        Certificates: []tls.Certificate{cert},
    },
}

tlsClient, err := infinity.New(
    infinity.WithBaseURL("https://your-pexip-server.com"),
    infinity.WithTransport(tlsTransport),
    infinity.WithBasicAuth("admin", "password"),
)

Error Handling

import "github.com/pexip/go-infinity-sdk/v38"

// All API calls return typed errors
conferences, err := client.Config.ListConferences(ctx, nil)
if err != nil {
    // Check if it's an API error
    if apiErr, ok := err.(*infinity.APIError); ok {
        fmt.Printf("API Error %d: %s\n", apiErr.StatusCode, apiErr.Message)
        if apiErr.Details != "" {
            fmt.Printf("Details: %s\n", apiErr.Details)
        }
    } else {
        // Handle other types of errors (network, timeout, etc.)
        fmt.Printf("Other error: %v\n", err)
    }
}

Context and Timeouts

import (
    "context"
    "time"
)

// Create a context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

// Use the context for all API calls
conferences, err := client.Config.ListConferences(ctx, nil)
if err != nil {
    if ctx.Err() == context.DeadlineExceeded {
        fmt.Println("Request timed out")
    }
}

Support

For questions and support, please refer to the Pexip Infinity API Documentation or open an issue in this repository.

About

Go Infinity SDK

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 5