hduhelp

package module
v0.3.27 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 19 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 cmd/hduhelp-sdk-gen generator in the upstream hduhelp-neo repo: 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")
// StaffID is required when the automatic tenant token targets a user.
req := academic.NewStudentInfoReqBuilder().
    StaffID("2025123456").
    Build()
resp, err := client.Academic.StudentInfo(ctx, req)
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, path, and header parameter, a .Body(*models.X) setter when the endpoint takes a body, and .Build(). For a user-data endpoint called with a tenant/app token, set the generated .StaffID(...) header parameter; a user token gets the target identity from the token and does not need it. 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

Generation is owned by the upstream hduhelp-neo repo: the OpenAPI spec, the spec normalizer, the oapi-codegen config, and the cmd/hduhelp-sdk-gen generator all live there. To change the SDK surface, change the API upstream; its release pipeline regenerates from swagger/openapi.yaml, builds and tests the result, and pushes the generated client and tag here. The generated files (models, service, client.gen.go) and the vendored openapi.yaml are not edited in this repo by hand.

Releasing

This repository is a generated mirror; releases are driven from the upstream hduhelp-neo repository. Bump the sdk key in its release.yml and push to main: that pipeline regenerates the SDK from the upstream swagger/openapi.yaml, pushes the vendored openapi.yaml and generated client here, and creates the annotated tag v<version>. Tagging is the entire publish step for a Go module — consumers then run go get github.com/hduhelp/hduhelp-neo-sdk-go@v<version>.

The vendored openapi.yaml, the generated files, the version, and the tags are all owned by that pipeline. Do not edit them here 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
	AdminNotice    *adminnotice.Service
	CampusLife     *campuslife.Service
	EmptySchedule  *emptyschedule.Service
	Feed           *feed.Service
	Graduate       *graduate.Service
	GroupChat      *groupchat.Service
	Health         *health.Service
	Identity       *identity.Service
	Inbox          *inbox.Service
	Knowledge      *knowledge.Service
	LibraryBooking *librarybooking.Service
	Messaging      *messaging.Service
	Notification   *notification.Service
	Subscription   *subscription.Service
	Upload         *upload.Service
	Volunteer      *volunteer.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