Files
zeekayandHanzo Dev 8ee8950230 Go 1.27.1, and the code it can say more simply
The module declares go 1.27.1 and the adapter image follows. go fix
applied the modernizers and left ptrString and ptrBool with no callers,
so they are gone; omitzero is not applied, since it changes what the
JSON says.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 19:52:31 -07:00

93 lines
3.1 KiB
Go

package insights
import (
"time"
json "github.com/goccy/go-json"
"github.com/google/uuid"
)
// Values implementing this interface are used by insights clients to notify
// the application when a message send succeeded or failed.
//
// Callback methods are called by a client's internal goroutines. There are no
// guarantees about which goroutine triggers the callbacks, whether calls are
// made sequentially or in parallel, or whether callback order matches enqueue order.
//
// Callback methods must return quickly and avoid long blocking operations so
// they do not interfere with the client's internal workflow.
type Callback interface {
// Success is called for every message that was successfully sent to the API.
Success(APIMessage)
// Failure is called for every message that failed to be sent to the API and
// will be discarded by the client. The error describes the send or serialization failure.
Failure(APIMessage, error)
}
// This interface is used to represent insights objects that can be sent via
// a client.
//
// Types like insights.Capture, insights.Alias, etc... implement this interface
// and therefore can be passed to the insights.Client.Enqueue method.
type Message interface {
// Validate checks the internal structure of the message. It returns nil when
// the message is valid or an error describing the invalid field.
Validate() error
// APIfy converts the message into its PostHog batch API representation.
APIfy() APIMessage
// internal prevents external packages from satisfying Message. Calling it panics.
internal()
}
// Returns the time value passed as first argument, unless it's the zero-value,
// in that case the default value passed as second argument is returned.
func makeTimestamp(t time.Time, def time.Time) time.Time {
if t == (time.Time{}) {
return def
}
return t
}
// makeUUID returns the UUID passed as first argument if non-empty,
// otherwise generates and returns a new random UUID (v4).
func makeUUID(u string) string {
if u != "" {
return u
}
return uuid.New().String()
}
// batch represents objects sent to the /batch/ endpoint with pre-serialized messages.
// Messages are pre-serialized as json.RawMessage for efficient batch building -
// json.Marshal embeds them directly without re-encoding.
type batch struct {
ApiKey string `json:"api_key"`
HistoricalMigration bool `json:"historical_migration,omitempty"`
Messages []json.RawMessage `json:"batch"`
}
// APIMessage is a wire-format message produced by Message.APIfy and passed to callbacks.
type APIMessage any
// prepareForSend creates the API message and serializes it to JSON.
// Returns pre-serialized JSON for efficient batch building, the original
// APIMessage for callbacks, and any serialization error.
// Size is derived from len(json.RawMessage) when needed - O(1) operation.
func prepareForSend(msg Message) (json.RawMessage, APIMessage, error) {
apiMsg := msg.APIfy()
data, err := json.Marshal(apiMsg)
if err != nil {
return nil, apiMsg, err
}
return json.RawMessage(data), apiMsg, nil
}
const (
maxBatchBytes = 500000
maxMessageBytes = 500000
)