earnalliance

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 25, 2024 License: MIT Imports: 15 Imported by: 0

README

Earn Alliance

GitHub Tag Go Reference Test Discord

Official Earn Alliance SDKs for Go

This is the Earn Alliance SDK for Go.

  • Discord
  • Twitter Follow

Contents

Supported Platforms

We currently support the Go language in this package.

Installation and Usage

To install the SDK, get the package via:

go get github.com/earn-alliance/earnalliance-go
Initialize

Build the client via the ClientBuilder. The example below shows only the required options. Check the ClientBuilder documentation to see the complete list.

import ea "github.com/earn-alliance/earnalliance-go"

client := ea.NewClientBuilder().
    WithClientID("[client id]").
    WithClientSecret("[client secret]").
    WithGameID("[game id]").
    WithDSN("[dsn]"). // Optional
    Build()

The client configuration can also be read from environment variables if not provided as an option.

// When the NewClientBuilder function is called, it will look
// for the environment variables `ALLIANCE_CLIENT_ID`, `ALLIANCE_CLIENT_SECRET`,
// `ALLIANCE_GAME_ID` and optionally `ALLIANCE_DSN`. The builder will use these to set the values.
client := ea.NewClientBuilder().Build()
Set User Identifiers

Whenever a new user identifier is set, or a new user is registered, you can add or update the identifiers associated with the internal user id.

This is used to tell us the user has installed the app and enrich their information when more game platform accounts or social accounts are added to help us map the user to the game events.

// This shows all of our currently supported platforms, but you only need to
// provide the identifiers that are relevant for your game.
client.SetIdentifiers("[internal user id]", &ea.Identifiers{
    AppleID: ea.IdentifierFrom("..."),
    DiscordID: ea.IdentifierFrom("..."),
    Email: ea.IdentifierFrom("..."),
    EpicGamesID: ea.IdentifierFrom("..."),
    WalletAddress: nil, // This will be ignored, same thing as not setting this value.
})

Note that if you pass a nil pointer in ea.Identifiers, that identifier will simply be ignored. If however, you pass an empty string, then that identifier will be removed from the user's account.

// You can remove a previously set identifier like this.
client.Identify("[internal user id]", &ea.Identifiers(
    AppleID: ea.RemoveIdentifier(), // This will be removed from the user's account.
))
Track User Start Session

Sends standard TRACK event for launching a game. This lets us know that the user has launched the game and is ready to start a challenge.

client.StartGame("[internal user id]")
Track Events

Tracking events that happens in a game. Tracked events are batched together and sent after 30 seconds interval, or when a batch size of 100 events have accumulated, whichever comes first. Both the interval and the batch size are configurable in the client options.

The name of the events can be almost anything, but we recommend sticking to common terms as shown in the following examples.

// An event without any specific value, commonly used for counting event
// instances, i.e. "Kill X Zombies".
client.Track("[internal user id]", "KILL_ZOMBIE", nil, nil)

// An event with an associated value, commonly used for accumulating or
// checking min / max values, i.e. "Score a total of X" or "Achieve a
// highscore of at least X".
score := 100
client.Track("[internal user id]", "SCORE", &score, nil)

// The client can track events for multiple users in parallel.
client.Track("[internal user id]", "DAMAGE_DONE", 500, nil)
client.Track("[another user id]", "DAMAGE_TAKEN", 500, nil)

// Additional traits can be added to the event, which can be used to
// create more detailed challenges, i.e. "Kill X monsters with a knife".
client.Track("[internal user id]", "KILL", ea.Traits{ "weapon": "knife", "mob": "zombie" })
Group Tracked Events

You can group events together, i.e. a game round or a match, whichever makes sense for your game. This allows for natural challenge scopes like "Kill X players in a match".

// Generates unique group id which will be associated with all the events
round := client.StartRound(nil)
round.Track("[internal user id]", "KILL_ZOMBIE")

// Additional traits can be set when starting the round, which will be added
// to all events that are tracked for the specific round.
round := client.StartRound(ea.Traits{ "map": "nuclear_wasteland" })
round.Track("[internal user id]", "KILL_ZOMBIE")
Flush event queue

For events that have higher priority (i.e. SetIdentifiers), instead of initiating a scheduled batch, they trigger the use of an event queue flush. This means that as long as the client has not been flushed prior to the event, the event will be sent to the API right away.

Once the queue has been has been flushed, the client enters a cooldown period (10 seconds by default), during which any subsequent calls to flush will wait for the cooldown to finish, before another Flush is ran. These calls also will not do anything if another Flush call before them started the waiter for the cooldown. Note that any normal procedures, like the queue size reaching the batch limit, will still send the events to the API.

The Flush function can also be called manually on the client instance, but it is still restricted by the same cooldown mechanic.

client.Flush()

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PointerFrom

func PointerFrom[T any](v T) *T

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the gateway to the Earn Alliance API. It is concurrency safe after CreateClient is called. It contains an event queue which sends batchSize (can be set via options) events to the API. This queue is LIFO.

func (*Client) Close

func (c *Client) Close()

Close closes the open goroutines. It is not concurrency safe.

func (*Client) Flush

func (c *Client) Flush() error

Flush flushes the event queue. We can only rely on this returning an error or not in case #1 below. Other cases are asynchronous and won't return an error. Three cases can happen: 1. The cooldown period has passed: - Then we simply send the events to the API. - This case will return an error if the HTTP request fails after max retries. 2. The cooldown period is active & Flush hasn't been called during this period yet: - Then we start a goroutine that will send the events to the API once cooldown is over. - Basically this goroutine is async and the function will return nil immediately. 3. The cooldown is active & Flush has been called during this period: - Then this simply returns nil and the events will be sent by the goroutine that was created in case #2.

func (*Client) SetIdentifiers

func (c *Client) SetIdentifiers(userID string, is *Identifiers)

SetIdentifiers submits an identifier to the event queue. This will call Flush no matter what, but whether it will be sent immediately depends on if the cooldown period is active. However if the event queue hits the batch size limit, the events will be sent to the API.

func (*Client) StartGame

func (c *Client) StartGame(userID string)

StartGame submits an event with the name "START_GAME" and without any traits or value to the event queue. If the event queue hits the batch size limit, then Flush will be called.

func (*Client) StartRound

func (c *Client) StartRound(id string, traits Traits) *Round

StartRound creates a new Round with the given traits. These traits can be overwritten for specific events via passing in traits with the same keys when submitting an event. If id is an empty string we will generate a fresh UUID, and the events sent to this round will have their GroupID set to this UUID.

func (*Client) Track

func (c *Client) Track(userID string, eventName string, value *int, traits Traits)

Track submits an event to the event queue. If the event queue hits the batch size limit, then Flush will be called.

type ClientBuilder

type ClientBuilder struct {
	// contains filtered or unexported fields
}

ClientBuilder builds a new client. It is not concurrency safe. It will panic if required options are missing, or if any invalid options are passed in.

func NewClientBuilder

func NewClientBuilder() *ClientBuilder

NewClientBuilder creates a new ClientBuilder. It also sets the default values in the underlying client. And looks for the environment variables: ALLIANCE_CLIENT_ID, ALLIANCE_CLIENT_SECRET, ALLIANCE_GAME_ID and ALLIANCE_DSN.

func (*ClientBuilder) Build

func (cb *ClientBuilder) Build() *Client

Build returns the client that was created via the builder and starts the internal batch processing goroutine. Ensure that you have the ClientID, ClientSecret and GameID set before you call this.

func (*ClientBuilder) WithBatchSize

func (cb *ClientBuilder) WithBatchSize(batchSize int) *ClientBuilder

WithBatchSize sets the batch size which is the maximum size of the event queue where it will be flushed automatically if reached. Default: 100 This is optional.

func (*ClientBuilder) WithClientID

func (cb *ClientBuilder) WithClientID(clientID string) *ClientBuilder

WithClientID sets the Earn Alliance client ID. Default: N/A This is required.

func (*ClientBuilder) WithClientSecret

func (cb *ClientBuilder) WithClientSecret(clientSecret string) *ClientBuilder

WithClientSecret sets the Earn Alliance client secret. Default: N/A This is required.

func (*ClientBuilder) WithDSN

func (cb *ClientBuilder) WithDSN(dsn string) *ClientBuilder

WithDSN sets the DSN (the URL that requests are sent to) for the Earn Alliance API. Default: https://events.earnalliance.com/v2/custom-events This is optional.

func (*ClientBuilder) WithErrorChannel

func (cb *ClientBuilder) WithErrorChannel(ch chan error) *ClientBuilder

WithErrorChannel sets the error channel where the asynchronous Flush calls will send their errors to. Multiple errors may be sent at once. Default: N/A This is optional.

func (*ClientBuilder) WithFlushCooldown

func (cb *ClientBuilder) WithFlushCooldown(cooldown time.Duration) *ClientBuilder

WithFlushCooldown sets the flush cooldown which is the minimum required time between Flush() calls. During this cooldown period, a Flush() call will start a timer in a goroutine that will flush afterwards. Default: 10 seconds This is optional.

func (*ClientBuilder) WithFlushInterval

func (cb *ClientBuilder) WithFlushInterval(interval time.Duration) *ClientBuilder

WithFlushInterval sets the flush interval which is the time between flushes without the event queue hitting the batch size. Default: 30 seconds This is optional.

func (*ClientBuilder) WithGameID

func (cb *ClientBuilder) WithGameID(gameID string) *ClientBuilder

WithGameID sets the Earn Alliance game ID. Default: N/A This is required.

func (*ClientBuilder) WithMaxRetryAttempts

func (cb *ClientBuilder) WithMaxRetryAttempts(maxAttempts int) *ClientBuilder

WithMaxRetryAttempts sets the maximum number of retries before an HTTP request is considered as failed and the library returns an error. Default: 5 This is optional.

type Identifier added in v0.0.2

type Identifier string

Identifier represents a user's idenfitier which is a string. To remove the identifier from the user, its value should be an empty string. Use the IdentifierFrom function to create these with ease.

func IdentifierFrom added in v0.0.2

func IdentifierFrom(s string) *Identifier

IdentifierFrom creates a new Identifier from s.

func RemoveIdentifier added in v0.0.2

func RemoveIdentifier() *Identifier

RemoveIdentifier creates a new Identifier with empty string. Use this to remove any identifier.

func (Identifier) MarshalJSON added in v0.0.2

func (s Identifier) MarshalJSON() ([]byte, error)

MarshalJSON marshals a Identifier to JSON. This will marshal a null if string is empty. If it's not, it will marshal the string as normal JSON string.

type Identifiers

type Identifiers struct {
	AppleID       *Identifier `json:"appleId,omitempty"`
	DiscordID     *Identifier `json:"discordId,omitempty"`
	Email         *Identifier `json:"email,omitempty"`
	EpicGamesID   *Identifier `json:"epicGamesId,omitempty"`
	SteamID       *Identifier `json:"steamId,omitempty"`
	TwitterId     *Identifier `json:"twitterId,omitempty"`
	WalletAddress *Identifier `json:"walletAddress,omitempty"`
}

Identifiers contains the current identifiers supported by Earn Alliance. The pointers provide an easy way of omitting values. A nil pointer will be omitted from the JSON when submitting it to the API. If the value is an empty string, that identifier will be removed from the user. We provide the generic helper function PointerFrom() to get the pointer to any value.

type Round

type Round struct {
	// contains filtered or unexported fields
}

Round is a nice way of grouping some events together. It sets the GroupID of the events submitted to it. Its ID is a random UUID. You can also create the Round with some traits and these traits will be copied to the events.

func (*Round) Track

func (r *Round) Track(userID string, eventName string, value *int, traits Traits)

Track submits an event to the event queue with its GroupID set to the round's ID. The traits are combined with the round's traits. The traits passed to this function will overwrite the round's traits for this event when they are combined. If the event queue hits the batch size limit, then Flush will be called.

type Traits

type Traits map[string]any

Traits is a JSON object.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL