fix(feishu): resolve group mentions by probing live bot name
This commit is contained in:
parent
98c78363b3
commit
167c2ad8f2
1 changed files with 28 additions and 18 deletions
|
|
@ -42,7 +42,8 @@ type FeishuChannel struct {
|
||||||
wsClient *larkws.Client
|
wsClient *larkws.Client
|
||||||
tokenCache *tokenCache // custom cache that supports invalidation
|
tokenCache *tokenCache // custom cache that supports invalidation
|
||||||
|
|
||||||
botOpenID atomic.Value // stores string; populated lazily for @mention detection
|
botOpenID atomic.Value // stores string; probed identity for @mention detection
|
||||||
|
botName atomic.Value // stores string; probed identity for @mention detection
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
|
@ -74,9 +75,9 @@ func (c *FeishuChannel) Start(ctx context.Context) error {
|
||||||
return fmt.Errorf("feishu app_id or app_secret is empty")
|
return fmt.Errorf("feishu app_id or app_secret is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch bot open_id via API for reliable @mention detection.
|
// Fetch bot identity (ID and Name) via API for reliable @mention detection.
|
||||||
if err := c.fetchBotOpenID(ctx); err != nil {
|
if err := c.fetchBotOpenID(ctx); err != nil {
|
||||||
logger.ErrorCF("feishu", "Failed to fetch bot open_id, @mention detection may not work", map[string]any{
|
logger.ErrorCF("feishu", "Failed to fetch bot identity, @mention detection may not work", map[string]any{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -487,7 +488,7 @@ func (c *FeishuChannel) handleMessageReceive(ctx context.Context, event *larkim.
|
||||||
|
|
||||||
// --- Internal helpers ---
|
// --- Internal helpers ---
|
||||||
|
|
||||||
// fetchBotOpenID calls the Feishu bot info API to retrieve and store the bot's open_id.
|
// fetchBotOpenID calls the Feishu bot info API to retrieve the bot's identity (ID and Name).
|
||||||
func (c *FeishuChannel) fetchBotOpenID(ctx context.Context) error {
|
func (c *FeishuChannel) fetchBotOpenID(ctx context.Context) error {
|
||||||
resp, err := c.client.Do(ctx, &larkcore.ApiReq{
|
resp, err := c.client.Do(ctx, &larkcore.ApiReq{
|
||||||
HttpMethod: http.MethodGet,
|
HttpMethod: http.MethodGet,
|
||||||
|
|
@ -502,6 +503,7 @@ func (c *FeishuChannel) fetchBotOpenID(ctx context.Context) error {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
Bot struct {
|
Bot struct {
|
||||||
OpenID string `json:"open_id"`
|
OpenID string `json:"open_id"`
|
||||||
|
Name string `json:"name"`
|
||||||
} `json:"bot"`
|
} `json:"bot"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(resp.RawBody, &result); err != nil {
|
if err := json.Unmarshal(resp.RawBody, &result); err != nil {
|
||||||
|
|
@ -516,32 +518,40 @@ func (c *FeishuChannel) fetchBotOpenID(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
c.botOpenID.Store(result.Bot.OpenID)
|
c.botOpenID.Store(result.Bot.OpenID)
|
||||||
logger.InfoCF("feishu", "Fetched bot open_id from API", map[string]any{
|
c.botName.Store(result.Bot.Name)
|
||||||
|
logger.InfoCF("feishu", "Fetched bot identity from API", map[string]any{
|
||||||
"open_id": result.Bot.OpenID,
|
"open_id": result.Bot.OpenID,
|
||||||
|
"bot_name": result.Bot.Name,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// isBotMentioned checks if the bot was @mentioned in the message.
|
// isBotMentioned checks if the bot was @mentioned in the message.
|
||||||
func (c *FeishuChannel) isBotMentioned(message *larkim.EventMessage) bool {
|
func (c *FeishuChannel) isBotMentioned(message *larkim.EventMessage) bool {
|
||||||
if message.Mentions == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
knownID, _ := c.botOpenID.Load().(string)
|
knownID, _ := c.botOpenID.Load().(string)
|
||||||
if knownID == "" {
|
knownName, _ := c.botName.Load().(string)
|
||||||
logger.DebugCF("feishu", "Bot open_id unknown, cannot detect @mention", nil)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Case 1: Structured Mentions check via OpenID match
|
||||||
|
if message.Mentions != nil {
|
||||||
for _, m := range message.Mentions {
|
for _, m := range message.Mentions {
|
||||||
if m.Id == nil {
|
if m.Id != nil && m.Id.OpenId != nil && *m.Id.OpenId == knownID {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if m.Id.OpenId != nil && *m.Id.OpenId == knownID {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2: Unstructured Name-based fallback check (e.g. "@BotName hello")
|
||||||
|
// This happens if the platform/client fails to resolve the mention as a structured ID.
|
||||||
|
if knownName != "" && message.MessageType != nil && *message.MessageType == larkim.MsgTypeText {
|
||||||
|
content := stringValue(message.Content)
|
||||||
|
if strings.Contains(content, "@"+knownName) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if knownID == "" {
|
||||||
|
logger.DebugCF("feishu", "Bot open_id unknown, cannot detect @mention", nil)
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue