Files
remnawave-api-go/README.md
T

270 lines
6.7 KiB
Markdown

# Remnawave GO SDK
A Go SDK client for interacting with the **[Remnawave API](https://remna.st)**.
## Version Compatibility
| API Version | SDK Version | Install |
|-------------|-------------|---------|
| 2.7.4 | v2.7.4 | `go get git.voidsmiths.dev/shiranui/remnawave-api-go/v2@v2.7.4` |
Generated with [**ogen**](https://github.com/ogen-go/ogen) v1.19.0:
* Zero-reflection JSON decoder for high throughput
* Compile-time validation against OpenAPI 3.0 spec
* First-class `context.Context` support
* Built-in OpenTelemetry instrumentation
* Per-request options via `RequestOption`
* Request/response editors (middleware)
* Organized sub-clients for clean API access
* Simplified method signatures (no verbose Params structs)
## Installation
```bash
go get github.com/shiranuiyami/remnawave-api-go/v2@v2.7.4
```
## Quick Start
```go
package main
import (
"context"
"fmt"
remapi "git.voidsmiths.dev/shiranui/remnawave-api-go/v2/api"
)
func main() {
ctx := context.Background()
// Create base client
baseClient, _ := remapi.NewClient(
"https://your-panel.example.com",
remapi.StaticToken{Token: "YOUR_JWT_TOKEN"},
)
// Wrap with organized sub-clients
client := remapi.NewClientExt(baseClient)
// Get user by UUID - simple string argument
user, _ := client.Users().GetUserByUuid(ctx, "user-uuid-here")
fmt.Printf("User: %s\n", user.(*remapi.UserResponse).Response.Username)
// Get node by UUID
node, _ := client.Nodes().GetOneNode(ctx, "node-uuid-here")
fmt.Printf("Node: %s\n", node.(*remapi.NodeResponse).Response.Name)
// Create user
newUser, _ := client.Users().CreateUser(ctx, &remapi.CreateUserRequest{
Username: "john_doe",
})
fmt.Printf("Created: %s\n", newUser.(*remapi.UserResponse).Response.Username)
}
```
## Available Controllers
| Controller | Description |
|------------|-------------|
| `client.ApiTokens()` | API token management |
| `client.Auth()` | Authentication |
| `client.BandwidthStatsNodes()` | Node bandwidth statistics |
| `client.BandwidthStatsUsers()` | User bandwidth statistics |
| `client.ConfigProfile()` | Config profiles |
| `client.ExternalSquad()` | External squads |
| `client.Hosts()` | Host management |
| `client.HostsBulkActions()` | Bulk host operations |
| `client.HwidUserDevices()` | HWID devices |
| `client.InfraBilling()` | Infrastructure billing |
| `client.InternalSquad()` | Internal squads |
| `client.Keygen()` | Key generation |
| `client.Nodes()` | Node management |
| `client.NodesUsageHistory()` | Node usage history |
| `client.Passkey()` | Passkey authentication |
| `client.RemnawaveSettings()` | Panel settings |
| `client.Snippets()` | Code snippets |
| `client.Subscription()` | Subscription management |
| `client.SubscriptionPageConfig()` | Subscription page config |
| `client.SubscriptionSettings()` | Subscription settings |
| `client.SubscriptionTemplate()` | Subscription templates |
| `client.Subscriptions()` | Multiple subscriptions |
| `client.System()` | System info |
| `client.UserSubscriptionRequestHistory()` | Request history |
| `client.Users()` | User management |
| `client.UsersBulkActions()` | Bulk user operations |
## Error Handling
Unified error types for consistent error handling:
```go
resp, err := client.Users().GetUserByUuid(ctx, "invalid-uuid")
if err != nil {
panic(err)
}
switch e := resp.(type) {
case *remapi.UserResponse:
fmt.Printf("User: %s\n", e.Response.Username)
case *remapi.BadRequestError:
for _, validationErr := range e.Errors {
fmt.Printf("Field: %v, Error: %s\n", validationErr.Path, validationErr.Message)
}
case *remapi.NotFoundError:
fmt.Println("User not found")
case *remapi.InternalServerError:
fmt.Printf("Server error: %s\n", e.Message.Value)
}
```
### Error Types
| Type | Status | Description |
|------|--------|-------------|
| `BadRequestError` | 400 | Validation errors with `[]ValidationError` |
| `UnauthorizedError` | 401 | Authentication required |
| `ForbiddenError` | 403 | Access denied |
| `NotFoundError` | 404 | Resource not found |
| `InternalServerError` | 500 | Server error |
### ValidationError Structure
```go
type ValidationError struct {
Validation string // e.g., "uuid"
Code string // e.g., "invalid_string"
Message string // e.g., "Invalid uuid"
Path []string // e.g., ["uuid"]
}
```
## Common Operations
### Users
```go
// Get by UUID (simplified - just pass the string)
user, _ := client.Users().GetUserByUuid(ctx, "uuid-here")
// Get by username
user, _ := client.Users().GetUserByUsername(ctx, "john")
// Get by short UUID
user, _ := client.Users().GetUserByShortUuid(ctx, "short-uuid")
// Create
user, _ := client.Users().CreateUser(ctx, &remapi.CreateUserRequest{
Username: "new_user",
})
// Update
user, _ := client.Users().UpdateUser(ctx, &remapi.UpdateUserRequest{
Uuid: "uuid-here",
})
// Delete
client.Users().DeleteUser(ctx, "uuid-here")
// Enable/Disable
client.Users().EnableUser(ctx, "uuid-here")
client.Users().DisableUser(ctx, "uuid-here")
// Reset traffic
client.Users().ResetUserTraffic(ctx, "uuid-here")
```
### Nodes
```go
// List all
nodes, _ := client.Nodes().GetAllNodes(ctx)
// Get one (simplified)
node, _ := client.Nodes().GetOneNode(ctx, "uuid-here")
// Create
node, _ := client.Nodes().CreateNode(ctx, &remapi.CreateNodeRequest{
Name: "Node-1",
})
// Delete
client.Nodes().DeleteNode(ctx, "uuid-here")
// Enable/Disable
client.Nodes().EnableNode(ctx, "uuid-here")
client.Nodes().DisableNode(ctx, "uuid-here")
// Restart
client.Nodes().RestartNode(ctx, "uuid-here")
// Reset traffic
client.Nodes().ResetNodeTraffic(ctx, "uuid-here")
```
### Hosts
```go
// List all
hosts, _ := client.Hosts().GetAllHosts(ctx)
// Get one
host, _ := client.Hosts().GetOneHost(ctx, "uuid-here")
// Create
host, _ := client.Hosts().CreateHost(ctx, &remapi.CreateHostRequest{...})
// Delete
client.Hosts().DeleteHost(ctx, "uuid-here")
```
### Authentication
```go
// Login
resp, _ := client.Auth().Login(ctx, &remapi.LoginRequest{
Username: "admin",
Password: "password",
})
token := resp.(*remapi.TokenResponse).Response.AccessToken
// Get status
status, _ := client.Auth().GetStatus(ctx)
```
## Request Options
All methods support per-request `RequestOption` for customization:
```go
// Pass options as the last variadic argument
user, err := client.Users().GetUserByUuid(ctx, "uuid-here", opts...)
```
## Access to Base Client
If you need direct access to the underlying ogen client:
```go
baseClient := client.Client()
```
## Requirements
| Requirement | Version |
|-------------|---------|
| Go | 1.21+ |
| Remnawave API | 2.8.+ |
## License
[MIT](LICENSE)
## Acknowledgments
* [Jolymmiles](https://github.com/Jolymmiles)
## Donation
- **LTC:** `ltc1qac3x0rfh6py309apjlztzrmr2rdv0jmu9dytex`