webhook

package
v0.7.3 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package webhook 提供事件驱动的 Webhook 通知:按事件类型过滤、自定义 header、 可选 body 模板、可选 HMAC 签名,异步触发并带指数退避重试。

可靠投递增强(可选,通过 WithStore/WithDLQ 启用):

  • 幂等去重:Event.EventID 非空时,同一 (endpoint, eventID) 只投递一次;
  • 投递状态追踪:Store 记录每次投递的最终状态(delivered/failed);
  • DLQ:重试耗尽后投递入死信队列,供后续重放(Replay)。

at-least-once + 去重语义。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DLQ

type DLQ interface {
	// Push 入队一条死信。
	Push(rec DeliveryRecord)
	// Pop 取出最早一条死信(无则返回 ok=false)。
	Pop() (DeliveryRecord, bool)
	// Len 当前死信数量。
	Len() int
}

DLQ 死信队列:收集重试耗尽的投递,供后续重放。

type DeliveryRecord

type DeliveryRecord struct {
	EventID     string
	EndpointURL string
	Status      DeliveryStatus
	Attempts    int
	LastErr     string
	At          time.Time
}

DeliveryRecord 一次投递的最终记录(成功或重试耗尽后)。

type DeliveryStatus

type DeliveryStatus string

DeliveryStatus 投递最终状态。

const (
	StatusDelivered DeliveryStatus = "delivered"
	StatusFailed    DeliveryStatus = "failed"
)

type Endpoint

type Endpoint struct {
	URL string
	// Events 为空表示接收所有事件;否则仅接收 Type 在列表中的事件。
	Events []string
	// Headers 附加请求头。
	Headers map[string]string
	// Secret 非空时对 body 做 HMAC-SHA256 签名,写入 X-Webhook-Signature: sha256=<hex>。
	Secret string
	// BodyTemplate 为空时 body = JSON(Payload);否则用 text/template 渲染整个 Event
	//(可用 {{.Type}} / {{.Payload.Field}})。
	BodyTemplate string
	// contains filtered or unexported fields
}

Endpoint 描述一个 Webhook 端点。

type Event

type Event struct {
	Type    string
	Payload any
	EventID string // 业务幂等键;为空则不去重
}

Event 是一次通知的事件:Type 用于端点过滤,Payload 作为默认 body 与模板数据。 EventID 非空时启用幂等去重(同一 endpoint+EventID 只投递一次)。

type MemDLQ

type MemDLQ struct {
	// contains filtered or unexported fields
}

MemDLQ 是 DLQ 的内存实现:用 slice 做 FIFO 队列。

func NewMemDLQ

func NewMemDLQ() *MemDLQ

NewMemDLQ 创建空内存死信队列。

func (*MemDLQ) Len

func (q *MemDLQ) Len() int

func (*MemDLQ) Pop

func (q *MemDLQ) Pop() (DeliveryRecord, bool)

func (*MemDLQ) Push

func (q *MemDLQ) Push(rec DeliveryRecord)

type MemStore

type MemStore struct {
	// contains filtered or unexported fields
}

MemStore 是 Store 的内存实现:用 map 做 (endpoint,eventID) 去重 + 状态记录。 适合单进程;多进程需用 Redis/DB 实现 Store 接口。

func NewMemStore

func NewMemStore() *MemStore

NewMemStore 创建空内存 store。

func (*MemStore) MarkDelivered

func (s *MemStore) MarkDelivered(endpointURL, eventID string) bool

func (*MemStore) RecordDelivered

func (s *MemStore) RecordDelivered(rec DeliveryRecord)

func (*MemStore) RecordFailed

func (s *MemStore) RecordFailed(rec DeliveryRecord)

func (*MemStore) Records

func (s *MemStore) Records() []DeliveryRecord

Records 返回所有投递记录的快照(成功+失败)。

func (*MemStore) UnmarkDelivered added in v0.3.0

func (s *MemStore) UnmarkDelivered(endpointURL, eventID string)

type Notifier

type Notifier struct {
	// contains filtered or unexported fields
}

Notifier 管理一组端点并触发通知。

func New

func New(opts ...Option) *Notifier

New 创建一个 Notifier。

func (*Notifier) Add

func (n *Notifier) Add(ep Endpoint) error

Add 注册端点;若带 BodyTemplate 会预编译,模板非法则返回错误。

func (*Notifier) Notify

func (n *Notifier) Notify(ctx context.Context, ev Event)

Notify 异步把 ev 投递给所有匹配的端点(按 Type 过滤),每个端点独立重试。 立即返回,不阻塞调用方;失败通过 WithErrorHandler 上报。 若启用 Store 且 ev.EventID 非空:同一 (endpoint, eventID) 已投递过则跳过。

func (*Notifier) Replay

func (n *Notifier) Replay(ctx context.Context) (bool, error)

Replay 从 DLQ 取一条死信重新投递。返回 (是否取到, 投递结果)。 无 DLQ 时返回 false。

type Option

type Option func(*Notifier)

Option 配置 Notifier。

func WithBackoff

func WithBackoff(d time.Duration) Option

WithBackoff 设置首次重试退避(指数增长),默认 200ms。

func WithDLQ

func WithDLQ(q DLQ) Option

WithDLQ 启用死信队列:重试耗尽后投递入队,供 Replay 重放。

func WithErrorHandler

func WithErrorHandler(fn func(ep Endpoint, ev Event, err error)) Option

WithErrorHandler 设置最终失败回调(用于日志/告警)。

func WithRetries

func WithRetries(n int) Option

WithRetries 设置失败重试次数(额外次数),默认 2。

func WithStore

func WithStore(s Store) Option

WithStore 启用幂等去重 + 投递状态追踪。

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout 设置单次请求超时,默认 10s。

type Store

type Store interface {
	// MarkDelivered 标记 (endpoint, eventID) 为"投递中/已投递"。
	// 返回 true 表示本次标记生效(之前未标记过),false 表示已标记过(应跳过)。
	MarkDelivered(endpointURL, eventID string) bool
	// UnmarkDelivered 撤销 MarkDelivered 的标记(投递失败时调用,允许后续重试)。
	UnmarkDelivered(endpointURL, eventID string)
	// RecordFailed 记录一次最终失败的投递(用于状态追踪)。
	RecordFailed(rec DeliveryRecord)
	// RecordDelivered 记录一次成功的投递(用于状态追踪)。
	RecordDelivered(rec DeliveryRecord)
}

Store 持久化投递状态与幂等去重。实现方对接 Redis/DB/内存。 并发安全由实现方保证。

Jump to

Keyboard shortcuts

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