hduhelp

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 12 Imported by: 0

README

hduhelp-neo-sdk-go

The official Go SDK for the hduhelp-neo API, modeled on the Feishu (larksuite/oapi-sdk-go) ergonomics: a namespaced client, fluent per-endpoint request builders, automatic token management, and typed response wrappers.

client := hduhelp.NewClient(appID, appSecret)

req := academic.NewScheduleReqBuilder().
    SchoolYear("2025-2026").
    Semester(1).
    Build()

resp, err := client.Academic.Schedule(ctx, req)
if err != nil {
    return err
}
if !resp.Success() {
    log.Println(resp.Code, resp.Msg, resp.RequestID())
    return
}
use(resp.Data) // []models.ScheduleItem

Install

go get github.com/hduhelp/hduhelp-neo-sdk-go@latest

Requires Go 1.24+.

How it is built

The SDK is generated from the API's openapi.yaml in two layers:

  1. Models (models package) — plain typed structs for every schema, generated by oapi-codegen.
  2. Services (service/<name> packages) plus the top-level Client — the Feishu-style layer, generated by the custom generator in internal/gen: one service per API tag, a fluent request builder per endpoint, and a typed response wrapper per endpoint.

Auth and transport live in the hand-written core package.

Client construction

NewClient(appID, appSecret, ...ClientOption) works zero-config; options tune the rest:

Option Effect
hduhelp.WithBaseURL(url) Gateway base URL (default https://api.hduhelp.com).
hduhelp.WithHTTPClient(hc) Supply your own *http.Client.
hduhelp.WithReqTimeout(d) Per-request timeout for the built-in client (default 30s).
hduhelp.WithEnableTokenCache(b) Toggle automatic token management (default on).
hduhelp.WithPAT(token) Authenticate every call with a personal access token.
hduhelp.WithLogLevel(l) Log verbosity.

Authentication

App / tenant token (automatic)

With app credentials the client fetches, caches, and auto-refreshes the tenant_access_token (via /hduhelp-neo/open-apis/auth/v3/tenant_access_token/internal) and injects it as Authorization: Bearer <token>. You never touch the token endpoint.

client := hduhelp.NewClient("cli_xxx", "secret")
resp, err := client.Identity.AuthenUserInfoV1(ctx, identity.NewAuthenUserInfoV1ReqBuilder().Build())
Personal access token (PAT)
client := hduhelp.NewClient("", "", hduhelp.WithPAT("hduhelp_pat_xxx"))
Per-request auth override

Pass a trailing option to any call to override the client default for that call (precedence: user > tenant > PAT):

resp, err := client.Academic.Schedule(ctx, req, hduhelp.WithUserAccessToken(uat))
resp, err = client.Academic.Schedule(ctx, req, hduhelp.WithTenantAccessToken(tat))
resp, err = client.Academic.Schedule(ctx, req, hduhelp.WithPAT(pat))
User OAuth2 + PKCE

Build an authorize URL with an S256 PKCE challenge, redirect the user, then exchange the returned code with the saved code_verifier. UserTokenSource auto-refreshes and rotates the refresh token.

auth := client.UserAuth()
pkce, _ := hduhelp.GeneratePKCE()               // keep pkce.Verifier
url, _ := auth.AuthorizeURL(hduhelp.AuthorizeParams{
    RedirectURI: "https://app.example.com/callback",
    Scope:       "contact:user.id:read",
    State:       "xyz",
    PKCE:        pkce,
})
// ... redirect the user to url; on callback you receive `code` ...

tok, _ := auth.ExchangeCode(ctx, code, pkce.Verifier)
src := hduhelp.NewUserTokenSource(auth, tok)
uat, _ := src.Token(ctx)                          // valid access token, refreshed as needed
resp, err := client.Academic.Schedule(ctx, req, hduhelp.WithUserAccessToken(uat))

Request builders and responses

Each endpoint has New<Method>ReqBuilder() with a setter per query and path parameter, a .Body(*models.X) setter when the endpoint takes a body, and .Build(). Each call returns a typed *<Method>Resp embedding:

  • resp.Success() — true when the business code is 0.
  • resp.Code, resp.Msg — the response envelope.
  • resp.RequestID() — the server request id, for tracing.
  • resp.Data — the typed payload (*models.X, []models.X, or a scalar).
  • resp.StatusCode, resp.Header, resp.RawBody — the raw transport result.

Services: client.Academic, client.Identity, client.Admin, client.CampusLife, client.EmptySchedule, client.GroupChat, client.Feed, client.Subscription, client.Graduate, client.Health, client.Upload.

Regenerating

The SDK is generated from the vendored openapi.yaml. Refresh it after the API changes:

go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@v2.7.2
pip install pyyaml
make generate

make generate normalizes the spec, runs oapi-codegen for the models, and runs the custom generator for the services and client. CI regenerates on every push and fails if the committed models, service, or client.gen.go differ, so the checked-in code always matches the spec.

Releasing

Releases are driven by the version field in release.yaml:

  1. Regenerate from the latest openapi.yaml and commit.
  2. Bump version in release.yaml (major.minor.patch).
  3. Push to main.

The Release workflow reads version and, if the tag v<version> does not exist, creates and pushes it. That tag is the entire publish step for a Go module — consumers then run go get github.com/hduhelp/hduhelp-neo-sdk-go@v<version>. Tags are never pushed by hand.

License

MIT. See LICENSE.

Documentation

Overview

Package hduhelp is the entry point for the hduhelp-neo Go SDK, modeled on the Feishu (larksuite/oapi-sdk-go) ergonomics.

Construct a client with app credentials, then call namespaced services with fluent request builders:

client := hduhelp.NewClient(appID, appSecret)
req := academic.NewScheduleReqBuilder().SchoolYear("2025-2026").Semester(1).Build()
resp, err := client.Academic.Schedule(ctx, req)
if err != nil { return err }
if !resp.Success() { log.Println(resp.Code, resp.Msg, resp.RequestID()); return }
use(resp.Data)

The client fetches, caches, and auto-refreshes the tenant_access_token and injects it as `Authorization: Bearer <token>`. Override auth per call with the WithUserAccessToken / WithTenantAccessToken / WithPAT request options.

Index

Constants

View Source
const (
	LogLevelError = core.LogLevelError
	LogLevelWarn  = core.LogLevelWarn
	LogLevelInfo  = core.LogLevelInfo
	LogLevelDebug = core.LogLevelDebug
)

Log levels.

View Source
const DefaultBaseURL = core.DefaultBaseURL

DefaultBaseURL is the gateway used when WithBaseURL is not supplied.

Variables

View Source
var (
	WithBaseURL          = core.WithBaseURL
	WithHTTPClient       = core.WithHTTPClient
	WithReqTimeout       = core.WithReqTimeout
	WithEnableTokenCache = core.WithEnableTokenCache
	WithLogLevel         = core.WithLogLevel
)

Client construction options.

View Source
var (
	WithPAT               = core.WithPAT
	WithUserAccessToken   = core.WithUserAccessToken
	WithTenantAccessToken = core.WithTenantAccessToken
)

Auth options. WithPAT works both at construction (client default) and as a trailing per-request option; WithUserAccessToken and WithTenantAccessToken override auth for a single call.

View Source
var (
	GeneratePKCE       = core.GeneratePKCE
	S256Challenge      = core.S256Challenge
	NewUserTokenSource = core.NewUserTokenSource
)

PKCE / user-flow helpers.

Functions

This section is empty.

Types

type AuthorizeParams

type AuthorizeParams = core.AuthorizeParams

Option and token types re-exported so callers depend only on this package.

type Client

type Client struct {
	Academic      *academic.Service
	Admin         *admin.Service
	CampusLife    *campuslife.Service
	EmptySchedule *emptyschedule.Service
	Feed          *feed.Service
	Graduate      *graduate.Service
	GroupChat     *groupchat.Service
	Health        *health.Service
	Identity      *identity.Service
	Subscription  *subscription.Service
	Upload        *upload.Service
	// contains filtered or unexported fields
}

Client is a fully configured hduhelp-neo API client. Each field is a namespaced service; call endpoints as client.<Service>.<Method>(ctx, req, opts...).

func NewClient

func NewClient(appID, appSecret string, opts ...ClientOption) *Client

NewClient builds a client from app credentials. With no options it manages the tenant_access_token automatically; options tune the base URL, HTTP client, timeout, token caching, a default PAT, and log level.

func (*Client) Config

func (c *Client) Config() *core.Config

Config exposes the underlying client configuration.

func (*Client) UserAuth

func (c *Client) UserAuth() *core.UserAuth

UserAuth returns the OAuth2 + PKCE helper bound to this client's credentials.

type ClientOption

type ClientOption = core.ClientOption

Option and token types re-exported so callers depend only on this package.

type LogLevel

type LogLevel = core.LogLevel

Option and token types re-exported so callers depend only on this package.

type PKCE

type PKCE = core.PKCE

Option and token types re-exported so callers depend only on this package.

type RequestOption

type RequestOption = core.RequestOption

Option and token types re-exported so callers depend only on this package.

type UserAuth

type UserAuth = core.UserAuth

Option and token types re-exported so callers depend only on this package.

type UserToken

type UserToken = core.UserToken

Option and token types re-exported so callers depend only on this package.

type UserTokenSource

type UserTokenSource = core.UserTokenSource

Option and token types re-exported so callers depend only on this package.

Directories

Path Synopsis
Package models provides primitives to interact with the openapi HTTP API.
Package models provides primitives to interact with the openapi HTTP API.
service

Jump to

Keyboard shortcuts

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