mirror of
https://github.com/larksuite/cli.git
synced 2026-07-06 16:18:05 +08:00
117 lines
3.6 KiB
Go
117 lines
3.6 KiB
Go
// Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package minutes
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/larksuite/cli/internal/event"
|
|
"github.com/larksuite/cli/internal/validate"
|
|
)
|
|
|
|
const (
|
|
minutesDetailRetryDelay = 500 * time.Millisecond
|
|
minutesDetailMaxRetries = 2
|
|
)
|
|
|
|
// MinutesMinuteSourceOutput is the flattened minute source payload.
|
|
type MinutesMinuteSourceOutput struct {
|
|
SourceType string `json:"source_type,omitempty" desc:"Minute source type"`
|
|
SourceEntityID string `json:"source_entity_id,omitempty" desc:"Source entity ID"`
|
|
}
|
|
|
|
// MinutesMinuteGeneratedOutput is the flattened shape for minutes.minute.generated_v1.
|
|
type MinutesMinuteGeneratedOutput struct {
|
|
Type string `json:"type" desc:"Event type; always minutes.minute.generated_v1"`
|
|
EventID string `json:"event_id,omitempty" desc:"Globally unique event ID; safe for deduplication"`
|
|
Timestamp string `json:"timestamp,omitempty" desc:"Event delivery time (ms timestamp string); taken from header.create_time when present" kind:"timestamp_ms"`
|
|
MinuteToken string `json:"minute_token,omitempty" desc:"Minute token"`
|
|
Title string `json:"title,omitempty" desc:"Minute title"`
|
|
MinuteSource *MinutesMinuteSourceOutput `json:"minute_source,omitempty" desc:"Minute source metadata"`
|
|
}
|
|
|
|
func processMinutesMinuteGenerated(ctx context.Context, rt event.APIClient, raw *event.RawEvent, _ map[string]string) (json.RawMessage, error) {
|
|
var envelope struct {
|
|
Header struct {
|
|
EventID string `json:"event_id"`
|
|
EventType string `json:"event_type"`
|
|
CreateTime string `json:"create_time"`
|
|
} `json:"header"`
|
|
Event struct {
|
|
MinuteToken string `json:"minute_token"`
|
|
MinuteSource struct {
|
|
SourceType string `json:"source_type"`
|
|
SourceEntityID string `json:"source_entity_id"`
|
|
} `json:"minute_source"`
|
|
} `json:"event"`
|
|
}
|
|
if err := json.Unmarshal(raw.Payload, &envelope); err != nil {
|
|
return raw.Payload, nil //nolint:nilerr // passthrough on malformed payload so consumers still see the event
|
|
}
|
|
|
|
out := &MinutesMinuteGeneratedOutput{
|
|
Type: envelope.Header.EventType,
|
|
EventID: envelope.Header.EventID,
|
|
Timestamp: envelope.Header.CreateTime,
|
|
MinuteToken: envelope.Event.MinuteToken,
|
|
}
|
|
if out.Type == "" {
|
|
out.Type = raw.EventType
|
|
}
|
|
if src := envelope.Event.MinuteSource; src.SourceType != "" || src.SourceEntityID != "" {
|
|
out.MinuteSource = &MinutesMinuteSourceOutput{
|
|
SourceType: src.SourceType,
|
|
SourceEntityID: src.SourceEntityID,
|
|
}
|
|
}
|
|
|
|
if rt != nil && out.MinuteToken != "" {
|
|
fillMinutesMinuteGeneratedDetails(ctx, rt, out)
|
|
}
|
|
|
|
return json.Marshal(out)
|
|
}
|
|
|
|
func fillMinutesMinuteGeneratedDetails(ctx context.Context, rt event.APIClient, out *MinutesMinuteGeneratedOutput) {
|
|
if rt == nil || out == nil || out.MinuteToken == "" {
|
|
return
|
|
}
|
|
|
|
path := fmt.Sprintf(pathMinuteDetailFmt, validate.EncodePathSegment(out.MinuteToken))
|
|
|
|
type minuteDetailResp struct {
|
|
Data struct {
|
|
Minute struct {
|
|
Title string `json:"title"`
|
|
} `json:"minute"`
|
|
} `json:"data"`
|
|
}
|
|
|
|
for attempt := 0; attempt <= minutesDetailMaxRetries; attempt++ {
|
|
if attempt > 0 {
|
|
time.Sleep(minutesDetailRetryDelay)
|
|
}
|
|
|
|
raw, err := rt.CallAPI(ctx, "GET", path, nil)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
|
|
var resp minuteDetailResp
|
|
if err := json.Unmarshal(raw, &resp); err != nil {
|
|
continue
|
|
}
|
|
|
|
if resp.Data.Minute.Title == "" {
|
|
continue
|
|
}
|
|
|
|
out.Title = resp.Data.Minute.Title
|
|
return
|
|
}
|
|
}
|