44 "context"
55 "encoding/json"
66 "fmt"
7+ "regexp"
78 "slices"
89 "strings"
910 "time"
@@ -20,6 +21,10 @@ import (
2021const (
2122 ctxKeyGithubToken = "github_token"
2223 ctxKeyLarkSenderEmail = "lark.sender.email"
24+
25+ // Message types
26+ msgTypePrivate = "private"
27+ msgTypeGroup = "group"
2328)
2429
2530var (
5964)
6065
6166type Command struct {
62- Name string
63- Args []string
64- Sender * CommandSender
67+ Name string
68+ Args []string
69+ Sender * CommandSender
70+ MsgType string // Message type: private or group
71+ ChatID string // Group ID, only valid when MsgType is group
6572}
6673
6774type CommandSender struct {
@@ -124,7 +131,14 @@ func (r *rootHandler) Handle(ctx context.Context, event *larkim.P2MessageReceive
124131 }
125132
126133 hl := log .With ().Str ("eventId" , eventID ).Logger ()
127- command := shouldHandle (event )
134+
135+ // Get bot name from config with type assertion
136+ botName := ""
137+ if name , ok := r .Config ["bot_name" ].(string ); ok {
138+ botName = name
139+ }
140+
141+ command := shouldHandle (event , botName )
128142 if command == nil {
129143 hl .Debug ().Msg ("none command received" )
130144 return nil
@@ -271,7 +285,76 @@ func (r *rootHandler) deleteReaction(reqMsgID, reactionID string) error {
271285 return nil
272286}
273287
274- func shouldHandle (event * larkim.P2MessageReceiveV1 ) * Command {
288+ // determineMessageType determines the message type and checks if the bot was mentioned
289+ func determineMessageType (event * larkim.P2MessageReceiveV1 , botName string ) (msgType string , chatID string , isMentionBot bool ) {
290+ // Check if the message is from a group chat
291+ if event .Event .Message .ChatId != nil && event .Event .Message .ChatType != nil && * event .Event .Message .ChatType == "group" {
292+ msgType = msgTypeGroup
293+ chatID = * event .Event .Message .ChatId
294+ isMentionBot = checkIfBotMentioned (event , botName )
295+ } else {
296+ msgType = msgTypePrivate
297+ }
298+
299+ return msgType , chatID , isMentionBot
300+ }
301+
302+ // checkIfBotMentioned checks if the bot was mentioned in the message
303+ func checkIfBotMentioned (event * larkim.P2MessageReceiveV1 , botName string ) bool {
304+ if event .Event .Message .Mentions == nil || len (event .Event .Message .Mentions ) == 0 {
305+ return false
306+ }
307+
308+ for _ , mention := range event .Event .Message .Mentions {
309+ if mention == nil {
310+ continue
311+ }
312+ if mention .Name != nil {
313+ // check if the bot was mentioned
314+ if * mention .Name == botName {
315+ return true
316+ }
317+ }
318+ }
319+ return false
320+ }
321+
322+ // parseGroupCommand parses commands from group messages
323+ // Supported format: @bot /command arg1 arg2...
324+ func parseGroupCommand (event * larkim.P2MessageReceiveV1 ) * Command {
325+ messageContent := strings .TrimSpace (* event .Event .Message .Content )
326+
327+ var content commandLarkMsgContent
328+ if err := json .Unmarshal ([]byte (messageContent ), & content ); err != nil {
329+ return nil
330+ }
331+
332+ // In Lark messages, mentions are converted to @_user_X format
333+ // Use regex to match commands after @_user_X: /command arg1 arg2...
334+ re := regexp .MustCompile (`@_user_\d+\s+(/\S+)(.*)` )
335+ matches := re .FindStringSubmatch (content .Text )
336+
337+ if len (matches ) < 3 {
338+ return nil
339+ }
340+
341+ commandName := matches [1 ]
342+ argsStr := strings .TrimSpace (matches [2 ])
343+ var args []string
344+ if argsStr != "" {
345+ args = strings .Fields (argsStr )
346+ }
347+
348+ // Check if it's a privileged command
349+ if slices .Contains (privilegedCommandList , commandName ) {
350+ return nil
351+ }
352+
353+ return & Command {Name : commandName , Args : args }
354+ }
355+
356+ // parsePrivateCommand parses commands from private messages
357+ func parsePrivateCommand (event * larkim.P2MessageReceiveV1 ) * Command {
275358 messageContent := strings .TrimSpace (* event .Event .Message .Content )
276359
277360 var content commandLarkMsgContent
@@ -286,3 +369,15 @@ func shouldHandle(event *larkim.P2MessageReceiveV1) *Command {
286369
287370 return & Command {Name : messageParts [0 ], Args : messageParts [1 :]}
288371}
372+
373+ func shouldHandle (event * larkim.P2MessageReceiveV1 , botName string ) * Command {
374+ // Determine message type and whether the bot was mentioned
375+ msgType , _ , isMentionBot := determineMessageType (event , botName )
376+
377+ if msgType == msgTypeGroup && isMentionBot {
378+ return parseGroupCommand (event )
379+ } else if msgType == msgTypePrivate {
380+ return parsePrivateCommand (event )
381+ }
382+ return nil
383+ }
0 commit comments