picoclaw/pkg/channels/events.go

198 lines
4.5 KiB
Go
Raw Normal View History

package channels
import (
"github.com/sipeed/picoclaw/pkg/bus"
runtimeevents "github.com/sipeed/picoclaw/pkg/events"
)
func channelTypeForEvent(m *Manager, channelName string) string {
if m == nil || m.config == nil {
return channelName
}
if bc := m.config.Channels.Get(channelName); bc != nil && bc.Type != "" {
return bc.Type
}
return channelName
}
func (m *Manager) publishChannelEvent(
kind runtimeevents.Kind,
channelName string,
scope runtimeevents.Scope,
severity runtimeevents.Severity,
payload any,
) {
if m == nil || m.runtimeEvents == nil {
return
}
if scope.Channel == "" {
scope.Channel = channelName
}
m.runtimeEvents.PublishNonBlocking(runtimeevents.Event{
Kind: kind,
Source: runtimeevents.Source{Component: "channel", Name: channelName},
Scope: scope,
Severity: severity,
Payload: payload,
Attrs: channelEventAttrs(payload),
})
}
func channelEventAttrs(payload any) map[string]any {
switch payload := payload.(type) {
case ChannelLifecyclePayload:
attrs := map[string]any{}
setAttrString(attrs, "type", payload.Type)
setAttrString(attrs, "error", payload.Error)
return attrs
case ChannelOutboundPayload:
attrs := map[string]any{}
if payload.Media {
attrs["media"] = payload.Media
}
if payload.ContentLen > 0 {
attrs["content_len"] = payload.ContentLen
}
if len(payload.MessageIDs) > 0 {
attrs["message_ids_count"] = len(payload.MessageIDs)
}
setAttrString(attrs, "reply_to_message_id", payload.ReplyToMessageID)
setAttrString(attrs, "error", payload.Error)
if payload.Retries > 0 {
attrs["retries"] = payload.Retries
}
return attrs
default:
return nil
}
}
func setAttrString(attrs map[string]any, key, value string) {
if value != "" {
attrs[key] = value
}
}
func (m *Manager) publishOutboundSent(
channelName string,
msg bus.OutboundMessage,
messageIDs []string,
) {
m.publishChannelEvent(
runtimeevents.KindChannelMessageOutboundSent,
channelName,
scopeFromOutboundContext(msg.Context),
runtimeevents.SeverityInfo,
ChannelOutboundPayload{
ContentLen: len([]rune(msg.Content)),
MessageIDs: append([]string(nil), messageIDs...),
ReplyToMessageID: msg.ReplyToMessageID,
},
)
}
func (m *Manager) publishOutboundQueued(
channelName string,
msg bus.OutboundMessage,
) {
m.publishChannelEvent(
runtimeevents.KindChannelMessageOutboundQueued,
channelName,
scopeFromOutboundContext(msg.Context),
runtimeevents.SeverityInfo,
ChannelOutboundPayload{
ContentLen: len([]rune(msg.Content)),
ReplyToMessageID: msg.ReplyToMessageID,
},
)
}
func (m *Manager) publishOutboundFailed(
channelName string,
msg bus.OutboundMessage,
err error,
media bool,
) {
payload := ChannelOutboundPayload{
Media: media,
ContentLen: len([]rune(msg.Content)),
ReplyToMessageID: msg.ReplyToMessageID,
Retries: maxRetries,
}
if err != nil {
payload.Error = err.Error()
}
m.publishChannelEvent(
runtimeevents.KindChannelMessageOutboundFailed,
channelName,
scopeFromOutboundContext(msg.Context),
runtimeevents.SeverityError,
payload,
)
}
func (m *Manager) publishOutboundMediaSent(
channelName string,
msg bus.OutboundMediaMessage,
messageIDs []string,
) {
m.publishChannelEvent(
runtimeevents.KindChannelMessageOutboundSent,
channelName,
scopeFromOutboundContext(msg.Context),
runtimeevents.SeverityInfo,
ChannelOutboundPayload{
Media: true,
MessageIDs: append([]string(nil), messageIDs...),
},
)
}
func (m *Manager) publishOutboundMediaQueued(
channelName string,
msg bus.OutboundMediaMessage,
) {
m.publishChannelEvent(
runtimeevents.KindChannelMessageOutboundQueued,
channelName,
scopeFromOutboundContext(msg.Context),
runtimeevents.SeverityInfo,
ChannelOutboundPayload{Media: true},
)
}
func (m *Manager) publishOutboundMediaFailed(
channelName string,
msg bus.OutboundMediaMessage,
err error,
) {
payload := ChannelOutboundPayload{
Media: true,
Retries: maxRetries,
}
if err != nil {
payload.Error = err.Error()
}
m.publishChannelEvent(
runtimeevents.KindChannelMessageOutboundFailed,
channelName,
scopeFromOutboundContext(msg.Context),
runtimeevents.SeverityError,
payload,
)
}
func scopeFromOutboundContext(ctx bus.InboundContext) runtimeevents.Scope {
return runtimeevents.Scope{
Channel: ctx.Channel,
Account: ctx.Account,
ChatID: ctx.ChatID,
TopicID: ctx.TopicID,
SpaceID: ctx.SpaceID,
SpaceType: ctx.SpaceType,
ChatType: ctx.ChatType,
SenderID: ctx.SenderID,
MessageID: ctx.MessageID,
}
}