2 Commits

Author SHA1 Message Date
4be44c4eb2 add limiter 2025-04-05 11:53:00 +11:00
e01d9805c6 README 2025-04-05 03:37:00 +11:00
3 changed files with 105 additions and 5 deletions

View File

@ -1,14 +1,61 @@
# go-igdb # go-igdb
a go library to access IGDB API A Go client library for the IGDB (Internet Game Database) API v4. This library provides a simple and efficient way to interact with IGDB's protobuf-based API.
## Usage ## Features
- Full support for IGDB API v4
- Protobuf-based communication for better performance
- Automatic token management for Twitch authentication
- Built-in retry mechanism for failed requests
- Optional Cloudflare bypass support via FlareSolverr
- All endpoints are supported
## Installation
```bash
go get github.com/bestnite/go-igdb
```
## Quick Start
```go ```go
g := igdb.New("clientID", "clientSecret") // Create a new IGDB client
game, err := g.GetGameByID(325594) client := igdb.New("your-client-id", "your-client-secret")
// Get a game by ID
game, err := client.GetGameByID(1942)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Game: %s\n", game.Name)
// Search games with custom query
games, err := client.GetGames("search \"Zelda\"; fields name,rating,release_dates.*;")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println(game.Name)
``` ```
## Advanced Usage
### Query Format
The library uses IGDB's query syntax. For example:
```go
// Get games released in 2023
games, err := client.GetGames("where release_dates.y = 2023; fields name,rating;")
// Get specific fields for a company
companies, err := client.GetCompanies("where id = 1234; fields name,description,country;")
```
## Requirements
- Go 1.24 or higher
- IGDB/Twitch API credentials (Client ID and Client Secret)
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.

View File

@ -11,11 +11,13 @@ type igdb struct {
clientID string clientID string
token *twitchToken token *twitchToken
flaresolverr *flaresolverr.Flaresolverr flaresolverr *flaresolverr.Flaresolverr
limiter *rateLimiter
} }
func New(clientID, clientSecret string) *igdb { func New(clientID, clientSecret string) *igdb {
return &igdb{ return &igdb{
clientID: clientID, clientID: clientID,
limiter: newRateLimiter(4),
token: NewTwitchToken(clientID, clientSecret), token: NewTwitchToken(clientID, clientSecret),
flaresolverr: nil, flaresolverr: nil,
} }
@ -24,12 +26,15 @@ func New(clientID, clientSecret string) *igdb {
func NewWithFlaresolverr(clientID, clientSecret string, f *flaresolverr.Flaresolverr) *igdb { func NewWithFlaresolverr(clientID, clientSecret string, f *flaresolverr.Flaresolverr) *igdb {
return &igdb{ return &igdb{
clientID: clientID, clientID: clientID,
limiter: newRateLimiter(4),
token: NewTwitchToken(clientID, clientSecret), token: NewTwitchToken(clientID, clientSecret),
flaresolverr: f, flaresolverr: f,
} }
} }
func (g *igdb) Request(URL string, dataBody any) (*resty.Response, error) { func (g *igdb) Request(URL string, dataBody any) (*resty.Response, error) {
g.limiter.wait()
t, err := g.token.getToken() t, err := g.token.getToken()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get twitch token: %w", err) return nil, fmt.Errorf("failed to get twitch token: %w", err)

48
rate_limiter.go Normal file
View File

@ -0,0 +1,48 @@
package igdb
import (
"sync"
"time"
)
type rateLimiter struct {
mu sync.Mutex
rate int
interval time.Duration
tokens int
lastRefill time.Time
}
func newRateLimiter(rate int) *rateLimiter {
return &rateLimiter{
rate: rate,
interval: time.Second,
tokens: rate,
lastRefill: time.Now(),
}
}
func (r *rateLimiter) wait() {
r.mu.Lock()
defer r.mu.Unlock()
now := time.Now()
elapsed := now.Sub(r.lastRefill)
if elapsed >= r.interval {
r.tokens = r.rate
r.lastRefill = now
}
if r.tokens <= 0 {
waitTime := r.interval - elapsed
r.mu.Unlock()
time.Sleep(waitTime)
r.mu.Lock()
r.tokens = r.rate - 1
r.lastRefill = time.Now()
return
}
r.tokens--
}