Files
SYNITY 21ad48de16 fix(bitrix24): preserve whisper visibility on intermediate replies [B24:2794] (#1449)
fix(bitrix24): preserve whisper visibility on intermediate replies (#1449)
2026-07-18 10:51:24 +07:00

60 lines
2.7 KiB
Go

package channels
// routingMetaKeys enumerates the metadata keys that must survive the hop from
// inbound RunContext.Metadata into outbound OutboundMessage.Metadata so that
// replies, block replies, retries, and placeholder updates all land in the
// correct thread / topic / subgroup routing bucket on each channel.
var routingMetaKeys = []string{
"message_thread_id", // telegram forum topics
"local_key", // composite chat-id suffix
"group_id", // legacy group identifier
"feishu_reply_target_id", // feishu/lark thread reply routing
"fb_mode", // facebook messenger vs comment routing
"sender_id", // facebook sender for first-inbox / pancake sender for private-reply
"page_id", // facebook page routing
"reply_to_comment_id", // facebook/pancake comment reply target
"pancake_mode", // pancake inbox vs comment routing
"post_id", // pancake: post id for template vars
"display_name", // pancake: commenter display name for template vars
// bitrix24 whisper/public visibility. MUST survive into intermediate
// replies (quick-ack, progress, reasoning bubbles, block replies) so a
// whisper-mode turn doesn't leak its FIRST (intermediate) message to the
// external connector while only the final answer is whispered. Literal
// string mirrors bitrix24.MetaKeyVisibility (kept as a string here to
// avoid a channels→bitrix24 import cycle). Non-bitrix channels ignore it.
"bitrix_visibility",
}
var finalReplyMetaKeys = append([]string{
"placeholder_key", // final outbound can update placeholder; block replies must not
}, routingMetaKeys...)
func copySelectedMeta(src map[string]string, keys []string) map[string]string {
out := make(map[string]string)
for _, k := range keys {
if v := src[k]; v != "" {
out[k] = v
}
}
return out
}
// CopyFinalRoutingMeta copies the routing metadata required for final outbound
// delivery after an inbound message has been processed by the agent loop.
func CopyFinalRoutingMeta(src map[string]string) map[string]string {
return copySelectedMeta(src, finalReplyMetaKeys)
}
// CopyFollowupRoutingMeta copies routing metadata for additional outbound
// messages after the first final reply. It preserves thread/topic routing but
// does not reuse placeholder or reply-to metadata reserved for the first reply.
func CopyFollowupRoutingMeta(src map[string]string) map[string]string {
return copyRoutingMeta(src)
}
// copyRoutingMeta copies only the subset safe for intermediate block replies,
// retries, and placeholder updates.
func copyRoutingMeta(src map[string]string) map[string]string {
return copySelectedMeta(src, routingMetaKeys)
}