@@ -81,101 +81,45 @@ const (
8181 PointCheck
8282)
8383
84- // detectPointOperation checks if the message contains a point operation (++, --, ==)
85- func (b * Bot ) detectPointOperation (text string ) PointOperation {
86- // Support both user mentions and emoji patterns
87- // User mention patterns: <@U123456>++
88- userPlusPattern := `.*<@[A-Z0-9]+>[ ]*\+\+.*`
89- userMinusPattern := `.*<@[A-Z0-9]+>[ ]*\-\-.*`
90- userEqualsPattern := `.*<@[A-Z0-9]+>[ ]*\=\=.*`
91-
92- // Emoji patterns: :emoji: ++
93- emojiPlusPattern := `.*:[a-zA-Z0-9_+-]+:[ ]*\+\+.*`
94- emojiMinusPattern := `.*:[a-zA-Z0-9_+-]+:[ ]*\-\-.*`
95- emojiEqualsPattern := `.*:[a-zA-Z0-9_+-]+:[ ]*\=\=.*`
96-
97- // Check for plus patterns
98- userPlusMatched , err := regexp .MatchString (userPlusPattern , text )
99- if err != nil {
100- b .logger .Error ("Error matching user plus pattern" , "error" , err )
101- return NoOperation
102- }
103- emojiPlusMatched , err := regexp .MatchString (emojiPlusPattern , text )
104- if err != nil {
105- b .logger .Error ("Error matching emoji plus pattern" , "error" , err )
106- return NoOperation
107- }
108- if userPlusMatched || emojiPlusMatched {
109- return PointUp
110- }
84+ // Pre-compiled regexes for detecting point operations with targets
85+ var (
86+ // User mention pattern: <@U123456> ++ (captures user ID and operator)
87+ userOperationPattern = regexp .MustCompile (`<@([A-Z0-9]+)>[ ]*(\+\+|-{2}|={2})` )
88+ // Emoji pattern: :emoji: ++ (captures emoji name and operator)
89+ emojiOperationPattern = regexp .MustCompile (`:([a-zA-Z0-9_+-]+):[ ]*(\+\+|-{2}|={2})` )
90+ )
11191
112- // Check for minus patterns
113- userMinusMatched , err := regexp .MatchString (userMinusPattern , text )
114- if err != nil {
115- b .logger .Error ("Error matching user minus pattern" , "error" , err )
116- return NoOperation
117- }
118- emojiMinusMatched , err := regexp .MatchString (emojiMinusPattern , text )
119- if err != nil {
120- b .logger .Error ("Error matching emoji minus pattern" , "error" , err )
121- return NoOperation
122- }
123- if userMinusMatched || emojiMinusMatched {
92+ // parseOperator converts an operator string to a PointOperation
93+ func parseOperator (op string ) PointOperation {
94+ switch op {
95+ case "++" :
96+ return PointUp
97+ case "--" :
12498 return PointDown
125- }
126-
127- // Check for equals patterns
128- userEqualsMatched , err := regexp .MatchString (userEqualsPattern , text )
129- if err != nil {
130- b .logger .Error ("Error matching user equals pattern" , "error" , err )
131- return NoOperation
132- }
133- emojiEqualsMatched , err := regexp .MatchString (emojiEqualsPattern , text )
134- if err != nil {
135- b .logger .Error ("Error matching emoji equals pattern" , "error" , err )
136- return NoOperation
137- }
138- if userEqualsMatched || emojiEqualsMatched {
99+ case "==" :
139100 return PointCheck
101+ default :
102+ return NoOperation
140103 }
141-
142- return NoOperation
143104}
144105
145- func extractUserID (text string ) string {
146- re := regexp .MustCompile (`<@([A-Z0-9]+)>` )
147- matches := re .FindStringSubmatch (text )
148- if len (matches ) < 2 {
149- return ""
106+ // detectOperationAndTarget detects the point operation and extracts the target in one step.
107+ // This ensures the detected operation is associated with the correct target.
108+ func detectOperationAndTarget (text string ) (PointOperation , string , bool ) {
109+ // User mentions have priority
110+ if matches := userOperationPattern .FindStringSubmatch (text ); len (matches ) >= 3 {
111+ return parseOperator (matches [2 ]), matches [1 ], true
150112 }
151- return matches [1 ]
152- }
153-
154- // extractEmojiName extracts emoji name from text (e.g., ":sake:" -> "sake")
155- func extractEmojiName (text string ) string {
156- re := regexp .MustCompile (`:([a-zA-Z0-9_+-]+):` )
157- matches := re .FindStringSubmatch (text )
158- if len (matches ) < 2 {
159- return ""
113+ if matches := emojiOperationPattern .FindStringSubmatch (text ); len (matches ) >= 3 {
114+ return parseOperator (matches [2 ]), matches [1 ], false
160115 }
161- return matches [ 1 ]
116+ return NoOperation , "" , false
162117}
163118
164- // extractTargetFromText extracts either user ID or emoji name from text
165- func extractTargetFromText (text string ) (string , bool ) {
166- // Try to extract user ID first
167- userID := extractUserID (text )
168- if userID != "" {
169- return userID , true // true indicates it's a user ID
170- }
171-
172- // If no user ID, try to extract emoji name
173- emojiName := extractEmojiName (text )
174- if emojiName != "" {
175- return emojiName , false // false indicates it's an emoji name
176- }
177-
178- return "" , false
119+ // detectPointOperation checks if the message contains a point operation (++, --, ==)
120+ func (b * Bot ) detectPointOperation (text string ) PointOperation {
121+ op , _ , _ := detectOperationAndTarget (text )
122+ return op
179123}
180124
181125// isUser checks if the given user ID belongs to a user
@@ -189,13 +133,7 @@ func (b *Bot) isUser(userID string) (bool, error) {
189133}
190134
191135// handlePointChangeMessage processes a point up or down message
192- func (b * Bot ) handlePointChangeMessage (ev * slackevents.MessageEvent , operation PointOperation ) {
193- // Extract target (user ID or emoji name) from the message
194- target , isUser := extractTargetFromText (ev .Text )
195- if target == "" {
196- b .logger .Error ("No target found in message" )
197- return
198- }
136+ func (b * Bot ) handlePointChangeMessage (ev * slackevents.MessageEvent , operation PointOperation , target string , isUser bool ) {
199137
200138 // Check if user is trying to point themselves (only applies to user targets)
201139 if isUser && target == ev .User {
@@ -258,14 +196,7 @@ func (b *Bot) handlePointChangeMessage(ev *slackevents.MessageEvent, operation P
258196 b .logger .Debug ("Reply sent" , "message" , message )
259197}
260198
261- func (b * Bot ) handlePointCheckMessage (ev * slackevents.MessageEvent ) {
262- // Extract target (user ID or emoji name) from the message
263- target , isUser := extractTargetFromText (ev .Text )
264- if target == "" {
265- b .logger .Error ("No target found in message" )
266- return
267- }
268-
199+ func (b * Bot ) handlePointCheckMessage (ev * slackevents.MessageEvent , target string , isUser bool ) {
269200 ctx := context .Background ()
270201 points , err := b .repo .GetPoints (ctx , target )
271202 if err != nil {
@@ -284,13 +215,13 @@ func (b *Bot) handlePointCheckMessage(ev *slackevents.MessageEvent) {
284215// handleMessageEvent processes a message event
285216func (b * Bot ) handleMessageEvent (ev * slackevents.MessageEvent ) {
286217 b .logger .Debug ("Received message event" , "event" , ev )
287- operation := b . detectPointOperation (ev .Text )
288- if operation != NoOperation {
289- b .logger .Info ("Point operation detected" , "text" , ev .Text )
218+ operation , target , isUser := detectOperationAndTarget (ev .Text )
219+ if operation != NoOperation && target != "" {
220+ b .logger .Info ("Point operation detected" , "text" , ev .Text , "target" , target , "isUser" , isUser )
290221 if operation == PointCheck {
291- b .handlePointCheckMessage (ev )
222+ b .handlePointCheckMessage (ev , target , isUser )
292223 } else {
293- b .handlePointChangeMessage (ev , operation )
224+ b .handlePointChangeMessage (ev , operation , target , isUser )
294225 }
295226 }
296227}
0 commit comments