Files
smartmate/backend/notification/provider.go
Losita 0a014f7472 Version: 0.9.60.dev.260430
后端:
1.接入主动调度 worker 与飞书通知链路
- 新增 due job scanner 与 active_schedule.triggered workflow
- 接入 notification.feishu.requested handler、飞书 webhook provider 和用户通知配置接口
- 支持 notification_records 去重、重试、skipped/dead 状态流转
- 完成 api / worker / all 启动模式装配与主动调度验收记录
2.后续要做的就是补全从异常发生到给用户推送消息之间的逻辑缺口
2026-04-30 23:45:27 +08:00

89 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package notification
import "context"
const (
// ChannelFeishu 表示当前通知记录走飞书通道。
ChannelFeishu = "feishu"
)
const (
// FeishuErrorCodeProviderTimeout 表示 provider 超时,属于可重试错误。
FeishuErrorCodeProviderTimeout = "provider_timeout"
// FeishuErrorCodeProviderRateLimited 表示 provider 限流,属于可重试错误。
FeishuErrorCodeProviderRateLimited = "provider_rate_limited"
// FeishuErrorCodeProvider5xx 表示 provider 服务端异常,属于可重试错误。
FeishuErrorCodeProvider5xx = "provider_5xx"
// FeishuErrorCodeNetworkError 表示网络层异常,属于可重试错误。
FeishuErrorCodeNetworkError = "network_error"
// FeishuErrorCodeRecipientMissing 表示缺少接收方,属于不可恢复错误。
FeishuErrorCodeRecipientMissing = "recipient_missing"
// FeishuErrorCodeInvalidURL 表示目标链接非法,属于不可恢复错误。
FeishuErrorCodeInvalidURL = "invalid_url"
// FeishuErrorCodeProviderAuthFailed 表示 provider 认证失败,属于不可恢复错误。
FeishuErrorCodeProviderAuthFailed = "provider_auth_failed"
// FeishuErrorCodePayloadInvalid 表示请求体非法,属于不可恢复错误。
FeishuErrorCodePayloadInvalid = "payload_invalid"
)
// FeishuSendOutcome 表示 provider 对一次投递尝试的分类结果。
//
// 职责边界:
// 1. 只表达 provider 层对“这次投递”是否成功、是否可重试的判断;
// 2. 不直接承载 notification_records 的状态机,状态流转由 NotificationService 决定;
// 3. future webhook/open_id provider 只要返回同一套枚举,即可复用现有重试逻辑。
type FeishuSendOutcome string
const (
FeishuSendOutcomeSuccess FeishuSendOutcome = "success"
FeishuSendOutcomeTemporaryFail FeishuSendOutcome = "temporary_fail"
FeishuSendOutcomePermanentFail FeishuSendOutcome = "permanent_fail"
FeishuSendOutcomeSkipped FeishuSendOutcome = "skipped"
)
// FeishuSendRequest 是通知服务传给 provider 的稳定输入。
//
// 职责边界:
// 1. 只描述 provider 真正发消息所需的信息;
// 2. 不暴露 GORM model避免 provider 依赖数据库细节;
// 3. 同时保留审计字段,方便 mock/webhook provider 记录请求摘要。
type FeishuSendRequest struct {
NotificationID int64 `json:"notification_id"`
UserID int `json:"user_id"`
TriggerID string `json:"trigger_id"`
PreviewID string `json:"preview_id"`
TriggerType string `json:"trigger_type"`
TargetType string `json:"target_type"`
TargetID int `json:"target_id"`
TargetURL string `json:"target_url"`
MessageText string `json:"message_text"`
FallbackUsed bool `json:"fallback_used"`
TraceID string `json:"trace_id,omitempty"`
AttemptCount int `json:"attempt_count"`
}
// FeishuSendResult 是 provider 对外返回的投递结果。
//
// 职责边界:
// 1. outcome 决定 NotificationService 应该进入 sent / failed / dead 中哪一条路径;
// 2. request/response payload 仅用于落库审计,不要求与任意具体 SDK 强绑定;
// 3. error_code 需要尽量稳定,便于后续按错误码做告警和排障。
type FeishuSendResult struct {
Outcome FeishuSendOutcome `json:"outcome"`
ProviderMessageID string `json:"provider_message_id,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
RequestPayload any `json:"request_payload,omitempty"`
ResponsePayload any `json:"response_payload,omitempty"`
}
// FeishuProvider 是飞书投递能力的抽象边界。
//
// 职责边界:
// 1. 负责把最终文案发给具体 provider
// 2. 不负责 notification_records 的创建、去重、状态机和重试节奏;
// 3. 后续新增 WebhookFeishuProvider / OpenIDFeishuProvider 时,只需实现这个接口。
type FeishuProvider interface {
Send(ctx context.Context, req FeishuSendRequest) (FeishuSendResult, error)
}