Kyrux
Back

Integrations (OAuth2, Mail, Metrics)

🧪 Experimental — part of the core layer (kyrux/core), the same one used by APIs and NoSQL. Labeled "experimental" by the framework's own USE.md.

OAuth2 — core.Auth.OAuth2

Authorization Code flow, generic to any provider (Google, GitHub, an internal IdP) — you supply authURL/tokenURL (the golang.org/x/oauth2/endpoints package already has these for the most common providers).

import "kyrux/core"

c := core.New()
cfg, err := c.Auth.OAuth2("google",
    clientID, clientSecret,
    "https://accounts.google.com/o/oauth2/auth",
    "https://oauth2.googleapis.com/token",
    "https://myapp.com/callback",
    "email", "profile", // scopes
)

// returns a standard golang.org/x/oauth2 *oauth2.Config:
url := cfg.AuthCodeURL(state)
token, err := cfg.Exchange(ctx, code)
httpClient := cfg.Client(ctx, token)

Init fails fast if clientID/clientSecret or authURL/tokenURL are empty — an error when you build it, not on the first request.

Mail/SMTP — core.Mail.SMTP

Sends via plain net/smtp (no third-party library) — builds MIME multipart (alternative/mixed) itself, for text + HTML + attachments.

import (
    "kyrux/core"
    kymail "kyrux/core/mail"
)

c := core.New()
client, err := c.Mail.SMTP("principal", host, port, username, password, true) // true = STARTTLS

err = client.Send(ctx, kymail.Message{
    From:    "[email protected]",
    To:      []string{"[email protected]"},
    Subject: "Welcome",
    Text:    "Thanks for signing up.",
    HTML:    "<p>Thanks for signing up.</p>",
    Attachments: []kymail.Attachment{
        {Filename: "invoice.pdf", Content: pdfBytes, ContentType: "application/pdf"},
    },
})

Port 465 automatically uses implicit TLS (SMTPS) — detected from the port, no extra parameter needed: the TLS handshake starts before any SMTP protocol byte, so StartTLS doesn't come into play and the useTLS from the example above is ignored in that case. Any other port (e.g. 587) keeps the previous behavior — plain text with optional STARTTLS via useTLS.

Configure only does a plain-text TCP dial as a connectivity check (no TLS, even on port 465) before returning a usable client — it fails early if the server is unreachable, but the TLS handshake itself (implicit or STARTTLS) only happens on the first Send.

kymail.Sender is the interface (Send(ctx, Message) error) — besides SMTP, there are adapters for SendGrid (core/adapters/sendgrid) and AWS SES (core/adapters/ses) implementing the same interface. Neither has sugar on core.Mail (third-party SDK weight) — activate them via core.UseModule[kymail.Sender].

Metrics — Prometheus and OpenTelemetry

No sugar for either (third-party dependency) — activate via core.UseModule.

Prometheus — core/adapters/prometheus

import (
    "kyrux/core"
    prometheusadapter "kyrux/core/adapters/prometheus"
    prom "github.com/prometheus/client_golang/prometheus"
)

c := core.New()
metrics, err := core.UseModule[*prometheusadapter.Client](
    c, prometheusadapter.New("principal"), "observability.prometheus.principal",
)

requestsTotal := prom.NewCounter(prom.CounterOpts{
    Name: "kyrux_requests_total",
    Help: "Total requests",
})
metrics.MustRegister(requestsTotal)

r, _ := c.API.REST(":8080")
r.HandlePrefix("/metrics", metrics.Handler()) // same pattern used to mount SOAP

c.Run()

Configure already pre-registers Go's standard runtime collectors (goroutines, GC, etc.). The registry is isolated (its own *prometheus.Registry) — it doesn't use the global DefaultRegisterer, so multiple instances don't collide.

OpenTelemetry — core/adapters/opentelemetry

Follows the same pattern (New + core.UseModule), OTLP/HTTP export only (no gRPC, no other exporters). See the package directly — it doesn't have its own doc page yet.