gm

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Google-account pairing cookie handling. The pairing flow needs the authenticated cookies from a messages.google.com browser session; this parser accepts a raw Cookie header, "Copy as cURL", "Copy as fetch", or a JSON map, and validates that the Google auth cookies are present.

Package gm wraps go.mau.fi/mautrix-gmessages/pkg/libgm with the conventions gmcli needs: filesystem-backed AuthData persistence, an event subscriber model on top of libgm's single SetEventHandler, and helpers for the QR pairing flow.

Two entry points cover the lifecycle:

Pair(ctx, layout, render)         // first run: produces session.json
Open(layout, logger) -> *Client   // subsequent runs: ready to Connect()

The wrapper does not own a goroutine of its own; libgm runs the long-poll. Subscribers must not block in their handlers.

Index

Constants

View Source
const PairTimeout = 5 * time.Minute

PairTimeout is the upper bound on how long we wait for a phone to scan the QR code. Google's relay drops unfinished pairings after a few minutes.

Variables

This section is empty.

Functions

func ParseGoogleCookieInput added in v0.4.0

func ParseGoogleCookieInput(input string) (map[string]string, error)

ParseGoogleCookieInput extracts and validates Google auth cookies from free-form pasted input.

Types

type Client

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

Client is a thin wrapper around *libgm.Client adding fan-out event subscription and persistence on AuthTokenRefreshed.

func Open

func Open(layout paths.Layout, logger zerolog.Logger) (*Client, error)

Open loads session.json and returns a connected-but-not-yet-Connect()'d Client. Returns an error if no session exists — the caller must run Pair first.

func (*Client) AuthSnapshot

func (c *Client) AuthSnapshot() (*libgm.AuthData, error)

AuthSnapshot returns a deep copy of the current AuthData by JSON round-trip. Useful for diagnostics; do not modify.

func (*Client) Connect

func (c *Client) Connect() error

Connect opens the long-poll connection. Events flow to subscribers immediately. Returns when the initial sync completes; the connection continues running in a background goroutine inside libgm.

func (*Client) Disconnect

func (c *Client) Disconnect()

Disconnect closes the long-poll. Safe to call multiple times.

func (*Client) DownloadMedia

func (c *Client) DownloadMedia(mediaID string, key []byte) ([]byte, error)

DownloadMedia retrieves and decrypts the bytes for an attachment. The connection does not need to be in long-poll mode — DownloadMedia uses authenticated HTTP — but the AuthData's TachyonAuthToken must be fresh. Call Connect once before this if the session has been idle.

func (*Client) IsConnected

func (c *Client) IsConnected() bool

IsConnected reports whether the long-poll is currently active.

func (*Client) SendReaction

func (c *Client) SendReaction(messageID, emoji string, action ReactionAction) error

SendReaction adds, removes, or switches a unicode reaction on a message.

func (*Client) SendText

func (c *Client) SendText(ctx context.Context, conversationID, body, replyToID string) (*SendTextResult, error)

SendText sends a text message into the given conversation. ReplyToID is optional; when set, the new message is rendered as a quoted reply by the recipient's client. The libgm long-poll must be Connected; call WaitForReady first for fresh sessions.

func (*Client) Subscribe

func (c *Client) Subscribe(h EventHandler)

Subscribe registers a handler. Multiple subscribers receive each event in the order they were registered. Handlers must not block.

func (*Client) Underlying

func (c *Client) Underlying() *libgm.Client

Underlying returns the wrapped *libgm.Client for callers that need access to libgm methods we haven't surfaced yet (ListContacts, FetchMessages, etc.). Higher-level operations should prefer the typed wrappers below.

func (*Client) WaitForReady

func (c *Client) WaitForReady(ctx context.Context) error

WaitForReady blocks until the libgm client emits *events.ClientReady or the context is cancelled. SendMessage and SendReaction need an established session before they can round-trip a response; ClientReady is the earliest signal that the session is up. The handler is removed before returning.

Subscribe(c.WaitForReady...) is not the right idiom — this method installs and removes a single-fire subscriber for you.

func (*Client) WaitForSettings

func (c *Client) WaitForSettings(ctx context.Context) error

WaitForSettings blocks until libgm emits the phone settings event. Send requests need its SIM metadata to match the browser client shape.

type EmojiRenderer

type EmojiRenderer func(emoji string)

EmojiRenderer is invoked once PairGoogle has the phone confirmation emoji.

type EventHandler

type EventHandler func(evt any)

EventHandler is invoked for each event delivered by libgm. The argument type is one of the concrete types in pkg/libgm/events or pkg/libgm/gmproto.

type PairResult

type PairResult struct {
	PhoneID     string
	SessionPath string
}

PairResult is returned by Pair on success. PhoneID identifies the paired device; SessionPath is where the persisted AuthData lives.

func Pair

func Pair(ctx context.Context, layout paths.Layout, logger zerolog.Logger, render QRRenderer) (*PairResult, error)

Pair runs the QR pairing flow. It writes session.json on success and returns the paired phone ID. Cancellable via ctx; otherwise bounded by PairTimeout. Existing session.json (if any) is overwritten on success.

func PairGoogle

func PairGoogle(ctx context.Context, layout paths.Layout, logger zerolog.Logger, cookies map[string]string, render EmojiRenderer) (*PairResult, error)

PairGoogle runs the Google account emoji pairing flow with caller-supplied cookies. It writes session.json on success and returns the paired phone ID.

type QRRenderer

type QRRenderer func(qrURL string)

QRRenderer is invoked once Pair has the QR URL ready. The implementation is responsible for displaying it (terminal QR, plain URL, etc.).

type ReactionAction

type ReactionAction int

ReactionAction selects ADD / REMOVE / SWITCH semantics on SendReaction.

const (
	ReactionAdd ReactionAction = iota
	ReactionRemove
	ReactionSwitch
)

type SendTextResult

type SendTextResult struct {
	MessageID      string
	ConversationID string
	TmpID          string
}

SendTextResult describes a successful send.

Jump to

Keyboard shortcuts

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