English | 中文
Go SDK for the Flashduty API. Provides typed methods for incident management, on-call scheduling, status pages, notification templates, and more.
go get github.com/flashcatcloud/flashduty-sdkRequires Go 1.24+.
package main
import (
"context""fmt""log"
flashduty "github.com/flashcatcloud/flashduty-sdk"
)
funcmain() {
client, err:=flashduty.NewClient("your-app-key")
iferr!=nil {
log.Fatal(err)
}
incidents, err:=client.ListIncidents(context.Background(), &flashduty.ListIncidentsInput{
Progress: "Triggered",
StartTime: 1710000000,
EndTime: 1710086400,
})
iferr!=nil {
log.Fatal(err)
}
for_, inc:=rangeincidents.Incidents {
fmt.Printf("[%s] %s (channel: %s)\n", inc.Severity, inc.Title, inc.ChannelName)
}
}client, err:=flashduty.NewClient("your-app-key",
flashduty.WithBaseURL("https://custom-api.example.com"),
flashduty.WithTimeout(10*time.Second),
flashduty.WithUserAgent("my-app/1.0"),
flashduty.WithHTTPClient(customHTTPClient),
flashduty.WithLogger(myLogger),
flashduty.WithRequestHeaders(staticHeaders),
flashduty.WithRequestHook(func(req*http.Request) {
// Inject per-request headers (e.g., W3C Trace Context)req.Header.Set("traceparent", traceID)
}),
)| Option | Default | Description |
|---|---|---|
WithBaseURL | https://api.flashcat.cloud | API base URL |
WithTimeout | 30s | HTTP client timeout |
WithUserAgent | flashduty-go-sdk | User-Agent header |
WithHTTPClient | Default http.Client | Custom HTTP client |
WithLogger | slog-based logger | Custom logger implementing Logger interface |
WithRequestHeaders | none | Static headers included in every request |
WithRequestHook | none | Callback invoked on every outgoing request before it is sent |
The User-Agent can be updated after client creation (e.g., per-session):
client.SetUserAgent("my-app/2.0 (client-name/1.2)")The SDK uses a pluggable logger. The default implementation wraps log/slog.
typeLoggerinterface {
Debug(msgstring, keysAndValues...any)
Info(msgstring, keysAndValues...any)
Warn(msgstring, keysAndValues...any)
Error(msgstring, keysAndValues...any)
}To adapt logrus or other backends:
typelogrusAdapterstruct{ *logrus.Logger }
func (a*logrusAdapter) Info(msgstring, kv...any) { a.WithFields(kvToFields(kv)).Info(msg) }
func (a*logrusAdapter) Warn(msgstring, kv...any) { a.WithFields(kvToFields(kv)).Warn(msg) }
func (a*logrusAdapter) Error(msgstring, kv...any) { a.WithFields(kvToFields(kv)).Error(msg) }
func (a*logrusAdapter) Debug(msgstring, kv...any) { a.WithFields(kvToFields(kv)).Debug(msg) }
funckvToFields(kv []any) logrus.Fields {
fields:=make(logrus.Fields, len(kv)/2)
fori:=0; i+1<len(kv); i+=2 {
ifkey, ok:=kv[i].(string); ok {
fields[key] =kv[i+1]
}
}
returnfields
}// List incidents by IDs or filters (time-based queries require StartTime and EndTime)client.ListIncidents(ctx, &ListIncidentsInput{...}) (*ListIncidentsOutput, error)
// Get timeline events for one or more incidentsclient.GetIncidentTimelines(ctx, incidentIDs) ([]IncidentTimelineOutput, error)
// Get alerts for one or more incidentsclient.ListIncidentAlerts(ctx, incidentIDs, limit) ([]IncidentAlertsOutput, error)
// Find similar historical incidentsclient.ListSimilarIncidents(ctx, incidentID, limit) (*ListIncidentsOutput, error)
// Create a new incidentclient.CreateIncident(ctx, &CreateIncidentInput{...}) (any, error)
// Update incident fields (title, description, severity, custom fields)client.UpdateIncident(ctx, &UpdateIncidentInput{...}) ([]string, error)
// Acknowledge incidentsclient.AckIncidents(ctx, incidentIDs) error// Close (resolve) incidentsclient.CloseIncidents(ctx, incidentIDs) error// List members by person IDs, name, or emailclient.ListMembers(ctx, &ListMembersInput{...}) (*ListMembersOutput, error)// List teams by team IDs or nameclient.ListTeams(ctx, &ListTeamsInput{...}) (*ListTeamsOutput, error)// List channels by IDs or name (name filtering is case-insensitive substring match)client.ListChannels(ctx, &ListChannelsInput{...}) (*ListChannelsOutput, error)// List escalation rules for a channel (enriched with person/team/schedule names)client.ListEscalationRules(ctx, channelID) (*ListEscalationRulesOutput, error)// List custom field definitions, optionally filtered by IDs or nameclient.ListFields(ctx, &ListFieldsInput{...}) (*ListFieldsOutput, error)// List change records (deployments, configurations) with enriched namesclient.ListChanges(ctx, &ListChangesInput{...}) (*ListChangesOutput, error)// List status pages, optionally filtered by page IDsclient.ListStatusPages(ctx, pageIDs) ([]StatusPage, error)
// List active incidents or maintenances on a status pageclient.ListStatusChanges(ctx, &ListStatusChangesInput{...}) (*ListStatusChangesOutput, error)
// Create an incident on a status pageclient.CreateStatusIncident(ctx, &CreateStatusIncidentInput{...}) (any, error)
// Add a timeline update to a status page incident or maintenanceclient.CreateChangeTimeline(ctx, &CreateChangeTimelineInput{...}) error// Fetch the preset (default) notification template for a channelclient.GetPresetTemplate(ctx, &GetPresetTemplateInput{...}) (*GetPresetTemplateOutput, error)
// Validate and preview a notification template with size-limit checksclient.ValidateTemplate(ctx, &ValidateTemplateInput{...}) (*ValidateTemplateOutput, error)These package-level functions return compiled-in reference data for template authoring:
// Available template variables (40 variables across 7 categories)flashduty.TemplateVariables() []TemplateVariable// Custom Flashduty template functions (19 functions)flashduty.TemplateCustomFunctions() []TemplateFunction// Commonly used Sprig template functions (19 functions)flashduty.TemplateSprigFunctions() []TemplateFunction// Valid notification channel identifiers (13 channels)flashduty.ChannelEnumValues() []stringSupported channels: dingtalk, dingtalk_app, feishu, feishu_app, wecom, wecom_app, slack, slack_app, telegram, teams_app, email, sms, zoom.
Channel size limits and channel-to-field mappings are available via flashduty.ChannelSizeLimits and flashduty.TemplateChannels.
Note: Static template data is compiled into the SDK. Platform-side additions require an SDK release.
Most query methods automatically enrich raw API data with human-readable names. For example, ListIncidents resolves CreatorID to CreatorName, ChannelID to ChannelName, and responder person IDs to names and emails.
Enrichment uses concurrent batch fetches via errgroup. For methods like ListChanges and ListChannels, enrichment failures are best-effort -- the primary data is still returned even if name resolution fails.
The SDK supports JSON and TOON (Token-Oriented Object Notation) serialization:
data, err:=flashduty.Marshal(incidents, flashduty.OutputFormatJSON)
data, err:=flashduty.Marshal(incidents, flashduty.OutputFormatTOON)
format:=flashduty.ParseOutputFormat("toon") // defaults to JSON for unknown valuesAPI errors are returned as *DutyError which implements the error interface:
incidents, err:=client.ListIncidents(ctx, input)
iferr!=nil {
vardutyErr*flashduty.DutyErroriferrors.As(err, &dutyErr) {
fmt.Printf("API error [%s]: %s\n", dutyErr.Code, dutyErr.Message)
}
}Requires Go 1.24+ and golangci-lint v2.
go test -race ./... # Run tests with race detection
golangci-lint run # Run the linterContributions are welcome! Please read CONTRIBUTING.md before opening a pull request, and note our Code of Conduct.
This project is licensed under the MIT License - see the LICENSE file for details.