// Package message provides pure parsing and formatting for Matrix messages. package message import ( "strings" "github.com/enmanuel/agents/pkg/decision" ) // ParseOptions configures how messages are parsed. type ParseOptions struct { CommandPrefix string // e.g. "!" BotUserID string // for mention detection, e.g. "@bot:server" MentionedUserIDs []string // pre-extracted from m.mentions event field (modern Matrix spec) } // Parse converts a raw Matrix message body into a structured MessageContext. Pure. func Parse(body, senderID, roomID string, powerLevel int, isDM bool, opts ParseOptions) decision.MessageContext { ctx := decision.MessageContext{ SenderID: senderID, RoomID: roomID, Content: body, PowerLevel: powerLevel, IsDirectMsg: isDM, } // Detect mention: check m.mentions list first (modern Matrix spec). if opts.BotUserID != "" { for _, uid := range opts.MentionedUserIDs { if uid == opts.BotUserID { ctx.IsMention = true break } } // Fallback: check if full user ID appears in the plain text body. if !ctx.IsMention && strings.Contains(body, opts.BotUserID) { ctx.IsMention = true } } // Parse command if opts.CommandPrefix != "" && strings.HasPrefix(body, opts.CommandPrefix) { parts := strings.Fields(strings.TrimPrefix(body, opts.CommandPrefix)) if len(parts) > 0 { ctx.Command = strings.ToLower(parts[0]) ctx.Args = parts[1:] } } return ctx }