跳转到主要内容

概述


go-flashduty 是 Flashduty 官方开源的 Go 客户端,覆盖 Flashduty Open API 的每一个 REST 接口。它采用与 go-github 一致的设计风格——服务分组、类型化请求与响应、可组合传输层——并与 OpenAPI 规范保持严格 1:1:每个方法对应且仅对应一次 HTTP 调用,返回 (*T, *Response, error),不做任何跨接口的隐式聚合或增强。 SDK 当前覆盖 253 个接口27 个服务,全部由 Flashduty OpenAPI 规范生成,经单元测试覆盖,并针对线上 API 做过端到端验证。
SDK 故意保持”薄”。诸如短 ID 解析、跨接口编排等消费侧逻辑应放在调用方(CLI / MCP)中,而不是塞进 SDK 或滥用某个接口。这样 SDK 始终与 API 一一对应,可预测、可生成、可校验。
模块路径为 github.com/flashcatcloud/go-flashduty,包名为 flashduty,源码遵循 Apache-2.0 协议开源在 flashcatcloud/go-flashduty

Open API 参考

全部接口的请求参数与响应字段说明。

命令行工具

在终端中直接操作 Flashduty 的 CLI。

安装


1

要求 Go 1.24+

请确认本地 Go 工具链版本不低于 1.24。
2

获取依赖

3

导入包

快速开始


以下是一个最小可运行示例:构造客户端、列出处于”已触发”状态的故障,并处理返回的三元组 (数据, *Response, error)
每次调用都返回三个值:
app_key 用于鉴权,SDK 会自动将其作为查询参数注入每个请求。请在 Flashduty 控制台的”推送集成”或团队配置中获取对应的 app_key

创建客户端


NewClient 接收 app_key 与零到多个 Optionapp_key 为空会直接返回错误。默认 Base URL 为 https://api.flashcat.cloud,默认 HTTP 超时为 30 秒,默认 User-Agent 为 go-flashduty
私有化部署:用 WithBaseURL 将客户端指向您自有的 Flashduty 网关地址即可,其余调用方式完全不变。

服务与方法


接口按服务分组挂在客户端上:调用约定统一为 client.<Service>.<Method>(ctx, req),返回 (*T, *Response, error)。例如 client.Incidents.List(ctx, req)client.Sessions.Info(ctx, req)
所有标识符、服务字段名与方法名均与生成代码保持一致。具体每个服务有哪些方法、请求与响应类型,请以 services_gen.go 与各服务文件,以及 Open API 参考 为准。

响应时间戳


响应中的时间字段不再是裸整数,而是自描述的 Timestamp(Unix 秒)或 TimestampMilli(毫秒)类型。它们序列化为本地时区的 RFC3339 字符串,因此 JSON、日志以及面向 LLM 的输出都直接可读;原始 epoch 仍只需一次方法调用即可取到。
  • 序列化(出站):非零值序列化为带引号的 RFC3339 字符串(TimestampMilli 用 RFC3339Nano 以保留毫秒精度)。零值序列化为裸整数 0——一个”未设置”哨兵,而非 1970 年的日期,并被 json:",omitempty" 丢弃。
  • 反序列化(入站):既兼容数字 epoch(线上原始形态),也兼容 RFC3339 字符串(使序列化后的值可无损往返),还接受 null(→ 0)。
请求侧时间字段仍为 int64,API 在 wire 上要求数字 epoch。注意:多数接口取,但 RUM 与 webhook 历史相关接口取毫秒

分页


所有列表接口共享 ListOptions,将其内嵌在请求结构体中即可。零值会被省略,不会覆盖服务端默认值(后端默认 p=1limit=20)。 响应侧,*Response 携带 TotalHasNextPageSearchAfterCtx。推荐用 search-after 游标逐页遍历:

错误处理


任何未成功的调用——无论是信封中携带了错误,还是 HTTP 状态非 2xx——都会返回 *ErrorResponse。它带有 CodeMessageRequestID 字段,排障时把 RequestID 提供给支持团队即可定位。 当 API 返回 429 时,错误被提升为 *RateLimitError:它内嵌 *ErrorResponse(所以 errors.As*ErrorResponse 仍然成立),并额外带上 RetryAfter 提示。
类型化判定函数能省去字符串比较,并能穿透被包裹的错误(内部用 errors.As):

重试


核心客户端不内置自动重试。请通过传输层组合可选的 retry 子包——一个安全默认的重试型 http.RoundTripper github.com/flashcatcloud/go-flashduty/retry 的特性:
  • 重试条件:HTTP 429、任意 5xx(状态码 ≥ 500),以及传输错误。其他 4xx 与所有 2xx/3xx 立即返回。
  • 退避策略:确定性指数退避(MinWait * 2^attempt,每次上限为 MaxWait);无随机抖动。存在合法的整数 Retry-After 头时,以其为准(同样不超过 MaxWait)。
  • 安全回放:仅当请求体可回放(req.Body 为 nil 或 req.GetBody 非空)时才重试,每次重试都在请求的克隆上重建请求体,绝不修改调用方的原始 *http.Request。SDK 构造的所有请求都设置了 GetBody,因此 POST 请求体都可安全回放。
  • 尊重取消:等待退避期间若请求 context 被取消,立即返回 context 错误。
retry 子包是纯 net/http 实现,刻意不导入父级 flashduty 包,因此永远不会引入循环依赖。retry.New()&retry.Transport{}(零值)都开箱即用。

流式导出


client.Sessions.Export 用于导出一个 AI SRE 会话的完整事件转录,返回的是 io.ReadCloser(NDJSON 流,application/x-ndjson),而非 JSON 信封。首行始终是一条 session_meta 信封,其后每行是一个会话事件;当 req.IncludeSubagents 为 true 时,每条 subagent_dispatch 行后会跟随子会话自身的完整事件流。 由于响应体可能很大,应当逐行读取并直接写入文件,不要把整段转录缓冲进内存。返回的 io.ReadCloser 是活动 HTTP 响应体,由调用方持有并必须 Close(defer 关闭即正确)。配合 NewExportScanner 可按行扫描,DecodeExportLine 可将一行解码为 ExportLine
NewExportScanner 配置的单行缓冲区足以容纳转录中较宽的事件行(如 tool 输出、LLM 调用),不受默认 64KB token 上限限制。任何非 2xx 状态下,响应体仍是常规 JSON 错误信封——Export 会读取并关闭它,返回类型化错误(*ErrorResponse,429 时为 *RateLimitError),此时 io.ReadClosernil,与其他生成接口行为一致。