feat(channels): add subscriber fan-out delivery
When messages are sent to a channel, subscribers now receive a copy in their inbox with [channel:name] prefix in the subject. Closes: gt-3rldf6 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -804,6 +804,7 @@ func (r *Router) sendToAnnounce(msg *Message) error {
|
|||||||
|
|
||||||
// sendToChannel delivers a message to a beads-native channel.
|
// sendToChannel delivers a message to a beads-native channel.
|
||||||
// Creates a message with channel:<name> label for channel queries.
|
// Creates a message with channel:<name> label for channel queries.
|
||||||
|
// Also fans out delivery to each subscriber's inbox.
|
||||||
// Retention is enforced by the channel's EnforceChannelRetention after message creation.
|
// Retention is enforced by the channel's EnforceChannelRetention after message creation.
|
||||||
func (r *Router) sendToChannel(msg *Message) error {
|
func (r *Router) sendToChannel(msg *Message) error {
|
||||||
channelName := parseChannelName(msg.To)
|
channelName := parseChannelName(msg.To)
|
||||||
@@ -872,7 +873,23 @@ func (r *Router) sendToChannel(msg *Message) error {
|
|||||||
// Enforce channel retention policy (on-write cleanup)
|
// Enforce channel retention policy (on-write cleanup)
|
||||||
_ = b.EnforceChannelRetention(channelName)
|
_ = b.EnforceChannelRetention(channelName)
|
||||||
|
|
||||||
// No notification for channel messages - readers poll or check on their own schedule
|
// Fan-out delivery: send a copy to each subscriber's inbox
|
||||||
|
if len(fields.Subscribers) > 0 {
|
||||||
|
for _, subscriber := range fields.Subscribers {
|
||||||
|
// Skip self-delivery (don't notify the sender)
|
||||||
|
if isSelfMail(msg.From, subscriber) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a copy for this subscriber with channel context in subject
|
||||||
|
msgCopy := *msg
|
||||||
|
msgCopy.To = subscriber
|
||||||
|
msgCopy.Subject = fmt.Sprintf("[channel:%s] %s", channelName, msg.Subject)
|
||||||
|
|
||||||
|
// Best-effort delivery - don't fail the channel send if one subscriber fails
|
||||||
|
_ = r.sendToSingle(&msgCopy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user