feat(feishu): 添加飞书消息反应功能
- 在配置中新增 react_emoji 字段用于设置反应表情类型 - 实现 ReactToMessage 方法为入站消息添加表情反应 - 添加 addReaction 和 removeReaction 方法管理反应操作 - 提供撤消函数支持移除已添加的表情反应 - 默认使用 OK 表情作为反应类型
This commit is contained in:
parent
302cd05be4
commit
99a50eb3b2
2 changed files with 102 additions and 0 deletions
|
|
@ -93,6 +93,107 @@ func (c *FeishuChannel) Stop(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ReactToMessage implements channels.ReactionCapable.
|
||||
// It adds an emoji reaction to the inbound message and returns an undo function.
|
||||
// Common emoji types: THUMBSUP, OK, EYES, DONE, HEART, ROCKET
|
||||
func (c *FeishuChannel) ReactToMessage(ctx context.Context, chatID, messageID string) (func(), error) {
|
||||
if messageID == "" {
|
||||
return func() {}, nil
|
||||
}
|
||||
|
||||
emojiType := c.config.ReactEmoji
|
||||
if emojiType == "" {
|
||||
emojiType = "OK" // Default emoji
|
||||
}
|
||||
|
||||
// Add reaction and get reaction_id
|
||||
reactionID, err := c.addReaction(ctx, messageID, emojiType)
|
||||
if err != nil {
|
||||
logger.DebugCF("feishu", "Failed to add reaction", map[string]any{
|
||||
"message_id": messageID,
|
||||
"emoji": emojiType,
|
||||
"error": err.Error(),
|
||||
})
|
||||
// Return no-op on error
|
||||
return func() {}, nil
|
||||
}
|
||||
|
||||
logger.DebugCF("feishu", "Added reaction to message", map[string]any{
|
||||
"message_id": messageID,
|
||||
"emoji": emojiType,
|
||||
"reaction_id": reactionID,
|
||||
})
|
||||
|
||||
// Return undo function
|
||||
return func() {
|
||||
if reactionID != "" {
|
||||
c.removeReaction(context.Background(), messageID, reactionID)
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// addReaction adds an emoji reaction to a message and returns the reaction_id.
|
||||
func (c *FeishuChannel) addReaction(ctx context.Context, messageID, emojiType string) (string, error) {
|
||||
req := larkim.NewCreateMessageReactionReqBuilder().
|
||||
MessageId(messageID).
|
||||
Body(larkim.NewCreateMessageReactionReqBodyBuilder().
|
||||
ReactionType(larkim.NewEmojiBuilder().
|
||||
EmojiType(emojiType).
|
||||
Build()).
|
||||
Build()).
|
||||
Build()
|
||||
|
||||
resp, err := c.client.Im.V1.MessageReaction.Create(ctx, req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("feishu add reaction: %w", err)
|
||||
}
|
||||
|
||||
if !resp.Success() {
|
||||
return "", fmt.Errorf("feishu add reaction failed: code=%d msg=%s", resp.Code, resp.Msg)
|
||||
}
|
||||
|
||||
if resp.Data != nil && resp.Data.ReactionId != nil {
|
||||
return *resp.Data.ReactionId, nil
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// removeReaction removes an emoji reaction from a message using reaction_id.
|
||||
func (c *FeishuChannel) removeReaction(ctx context.Context, messageID, reactionID string) error {
|
||||
req := larkim.NewDeleteMessageReactionReqBuilder().
|
||||
MessageId(messageID).
|
||||
ReactionId(reactionID).
|
||||
Build()
|
||||
|
||||
resp, err := c.client.Im.V1.MessageReaction.Delete(ctx, req)
|
||||
if err != nil {
|
||||
logger.DebugCF("feishu", "Failed to remove reaction", map[string]any{
|
||||
"message_id": messageID,
|
||||
"reaction_id": reactionID,
|
||||
"error": err.Error(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.Success() {
|
||||
logger.DebugCF("feishu", "Failed to remove reaction", map[string]any{
|
||||
"message_id": messageID,
|
||||
"reaction_id": reactionID,
|
||||
"code": resp.Code,
|
||||
"msg": resp.Msg,
|
||||
})
|
||||
return fmt.Errorf("feishu remove reaction failed: code=%d msg=%s", resp.Code, resp.Msg)
|
||||
}
|
||||
|
||||
logger.DebugCF("feishu", "Removed reaction from message", map[string]any{
|
||||
"message_id": messageID,
|
||||
"reaction_id": reactionID,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *FeishuChannel) Send(ctx context.Context, msg bus.OutboundMessage) error {
|
||||
if !c.IsRunning() {
|
||||
return channels.ErrNotRunning
|
||||
|
|
|
|||
|
|
@ -252,6 +252,7 @@ type FeishuConfig struct {
|
|||
AllowFrom FlexibleStringSlice `json:"allow_from" env:"PICOCLAW_CHANNELS_FEISHU_ALLOW_FROM"`
|
||||
GroupTrigger GroupTriggerConfig `json:"group_trigger,omitempty"`
|
||||
ReasoningChannelID string `json:"reasoning_channel_id" env:"PICOCLAW_CHANNELS_FEISHU_REASONING_CHANNEL_ID"`
|
||||
ReactEmoji string `json:"react_emoji" env:"PICOCLAW_CHANNELS_FEISHU_REACT_EMOJI"` // Emoji type for reaction, e.g. "THUMBSUP", "EYES", "OK"
|
||||
}
|
||||
|
||||
type DiscordConfig struct {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue