Files
go-caatsm/internal/infra/nats/publisher.go
T

75 lines
1.6 KiB
Go

package nats
import (
"caatsm/internal/adapter"
"caatsm/internal/domain"
"caatsm/internal/infra/config"
"encoding/json"
"fmt"
"github.com/google/uuid"
"github.com/nats-io/nats.go"
"go.uber.org/zap"
)
// Publisher publishes messages to NATS JetStream
type Publisher struct {
js nats.JetStreamContext
cfg *config.Config
logger *zap.Logger
}
// ProvidePublisher creates a NATS publisher
func ProvidePublisher(
js nats.JetStreamContext,
cfg *config.Config,
logger *zap.Logger,
) (adapter.Publisher, error) {
return &Publisher{
js: js,
cfg: cfg,
logger: logger,
}, nil
}
// Publish publishes a message
func (p *Publisher) Publish(message interface{}) error {
topic := p.cfg.Publisher.Topic
if topic == "" {
return fmt.Errorf("publisher topic is not configured")
}
// Marshal message to JSON
messageBytes, err := json.Marshal(message)
if err != nil {
return fmt.Errorf("failed to marshal message: %w", err)
}
// Build JetStream message to attach dedup headers
jsMsg := nats.NewMsg(topic)
jsMsg.Data = messageBytes
switch typed := message.(type) {
case *domain.ParsedMessage:
if typed != nil && typed.Uuid != "" {
jsMsg.Header.Set("Nats-Msg-Id", typed.Uuid)
} else {
jsMsg.Header.Set("Nats-Msg-Id", uuid.NewString())
}
default:
jsMsg.Header.Set("Nats-Msg-Id", uuid.NewString())
}
// Publish to JetStream
_, err = p.js.PublishMsg(jsMsg)
if err != nil {
return fmt.Errorf("failed to publish message: %w", err)
}
p.logger.Debug("Published message",
zap.String("topic", topic),
zap.Int("size", len(messageBytes)),
)
return nil
}