v2.0.0: module path /v2, quest slugs, per-environment admin keys, regenerated models
CI / build (push) Successful in 12s
CI / build (push) Successful in 12s
Claude-Session: https://claude.ai/code/session_01SMCvdwDmuxoaqGgvGBLk1V
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## 2.0.0
|
||||
|
||||
Breaking change — major bump, required by the backend environments release.
|
||||
The module path gains the Go major-version suffix: import
|
||||
`hub.rudder.build/rudder/rudder-go-sdk/v2` and pull it with
|
||||
`go get hub.rudder.build/rudder/rudder-go-sdk/v2@latest`. Nothing else about
|
||||
the import changes: the package is still `rudder`.
|
||||
|
||||
Admin keys are now per environment. A project has exactly two environments,
|
||||
`staging` and `prod`, and each has its own Admin Key, so the key you configure
|
||||
decides which environment every call reads and writes. There is no environment
|
||||
option on the client or on any method, and there is nothing to migrate in code
|
||||
— but the key itself changed: the old project Admin Key became the `prod` key
|
||||
and a separate `staging` key was generated, both visible under project
|
||||
Settings. Players are per environment too, so a player id from one environment
|
||||
does not resolve in the other, and the same holds for wallets, inventory,
|
||||
storage, counters, quests, runs, battle pass, purchases and leaderboard
|
||||
entries.
|
||||
|
||||
Quests are addressed by slug, because ids differ between staging and prod
|
||||
while slugs are stable. `PlayerQuestParameters.QuestID` is now
|
||||
`PlayerQuestParameters.QuestSlug`, `PlayerQuestRef` carries `QuestSlug`
|
||||
instead of `QuestID`, `PlayerQuest` reports `QuestSlug`, and `Quest`
|
||||
(the catalog definition) gained `Slug` alongside its `ID`.
|
||||
`Players.VerifyAuth` additionally returns `Environment`, which always matches
|
||||
the admin key's environment.
|
||||
|
||||
Environment create, delete and merge, and project-level admin key
|
||||
regeneration, were removed from the platform. This SDK never exposed them, so
|
||||
nothing is gone from its surface.
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
```bash
|
||||
go env -w GOPRIVATE=hub.rudder.build/*
|
||||
go get hub.rudder.build/rudder/rudder-go-sdk@latest
|
||||
go get hub.rudder.build/rudder/rudder-go-sdk/v2@latest
|
||||
```
|
||||
|
||||
Требуется Go 1.21+. Токен не нужен — репозиторий публичный.
|
||||
@@ -18,15 +18,18 @@ go get hub.rudder.build/rudder/rudder-go-sdk@latest
|
||||
## Версионирование
|
||||
|
||||
Потребители фиксируют версию по git-тегу
|
||||
(`go get hub.rudder.build/rudder/rudder-go-sdk@vX.Y.Z`). Первый тег `v0.1.0`
|
||||
будет создан при релизе; до него версионирования нет.
|
||||
(`go get hub.rudder.build/rudder/rudder-go-sdk/v2@vX.Y.Z`). Текущая мажорная
|
||||
версия — `v2`, поэтому путь модуля содержит суффикс `/v2`, а импорты идут
|
||||
через `hub.rudder.build/rudder/rudder-go-sdk/v2`.
|
||||
|
||||
## Доступ
|
||||
|
||||
`AdminKey` — это per-project Admin Key: поле «Admin Key» в настройках проекта
|
||||
в дашборде (app.rudder.build → проект → Settings). Ключ сам определяет
|
||||
проект, отдельный project ID не нужен. Храните его только на сервере —
|
||||
никогда не вшивайте в игровые клиенты.
|
||||
`AdminKey` — это Admin Key окружения: у проекта их два, для `staging` и для
|
||||
`prod` (app.rudder.build → проект → Settings → Environments). Ключ сам
|
||||
определяет и проект, и окружение, поэтому ни project ID, ни параметр
|
||||
окружения передавать не нужно; игроки и контент разных окружений полностью
|
||||
изолированы. Храните ключ только на сервере — никогда не вшивайте в игровые
|
||||
клиенты.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -76,7 +79,7 @@ updated, err := player.Storage().Upsert(ctx, rudder.UpsertPlayerStorageParameter
|
||||
err = player.Storage().Delete(ctx, rudder.DeletePlayerStorageParameters{Type: "settings"})
|
||||
|
||||
quests, err := player.Quests().List(ctx)
|
||||
err = player.Quests().Reset(ctx, rudder.PlayerQuestParameters{QuestID: "daily-1"})
|
||||
err = player.Quests().Reset(ctx, rudder.PlayerQuestParameters{QuestSlug: "daily-1"})
|
||||
// ForceComplete и ForceClaim — аналогично
|
||||
|
||||
updatedPlayer, err := player.Update(ctx, rudder.UpdatePlayerParameters{Nickname: "Neo"})
|
||||
@@ -145,12 +148,12 @@ err = client.Players.Delete(ctx, rudder.DeletePlayersParameters{
|
||||
## Верификация авторизации
|
||||
|
||||
`Players.VerifyAuth` — одиночный (не batch) вызов `POST /players/auth/verify`:
|
||||
проверяет access token игрока и возвращает `playerId`, `projectId` и `status`
|
||||
(`active`/`banned`/`deleted`).
|
||||
проверяет access token игрока и возвращает `playerId`, `projectId`,
|
||||
`environment` (`staging`/`prod`) и `status` (`active`/`banned`/`deleted`).
|
||||
|
||||
```go
|
||||
verification, err := client.Players.VerifyAuth(ctx, accessToken)
|
||||
// verification.PlayerID, verification.ProjectID, verification.Status
|
||||
// verification.PlayerID, verification.ProjectID, verification.Environment, verification.Status
|
||||
```
|
||||
|
||||
`VerifyWebhookSignature` — пакетный хелпер для приёма webhook'ов с подписью
|
||||
@@ -164,7 +167,7 @@ if !rudder.VerifyWebhookSignature(secret, body, r.Header.Get("X-Signature")) {
|
||||
|
||||
err = client.Quests.Reset(ctx, rudder.PlayerQuestsParameters{
|
||||
Items: []rudder.PlayerQuestRef{
|
||||
{PlayerID: "p1", QuestID: "daily-1"},
|
||||
{PlayerID: "p1", QuestSlug: "daily-1"},
|
||||
},
|
||||
})
|
||||
// ForceComplete и ForceClaim — аналогично
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
module hub.rudder.build/rudder/rudder-go-sdk
|
||||
module hub.rudder.build/rudder/rudder-go-sdk/v2
|
||||
|
||||
go 1.21
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type InventoryService struct {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type LeaderboardHandle struct {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type LeaderboardsService struct {
|
||||
|
||||
@@ -5,6 +5,6 @@ package models
|
||||
type AdminPlayerQuest struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Objectives []AdminPlayerQuestObjective `json:"objectives,omitempty"`
|
||||
QuestID string `json:"questId,omitempty"`
|
||||
QuestSlug string `json:"questSlug,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ package models
|
||||
|
||||
type BatchPlayerQuestsItem struct {
|
||||
PlayerID string `json:"playerId,omitempty"`
|
||||
QuestID string `json:"questId,omitempty"`
|
||||
QuestSlug string `json:"questSlug,omitempty"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// Code generated by apigen. DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
type EnvironmentName string
|
||||
|
||||
const (
|
||||
EnvironmentNameStaging EnvironmentName = "staging"
|
||||
EnvironmentNameProd EnvironmentName = "prod"
|
||||
)
|
||||
@@ -8,5 +8,6 @@ type QuestDefinition struct {
|
||||
NextQuestID string `json:"nextQuestId,omitempty"`
|
||||
Objectives []QuestObjective `json:"objectives,omitempty"`
|
||||
Rewards []QuestRewardDefinition `json:"rewards,omitempty"`
|
||||
Slug string `json:"slug,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package models
|
||||
|
||||
type VerifyPlayerAuthResponse struct {
|
||||
Environment EnvironmentName `json:"environment,omitempty"`
|
||||
PlayerID string `json:"playerId,omitempty"`
|
||||
ProjectID string `json:"projectId,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
|
||||
+5
-5
@@ -5,7 +5,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type PlayerQuestsHandle struct {
|
||||
@@ -24,26 +24,26 @@ func (h *PlayerQuestsHandle) List(ctx context.Context) ([]PlayerQuest, error) {
|
||||
|
||||
type PlayerQuestParameters struct {
|
||||
IdempotencyKey string
|
||||
QuestID string
|
||||
QuestSlug string
|
||||
}
|
||||
|
||||
func (h *PlayerQuestsHandle) Reset(ctx context.Context, parameters PlayerQuestParameters) error {
|
||||
return h.quests.Reset(ctx, PlayerQuestsParameters{
|
||||
IdempotencyKey: parameters.IdempotencyKey,
|
||||
Items: []PlayerQuestRef{{PlayerID: h.playerID, QuestID: parameters.QuestID}},
|
||||
Items: []PlayerQuestRef{{PlayerID: h.playerID, QuestSlug: parameters.QuestSlug}},
|
||||
})
|
||||
}
|
||||
|
||||
func (h *PlayerQuestsHandle) ForceComplete(ctx context.Context, parameters PlayerQuestParameters) error {
|
||||
return h.quests.ForceComplete(ctx, PlayerQuestsParameters{
|
||||
IdempotencyKey: parameters.IdempotencyKey,
|
||||
Items: []PlayerQuestRef{{PlayerID: h.playerID, QuestID: parameters.QuestID}},
|
||||
Items: []PlayerQuestRef{{PlayerID: h.playerID, QuestSlug: parameters.QuestSlug}},
|
||||
})
|
||||
}
|
||||
|
||||
func (h *PlayerQuestsHandle) ForceClaim(ctx context.Context, parameters PlayerQuestParameters) error {
|
||||
return h.quests.ForceClaim(ctx, PlayerQuestsParameters{
|
||||
IdempotencyKey: parameters.IdempotencyKey,
|
||||
Items: []PlayerQuestRef{{PlayerID: h.playerID, QuestID: parameters.QuestID}},
|
||||
Items: []PlayerQuestRef{{PlayerID: h.playerID, QuestSlug: parameters.QuestSlug}},
|
||||
})
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type PlayerStorageHandle struct {
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type PlayersService struct {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type QuestsService struct {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
name: rudder-go-sdk
|
||||
description: Use when working with the Rudder Go server SDK (package rudder, module hub.rudder.build/rudder/rudder-go-sdk) for server-side admin operations — players, wallet, inventory, storage, quests, leaderboards, webhook signature verification.
|
||||
description: Use when working with the Rudder Go server SDK (package rudder, module hub.rudder.build/rudder/rudder-go-sdk/v2) for server-side admin operations — players, wallet, inventory, storage, quests, leaderboards, webhook signature verification.
|
||||
---
|
||||
|
||||
# Rudder Go server SDK
|
||||
|
||||
Server-side admin SDK for the Rudder LiveOps platform. Covers the `/game/v1`
|
||||
admin surface, authenticated with `X-API-Key`. Module:
|
||||
`hub.rudder.build/rudder/rudder-go-sdk`, package `rudder`. Requires Go 1.21+.
|
||||
`hub.rudder.build/rudder/rudder-go-sdk/v2`, package `rudder`. Requires Go 1.21+.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -15,17 +15,20 @@ The module is served from a self-hosted Gitea, bypassing proxy.golang.org:
|
||||
|
||||
```bash
|
||||
go env -w GOPRIVATE=hub.rudder.build/*
|
||||
go get hub.rudder.build/rudder/rudder-go-sdk@latest
|
||||
go get hub.rudder.build/rudder/rudder-go-sdk/v2@latest
|
||||
```
|
||||
|
||||
## Client init
|
||||
|
||||
`AdminKey` is the per-project Admin Key from the dashboard
|
||||
(app.rudder.build → project → Settings). The key identifies the project; no
|
||||
separate project ID is needed. Keep it server-side only, never in game clients.
|
||||
`AdminKey` is the Admin Key of one environment. A project has exactly two,
|
||||
`staging` and `prod` (app.rudder.build → project → Settings → Environments).
|
||||
The key identifies both the project and the environment, so no project ID and
|
||||
no environment argument are ever passed; players, wallets, inventory, storage,
|
||||
quests and leaderboard entries of the two environments are fully isolated.
|
||||
Keep it server-side only, never in game clients.
|
||||
|
||||
```go
|
||||
import rudder "hub.rudder.build/rudder/rudder-go-sdk"
|
||||
import rudder "hub.rudder.build/rudder/rudder-go-sdk/v2"
|
||||
|
||||
client, err := rudder.New(rudder.Config{
|
||||
AdminKey: os.Getenv("RUDDER_ADMIN_KEY"),
|
||||
@@ -40,7 +43,7 @@ client, err := rudder.New(rudder.Config{
|
||||
Public types live in package `rudder` (aliases in `types.go`). The `models`
|
||||
package is generated wire format — never import it in application code and
|
||||
never edit it by hand (regenerate via `make generate-openapi` in
|
||||
liveops-gateway).
|
||||
liveops-backend).
|
||||
|
||||
## Batch-first mutation model
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@ func (s *PlayersService) Get(ctx context.Context, playerID string) (*PlayerDetai
|
||||
|
||||
func (s *PlayersService) VerifyAuth(ctx context.Context, accessToken string) (*PlayerAuthVerification, error)
|
||||
// Single (non-batch) call: POST /players/auth/verify.
|
||||
// PlayerAuthVerification: {PlayerID, ProjectID, Status} — Status is "active"/"banned"/"deleted".
|
||||
// PlayerAuthVerification: {PlayerID, ProjectID, Environment, Status} — Status is "active"/"banned"/"deleted".
|
||||
// Environment ("staging"/"prod") is the environment the token was issued for; it always
|
||||
// matches the admin key, since both come from the same environment.
|
||||
```
|
||||
|
||||
## Batch mutations
|
||||
|
||||
@@ -12,7 +12,7 @@ type ListQuestsParameters struct {
|
||||
Cursor *string
|
||||
}
|
||||
// QuestList: {Items []Quest, NextCursor string}
|
||||
// Quest: {ID, Name, Status, NextQuestID, Objectives []QuestObjective, Rewards []QuestReward}
|
||||
// Quest: {ID, Slug, Name, Status, NextQuestID, Objectives []QuestObjective, Rewards []QuestReward}
|
||||
// QuestObjective: {ID, Metric, Target int64}
|
||||
// QuestReward: {Amount int64, Currency, ItemID}
|
||||
```
|
||||
@@ -28,7 +28,7 @@ func (s *QuestsService) ForceClaim(ctx context.Context, parameters PlayerQuestsP
|
||||
|
||||
type PlayerQuestsParameters struct {
|
||||
IdempotencyKey string
|
||||
Items []PlayerQuestRef // {PlayerID, QuestID}
|
||||
Items []PlayerQuestRef // {PlayerID, QuestSlug}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -38,7 +38,7 @@ type PlayerQuestsParameters struct {
|
||||
|
||||
```go
|
||||
func (h *PlayerQuestsHandle) List(ctx context.Context) ([]PlayerQuest, error)
|
||||
// PlayerQuest: {QuestID, Name, Status, Objectives []PlayerQuestObjective}
|
||||
// PlayerQuest: {QuestSlug, Name, Status, Objectives []PlayerQuestObjective}
|
||||
// PlayerQuestObjective: {ObjectiveID, Current int64, Target int64}
|
||||
|
||||
func (h *PlayerQuestsHandle) Reset(ctx context.Context, parameters PlayerQuestParameters) error
|
||||
@@ -47,6 +47,6 @@ func (h *PlayerQuestsHandle) ForceClaim(ctx context.Context, parameters PlayerQu
|
||||
|
||||
type PlayerQuestParameters struct {
|
||||
IdempotencyKey string
|
||||
QuestID string
|
||||
QuestSlug string
|
||||
}
|
||||
```
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
"hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
)
|
||||
|
||||
type StorageService struct {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package rudder
|
||||
|
||||
import "hub.rudder.build/rudder/rudder-go-sdk/models"
|
||||
import "hub.rudder.build/rudder/rudder-go-sdk/v2/models"
|
||||
|
||||
// Domain types are aliases of generated OpenAPI models so callers import
|
||||
// only this package. models/ is wire format and is not part of the public API.
|
||||
|
||||
Reference in New Issue
Block a user